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
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
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
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/>. */
26 #include "coretypes.h"
29 #ifdef VMS_DEBUGGING_INFO
37 #include "langhooks.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
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
;
63 typedef struct dst_file_info_struct
*dst_file_info_ref
;
65 typedef struct dst_file_info_struct
68 unsigned int max_line
;
69 unsigned int listing_line_start
;
78 /* How to start an assembler comment. */
79 #ifndef ASM_COMMENT_START
80 #define ASM_COMMENT_START ";#"
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
91 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
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
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
107 #define FILE_TABLE_INCREMENT 64
109 typedef char *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
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
183 vmsdbgout_assembly_start
,
186 vmsdbgout_start_source_file
,
187 vmsdbgout_end_source_file
,
188 vmsdbgout_begin_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
,
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
, /* direct_call */
209 debug_nothing_tree_int
, /* virtual_call_token */
210 debug_nothing_rtx_rtx
, /* copy_call_info */
211 debug_nothing_uid
, /* virtual_call */
212 debug_nothing_tree_tree
, /* set_name */
213 0, /* start_end_main_source_file */
214 TYPE_SYMTAB_IS_ADDRESS
/* tree_type_symtab_field */
217 /* Definitions of defaults for assembler-dependent names of various
218 pseudo-ops and section names.
219 Theses may be overridden in the tm.h file (if necessary) for a particular
221 #ifdef UNALIGNED_SHORT_ASM_OP
222 #undef UNALIGNED_SHORT_ASM_OP
224 #define UNALIGNED_SHORT_ASM_OP ".word"
226 #ifdef UNALIGNED_INT_ASM_OP
227 #undef UNALIGNED_INT_ASM_OP
229 #define UNALIGNED_INT_ASM_OP ".long"
231 #ifdef UNALIGNED_LONG_ASM_OP
232 #undef UNALIGNED_LONG_ASM_OP
234 #define UNALIGNED_LONG_ASM_OP ".long"
236 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
237 #undef UNALIGNED_DOUBLE_INT_ASM_OP
239 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
244 #define ASM_BYTE_OP ".byte"
246 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
248 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
250 #ifndef UNALIGNED_PTR_ASM_OP
251 #define UNALIGNED_PTR_ASM_OP \
252 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
255 #ifndef UNALIGNED_OFFSET_ASM_OP
256 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
257 (NUMBYTES(OFFSET) == 4 \
258 ? UNALIGNED_LONG_ASM_OP \
259 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
262 /* Definitions of defaults for formats and names of various special
263 (artificial) labels which may be generated within this file (when the -g
264 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
265 may be overridden from within the tm.h file, but typically, overriding these
266 defaults is unnecessary. */
268 static char text_end_label
[MAX_ARTIFICIAL_LABEL_BYTES
];
270 #ifndef TEXT_END_LABEL
271 #define TEXT_END_LABEL "Lvetext"
273 #ifndef FUNC_BEGIN_LABEL
274 #define FUNC_BEGIN_LABEL "LVFB"
276 #ifndef FUNC_PROLOG_LABEL
277 #define FUNC_PROLOG_LABEL "LVFP"
279 #ifndef FUNC_EPILOG_LABEL
280 #define FUNC_EPILOG_LABEL "LVEB"
282 #ifndef FUNC_END_LABEL
283 #define FUNC_END_LABEL "LVFE"
285 #ifndef BLOCK_BEGIN_LABEL
286 #define BLOCK_BEGIN_LABEL "LVBB"
288 #ifndef BLOCK_END_LABEL
289 #define BLOCK_END_LABEL "LVBE"
291 #ifndef LINE_CODE_LABEL
292 #define LINE_CODE_LABEL "LVM"
295 #ifndef ASM_OUTPUT_DEBUG_DELTA2
296 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
299 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
300 assemble_name (FILE, LABEL1); \
301 fprintf (FILE, "-"); \
302 assemble_name (FILE, LABEL2); \
307 #ifndef ASM_OUTPUT_DEBUG_DELTA4
308 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
311 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
312 assemble_name (FILE, LABEL1); \
313 fprintf (FILE, "-"); \
314 assemble_name (FILE, LABEL2); \
319 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
320 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
323 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
324 assemble_name (FILE, LABEL1); \
325 fprintf (FILE, "-"); \
326 assemble_name (FILE, LABEL2); \
331 #ifndef ASM_OUTPUT_DEBUG_ADDR
332 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
335 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
336 assemble_name (FILE, LABEL); \
341 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
342 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
343 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
346 #ifndef ASM_OUTPUT_DEBUG_DATA1
347 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
348 fprintf ((FILE), "\t%s\t%#x", ASM_BYTE_OP, (unsigned char) VALUE)
351 #ifndef ASM_OUTPUT_DEBUG_DATA2
352 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
353 fprintf ((FILE), "\t%s\t%#x", UNALIGNED_SHORT_ASM_OP, \
354 (unsigned short) VALUE)
357 #ifndef ASM_OUTPUT_DEBUG_DATA4
358 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
359 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
362 #ifndef ASM_OUTPUT_DEBUG_DATA
363 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
364 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
367 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
368 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
369 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_PTR_ASM_OP, \
370 (unsigned long) VALUE)
373 #ifndef ASM_OUTPUT_DEBUG_DATA8
374 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
375 fprintf ((FILE), "\t%s\t%#llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
376 (unsigned long long) VALUE)
379 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
380 newline is produced. When flag_verbose_asm is asserted, we add commentary
381 at the end of the line, so we must avoid output of a newline here. */
382 #ifndef ASM_OUTPUT_DEBUG_STRING
383 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
386 register int slen = strlen(P); \
387 register const char *p = (P); \
389 fprintf (FILE, "\t.ascii \""); \
390 for (i = 0; i < slen; i++) \
392 register int c = p[i]; \
393 if (c == '\"' || c == '\\') \
395 if (c >= ' ' && c < 0177) \
398 fprintf (FILE, "\\%o", c); \
400 fprintf (FILE, "\""); \
405 /* Convert a reference to the assembler name of a C-level name. This
406 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
407 a string rather than writing to a file. */
408 #ifndef ASM_NAME_TO_STRING
409 #define ASM_NAME_TO_STRING(STR, NAME) \
412 if ((NAME)[0] == '*') \
413 strcpy (STR, NAME+1); \
415 strcpy (STR, NAME); \
421 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
422 set. Return the header size. Just return the size if DOSIZEONLY is
426 write_debug_header (DST_HEADER
*header
, const char *comment
, int dosizeonly
)
430 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
431 header
->dst__header_length
.dst_w_length
);
433 if (flag_verbose_asm
)
434 fprintf (asm_out_file
, "\t%s record length", ASM_COMMENT_START
);
435 fputc ('\n', asm_out_file
);
437 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
438 header
->dst__header_type
.dst_w_type
);
440 if (flag_verbose_asm
)
441 fprintf (asm_out_file
, "\t%s record type (%s)", ASM_COMMENT_START
,
444 fputc ('\n', asm_out_file
);
450 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
451 set. Return the address size. Just return the size if DOSIZEONLY is
455 write_debug_addr (const char *symbol
, const char *comment
, int dosizeonly
)
459 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, symbol
);
460 if (flag_verbose_asm
)
461 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
462 fputc ('\n', asm_out_file
);
468 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
469 set. Return the data size. Just return the size if DOSIZEONLY is
473 write_debug_data1 (unsigned int data1
, const char *comment
, int dosizeonly
)
477 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file
, data1
);
478 if (flag_verbose_asm
)
479 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
480 fputc ('\n', asm_out_file
);
486 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
487 set. Return the data size. Just return the size if DOSIZEONLY is
491 write_debug_data2 (unsigned int data2
, const char *comment
, int dosizeonly
)
495 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
, data2
);
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 double word DATA4. 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_data4 (unsigned long data4
, const char *comment
, int dosizeonly
)
512 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file
, data4
);
513 if (flag_verbose_asm
)
514 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
515 fputc ('\n', asm_out_file
);
521 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
522 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
525 write_debug_data8 (unsigned long long data8
, const char *comment
,
530 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file
, data8
);
531 if (flag_verbose_asm
)
532 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
533 fputc ('\n', asm_out_file
);
539 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
540 flag_verbose_asm is set. Return the data size. Just return the size if
541 DOSIZEONLY is nonzero. */
544 write_debug_delta4 (const char *label1
, const char *label2
,
545 const char *comment
, int dosizeonly
)
549 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file
, label1
, label2
);
550 if (flag_verbose_asm
)
551 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
552 fputc ('\n', asm_out_file
);
558 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
559 set. Return the string length. Just return the length if DOSIZEONLY is
563 write_debug_string (const char *string
, const char *comment
, int dosizeonly
)
567 ASM_OUTPUT_DEBUG_STRING (asm_out_file
, string
);
568 if (flag_verbose_asm
)
569 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
570 fputc ('\n', asm_out_file
);
573 return strlen (string
);
576 /* Output a module begin header and return the header size. Just return the
577 size if DOSIZEONLY is nonzero. */
580 write_modbeg (int dosizeonly
)
582 DST_MODULE_BEGIN modbeg
;
585 char *module_name
, *m
;
590 /* Assumes primary filename has Unix syntax file spec. */
591 module_name
= xstrdup (lbasename (primary_filename
));
593 m
= strrchr (module_name
, '.');
597 modnamelen
= strlen (module_name
);
598 for (i
= 0; i
< modnamelen
; i
++)
599 module_name
[i
] = TOUPPER (module_name
[i
]);
601 prodnamelen
= strlen (module_producer
);
603 modbeg
.dst_a_modbeg_header
.dst__header_length
.dst_w_length
604 = DST_K_MODBEG_SIZE
+ modnamelen
+ DST_K_MB_TRLR_SIZE
+ prodnamelen
- 1;
605 modbeg
.dst_a_modbeg_header
.dst__header_type
.dst_w_type
= DST_K_MODBEG
;
606 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_hide
= 0;
607 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_version
= 1;
608 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_unused
= 0;
609 modbeg
.dst_b_modbeg_unused
= 0;
610 modbeg
.dst_l_modbeg_language
= (DST_LANGUAGE
) module_language
;
611 modbeg
.dst_w_version_major
= DST_K_VERSION_MAJOR
;
612 modbeg
.dst_w_version_minor
= DST_K_VERSION_MINOR
;
613 modbeg
.dst_b_modbeg_name
= strlen (module_name
);
615 mb_trlr
.dst_b_compiler
= strlen (module_producer
);
617 totsize
+= write_debug_header (&modbeg
.dst_a_modbeg_header
,
618 "modbeg", dosizeonly
);
619 totsize
+= write_debug_data1 (*((char *) &modbeg
.dst_b_modbeg_flags
),
620 "flags", dosizeonly
);
621 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_unused
,
622 "unused", dosizeonly
);
623 totsize
+= write_debug_data4 (modbeg
.dst_l_modbeg_language
,
624 "language", dosizeonly
);
625 totsize
+= write_debug_data2 (modbeg
.dst_w_version_major
,
626 "DST major version", dosizeonly
);
627 totsize
+= write_debug_data2 (modbeg
.dst_w_version_minor
,
628 "DST minor version", dosizeonly
);
629 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_name
,
630 "length of module name", dosizeonly
);
631 totsize
+= write_debug_string (module_name
, "module name", dosizeonly
);
632 totsize
+= write_debug_data1 (mb_trlr
.dst_b_compiler
,
633 "length of compiler name", dosizeonly
);
634 totsize
+= write_debug_string (module_producer
, "compiler name", dosizeonly
);
639 /* Output a module end trailer and return the trailer size. Just return
640 the size if DOSIZEONLY is nonzero. */
643 write_modend (int dosizeonly
)
645 DST_MODULE_END modend
;
648 modend
.dst_a_modend_header
.dst__header_length
.dst_w_length
649 = DST_K_MODEND_SIZE
- 1;
650 modend
.dst_a_modend_header
.dst__header_type
.dst_w_type
= DST_K_MODEND
;
652 totsize
+= write_debug_header (&modend
.dst_a_modend_header
, "modend",
658 /* Output a routine begin header routine RTNNUM and return the header size.
659 Just return the size if DOSIZEONLY is nonzero. */
662 write_rtnbeg (int rtnnum
, int dosizeonly
)
668 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
669 DST_ROUTINE_BEGIN rtnbeg
;
672 rtnname
= VEC_index (char_p
, funcnam_table
, rtnnum
);
673 rtnnamelen
= strlen (rtnname
);
674 rtnentryname
= concat (rtnname
, "..en", NULL
);
676 if (!strcmp (rtnname
, "main"))
679 const char *go
= "TRANSFER$BREAK$GO";
681 /* This command isn't documented in DSTRECORDS, so it's made to
682 look like what DEC C does */
684 /* header size - 1st byte + flag byte + STO_LW size
685 + string count byte + string length */
686 header
.dst__header_length
.dst_w_length
687 = DST_K_DST_HEADER_SIZE
- 1 + 1 + 4 + 1 + strlen (go
);
688 header
.dst__header_type
.dst_w_type
= DST_K_TBG
;
690 totsize
+= write_debug_header (&header
, "transfer", dosizeonly
);
692 /* I think this is a flag byte, but I don't know what this flag means */
693 totsize
+= write_debug_data1 (0x1, "flags ???", dosizeonly
);
695 /* Routine Begin PD Address */
696 totsize
+= write_debug_addr (rtnname
, "main procedure descriptor",
698 totsize
+= write_debug_data1 (strlen (go
), "length of main_name",
700 totsize
+= write_debug_string (go
, "main name", dosizeonly
);
703 /* The header length never includes the length byte. */
704 rtnbeg
.dst_a_rtnbeg_header
.dst__header_length
.dst_w_length
705 = DST_K_RTNBEG_SIZE
+ rtnnamelen
- 1;
706 rtnbeg
.dst_a_rtnbeg_header
.dst__header_type
.dst_w_type
= DST_K_RTNBEG
;
707 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unused
= 0;
708 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unalloc
= 0;
709 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_prototype
= 0;
710 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_inlined
= 0;
711 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_no_call
= 1;
712 rtnbeg
.dst_b_rtnbeg_name
= rtnnamelen
;
714 totsize
+= write_debug_header (&rtnbeg
.dst_a_rtnbeg_header
, "rtnbeg",
716 totsize
+= write_debug_data1 (*((char *) &rtnbeg
.dst_b_rtnbeg_flags
),
717 "flags", dosizeonly
);
719 /* Routine Begin Address */
720 totsize
+= write_debug_addr (rtnentryname
, "routine entry name", dosizeonly
);
722 /* Routine Begin PD Address */
723 totsize
+= write_debug_addr (rtnname
, "routine procedure descriptor",
726 /* Routine Begin Name */
727 totsize
+= write_debug_data1 (rtnbeg
.dst_b_rtnbeg_name
,
728 "length of routine name", dosizeonly
);
730 totsize
+= write_debug_string (rtnname
, "routine name", dosizeonly
);
734 if (debug_info_level
> DINFO_LEVEL_TERSE
)
736 prolog
.dst_a_prolog_header
.dst__header_length
.dst_w_length
737 = DST_K_PROLOG_SIZE
- 1;
738 prolog
.dst_a_prolog_header
.dst__header_type
.dst_w_type
= DST_K_PROLOG
;
740 totsize
+= write_debug_header (&prolog
.dst_a_prolog_header
, "prolog",
743 ASM_GENERATE_INTERNAL_LABEL
744 (label
, FUNC_PROLOG_LABEL
,
745 VEC_index (unsigned, funcnum_table
, rtnnum
));
746 totsize
+= write_debug_addr (label
, "prolog breakpoint addr",
753 /* Output a routine end trailer for routine RTNNUM and return the header size.
754 Just return the size if DOSIZEONLY is nonzero. */
757 write_rtnend (int rtnnum
, int dosizeonly
)
759 DST_ROUTINE_END rtnend
;
760 char label1
[MAX_ARTIFICIAL_LABEL_BYTES
];
761 char label2
[MAX_ARTIFICIAL_LABEL_BYTES
];
766 rtnend
.dst_a_rtnend_header
.dst__header_length
.dst_w_length
767 = DST_K_RTNEND_SIZE
- 1;
768 rtnend
.dst_a_rtnend_header
.dst__header_type
.dst_w_type
= DST_K_RTNEND
;
769 rtnend
.dst_b_rtnend_unused
= 0;
770 rtnend
.dst_l_rtnend_size
= 0; /* Calculated below. */
772 totsize
+= write_debug_header (&rtnend
.dst_a_rtnend_header
, "rtnend",
774 totsize
+= write_debug_data1 (rtnend
.dst_b_rtnend_unused
, "unused",
777 ASM_GENERATE_INTERNAL_LABEL
778 (label1
, FUNC_BEGIN_LABEL
,
779 VEC_index (unsigned, funcnum_table
, rtnnum
));
780 ASM_GENERATE_INTERNAL_LABEL
781 (label2
, FUNC_END_LABEL
,
782 VEC_index (unsigned, funcnum_table
, rtnnum
));
783 totsize
+= write_debug_delta4 (label2
, label1
, "routine size", dosizeonly
);
788 #define K_DELTA_PC(I) \
789 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
791 #define K_SET_LINUM(I) \
792 ((I) < 256 ? DST_K_SET_LINUM_B \
793 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
795 #define K_INCR_LINUM(I) \
796 ((I) < 256 ? DST_K_INCR_LINUM \
797 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
799 /* Output the PC to line number correlations and return the size. Just return
800 the size if DOSIZEONLY is nonzero */
803 write_pclines (int dosizeonly
)
810 DST_LINE_NUM_HEADER line_num
;
811 DST_PCLINE_COMMANDS pcline
;
812 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
813 char lastlabel
[MAX_ARTIFICIAL_LABEL_BYTES
];
817 max_line
= file_info_table
[1].max_line
;
818 file_info_table
[1].listing_line_start
= linestart
;
819 linestart
= linestart
+ ((max_line
/ 100000) + 1) * 100000;
821 for (i
= 2; i
< file_info_table_in_use
; i
++)
823 max_line
= file_info_table
[i
].max_line
;
824 file_info_table
[i
].listing_line_start
= linestart
;
825 linestart
= linestart
+ ((max_line
/ 10000) + 1) * 10000;
828 /* Set starting address to beginning of text section. */
829 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 8;
830 line_num
.dst_a_line_num_header
.dst__header_type
.dst_w_type
= DST_K_LINE_NUM
;
831 pcline
.dst_b_pcline_command
= DST_K_SET_ABS_PC
;
833 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
834 "line_num", dosizeonly
);
835 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
836 "line_num (SET ABS PC)", dosizeonly
);
842 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, TEXT_SECTION_ASM_OP
);
843 if (flag_verbose_asm
)
844 fprintf (asm_out_file
, "\t%s line_num", ASM_COMMENT_START
);
845 fputc ('\n', asm_out_file
);
848 fn
= line_info_table
[1].dst_file_num
;
849 ln
= (file_info_table
[fn
].listing_line_start
850 + line_info_table
[1].dst_line_num
);
851 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 4 + 4;
852 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
854 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
855 "line_num", dosizeonly
);
856 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
857 "line_num (SET LINUM LONG)", dosizeonly
);
859 sprintf (buff
, "line_num (%d)", ln
? ln
- 1 : 0);
860 totsize
+= write_debug_data4 (ln
? ln
- 1 : 0, buff
, dosizeonly
);
863 strcpy (lastlabel
, TEXT_SECTION_ASM_OP
);
864 for (i
= 1; i
< line_info_table_in_use
; i
++)
868 fn
= line_info_table
[i
].dst_file_num
;
869 ln
= (file_info_table
[fn
].listing_line_start
870 + line_info_table
[i
].dst_line_num
);
873 extrabytes
= 5; /* NUMBYTES (ln - lastln - 1) + 1; */
874 else if (ln
<= lastln
)
875 extrabytes
= 5; /* NUMBYTES (ln - 1) + 1; */
879 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
882 totsize
+= write_debug_header
883 (&line_num
.dst_a_line_num_header
, "line_num", dosizeonly
);
887 int lndif
= ln
- lastln
- 1;
889 /* K_INCR_LINUM (lndif); */
890 pcline
.dst_b_pcline_command
= DST_K_INCR_LINUM_L
;
892 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
893 "line_num (INCR LINUM LONG)",
896 sprintf (buff
, "line_num (%d)", lndif
);
897 totsize
+= write_debug_data4 (lndif
, buff
, dosizeonly
);
899 else if (ln
<= lastln
)
901 /* K_SET_LINUM (ln-1); */
902 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
904 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
905 "line_num (SET LINUM LONG)",
908 sprintf (buff
, "line_num (%d)", ln
- 1);
909 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
912 pcline
.dst_b_pcline_command
= DST_K_DELTA_PC_L
;
914 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
915 "line_num (DELTA PC LONG)", dosizeonly
);
917 ASM_GENERATE_INTERNAL_LABEL (label
, LINE_CODE_LABEL
, i
);
918 totsize
+= write_debug_delta4 (label
, lastlabel
, "increment line_num",
922 strcpy (lastlabel
, label
);
928 /* Output a source correlation for file FILEID using information saved in
929 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
933 write_srccorr (int fileid
, dst_file_info_entry file_info_entry
,
936 int src_command_size
;
937 int linesleft
= file_info_entry
.max_line
;
938 int linestart
= file_info_entry
.listing_line_start
;
939 int flen
= file_info_entry
.flen
;
941 DST_SOURCE_CORR src_header
;
942 DST_SRC_COMMAND src_command
;
943 DST_SRC_COMMAND src_command_sf
;
944 DST_SRC_COMMAND src_command_sl
;
945 DST_SRC_COMMAND src_command_sr
;
946 DST_SRC_COMMAND src_command_dl
;
947 DST_SRC_CMDTRLR src_cmdtrlr
;
953 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
954 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 1 - 1;
955 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
957 src_command
.dst_b_src_command
= DST_K_SRC_FORMFEED
;
959 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
960 "source corr", dosizeonly
);
962 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
963 "source_corr (SRC FORMFEED)",
968 = DST_K_SRC_COMMAND_SIZE
+ flen
+ DST_K_SRC_CMDTRLR_SIZE
;
969 src_command
.dst_b_src_command
= DST_K_SRC_DECLFILE
;
970 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
971 = src_command_size
- 2;
972 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
= 0;
973 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
975 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
976 = file_info_entry
.cdt
;
977 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
978 = file_info_entry
.ebk
;
979 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
980 = file_info_entry
.ffb
;
981 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
982 = file_info_entry
.rfo
;
983 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
984 = file_info_entry
.flen
;
986 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
987 = DST_K_SOURCE_CORR_HEADER_SIZE
+ src_command_size
- 1;
988 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
991 src_cmdtrlr
.dst_b_src_df_libmodname
= 0;
993 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
994 "source corr", dosizeonly
);
995 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
996 "source_corr (DECL SRC FILE)", dosizeonly
);
997 totsize
+= write_debug_data1
998 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
,
999 "source_corr (length)", dosizeonly
);
1001 totsize
+= write_debug_data1
1002 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
,
1003 "source_corr (flags)", dosizeonly
);
1005 totsize
+= write_debug_data2
1006 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
,
1007 "source_corr (fileid)", dosizeonly
);
1009 totsize
+= write_debug_data8
1010 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
,
1011 "source_corr (creation date)", dosizeonly
);
1013 totsize
+= write_debug_data4
1014 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
,
1015 "source_corr (EOF block number)", dosizeonly
);
1017 totsize
+= write_debug_data2
1018 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
,
1019 "source_corr (first free byte)", dosizeonly
);
1021 totsize
+= write_debug_data1
1022 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
,
1023 "source_corr (record and file organization)", dosizeonly
);
1025 totsize
+= write_debug_data1
1026 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
,
1027 "source_corr (filename length)", dosizeonly
);
1029 totsize
+= write_debug_string (remap_debug_filename (
1030 file_info_entry
.file_name
),
1031 "source file name", dosizeonly
);
1032 totsize
+= write_debug_data1 (src_cmdtrlr
.dst_b_src_df_libmodname
,
1033 "source_corr (libmodname)", dosizeonly
);
1035 src_command_sf
.dst_b_src_command
= DST_K_SRC_SETFILE
;
1036 src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
= fileid
;
1038 src_command_sr
.dst_b_src_command
= DST_K_SRC_SETREC_W
;
1039 src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
= 1;
1041 src_command_sl
.dst_b_src_command
= DST_K_SRC_SETLNUM_L
;
1042 src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
= linestart
+ 1;
1044 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1046 if (linesleft
> 65534)
1047 linesleft
= linesleft
- 65534, linestodo
= 65534;
1049 linestodo
= linesleft
, linesleft
= 0;
1051 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1053 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1054 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 + 3 + 5 + 3 - 1;
1055 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1058 if (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
)
1060 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1061 "source corr", dosizeonly
);
1063 totsize
+= write_debug_data1 (src_command_sf
.dst_b_src_command
,
1064 "source_corr (src setfile)", dosizeonly
);
1066 totsize
+= write_debug_data2
1067 (src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1068 "source_corr (fileid)", dosizeonly
);
1070 totsize
+= write_debug_data1 (src_command_sr
.dst_b_src_command
,
1071 "source_corr (setrec)", dosizeonly
);
1073 totsize
+= write_debug_data2
1074 (src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1075 "source_corr (recnum)", dosizeonly
);
1077 totsize
+= write_debug_data1 (src_command_sl
.dst_b_src_command
,
1078 "source_corr (setlnum)", dosizeonly
);
1080 totsize
+= write_debug_data4
1081 (src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
,
1082 "source_corr (linenum)", dosizeonly
);
1084 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1085 "source_corr (deflines)", dosizeonly
);
1087 sprintf (buff
, "source_corr (%d)",
1088 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1089 totsize
+= write_debug_data2
1090 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1093 while (linesleft
> 0)
1095 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1096 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 - 1;
1097 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1099 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1101 if (linesleft
> 65534)
1102 linesleft
= linesleft
- 65534, linestodo
= 65534;
1104 linestodo
= linesleft
, linesleft
= 0;
1106 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1108 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1109 "source corr", dosizeonly
);
1110 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1111 "source_corr (deflines)", dosizeonly
);
1112 sprintf (buff
, "source_corr (%d)",
1113 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1114 totsize
+= write_debug_data2
1115 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1123 /* Output all the source correlation entries and return the size. Just return
1124 the size if DOSIZEONLY is nonzero. */
1127 write_srccorrs (int dosizeonly
)
1132 for (i
= 1; i
< file_info_table_in_use
; i
++)
1133 totsize
+= write_srccorr (i
, file_info_table
[i
], dosizeonly
);
1138 /* Output a marker (i.e. a label) for the beginning of a function, before
1142 vmsdbgout_begin_prologue (unsigned int line
, const char *file
)
1144 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1146 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1147 (*dwarf2_debug_hooks
.begin_prologue
) (line
, file
);
1149 if (debug_info_level
> DINFO_LEVEL_NONE
)
1151 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_BEGIN_LABEL
,
1152 current_function_funcdef_no
);
1153 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1157 /* Output a marker (i.e. a label) for the beginning of a function, after
1161 vmsdbgout_end_prologue (unsigned int line
, const char *file
)
1163 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1165 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1166 (*dwarf2_debug_hooks
.end_prologue
) (line
, file
);
1168 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1170 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
,
1171 current_function_funcdef_no
);
1172 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1174 /* VMS PCA expects every PC range to correlate to some line and file. */
1175 vmsdbgout_source_line (line
, file
, 0, true);
1179 /* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1182 vmsdbgout_end_function (unsigned int line
)
1184 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1185 (*dwarf2_debug_hooks
.end_function
) (line
);
1188 /* Output a marker (i.e. a label) for the beginning of the epilogue.
1189 This gets called *before* the epilogue code has been generated. */
1192 vmsdbgout_begin_epilogue (unsigned int line
, const char *file
)
1194 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1195 static int save_current_function_funcdef_no
= -1;
1197 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1198 (*dwarf2_debug_hooks
.begin_epilogue
) (line
, file
);
1200 if (debug_info_level
> DINFO_LEVEL_NONE
)
1202 if (save_current_function_funcdef_no
!= current_function_funcdef_no
)
1204 /* Output a label to mark the endpoint of the code generated for this
1206 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_EPILOG_LABEL
,
1207 current_function_funcdef_no
);
1209 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1211 save_current_function_funcdef_no
= current_function_funcdef_no
;
1213 /* VMS PCA expects every PC range to correlate to some line and
1215 vmsdbgout_source_line (line
, file
, 0, true);
1220 /* Output a marker (i.e. a label) for the absolute end of the generated code
1221 for a function definition. This gets called *after* the epilogue code has
1225 vmsdbgout_end_epilogue (unsigned int line
, const char *file
)
1227 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1229 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1230 (*dwarf2_debug_hooks
.end_epilogue
) (line
, file
);
1232 if (debug_info_level
> DINFO_LEVEL_NONE
)
1234 /* Output a label to mark the endpoint of the code generated for this
1236 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_END_LABEL
,
1237 current_function_funcdef_no
);
1238 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1240 /* VMS PCA expects every PC range to correlate to some line and file. */
1241 vmsdbgout_source_line (line
, file
, 0, true);
1245 /* Output a marker (i.e. a label) for the beginning of the generated code for
1249 vmsdbgout_begin_block (register unsigned line
, register unsigned blocknum
)
1251 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1252 (*dwarf2_debug_hooks
.begin_block
) (line
, blocknum
);
1254 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1255 targetm
.asm_out
.internal_label (asm_out_file
, BLOCK_BEGIN_LABEL
, blocknum
);
1258 /* Output a marker (i.e. a label) for the end of the generated code for a
1262 vmsdbgout_end_block (register unsigned line
, register unsigned blocknum
)
1264 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1265 (*dwarf2_debug_hooks
.end_block
) (line
, blocknum
);
1267 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1268 targetm
.asm_out
.internal_label (asm_out_file
, BLOCK_END_LABEL
, blocknum
);
1271 /* Not implemented in VMS Debug. */
1274 vmsdbgout_ignore_block (const_tree block
)
1278 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1279 retval
= (*dwarf2_debug_hooks
.ignore_block
) (block
);
1284 /* Add an entry for function DECL into the funcnam_table. */
1287 vmsdbgout_begin_function (tree decl
)
1289 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
1291 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1292 (*dwarf2_debug_hooks
.begin_function
) (decl
);
1294 /* Add the new entry to the end of the function name table. */
1295 VEC_safe_push (char_p
, heap
, funcnam_table
, xstrdup (name
));
1296 VEC_safe_push (unsigned, heap
, funcnum_table
,
1297 current_function_funcdef_no
);
1300 static char fullname_buff
[4096];
1302 /* Return the full file specification for FILENAME. The specification must be
1303 in VMS syntax in order to be processed by VMS Debug. */
1306 full_name (const char *filename
)
1309 FILE *fp
= fopen (filename
, "r");
1311 fgetname (fp
, fullname_buff
, 1);
1314 /* Unix paths really mess up VMS debug. Better to just output the
1316 strcpy (fullname_buff
, filename
);
1319 return fullname_buff
;
1322 /* Lookup a filename (in the list of filenames that we know about here in
1323 vmsdbgout.c) and return its "index". The index of each (known) filename is
1324 just a unique number which is associated with only that one filename. We
1325 need such numbers for the sake of generating labels and references
1326 to those files numbers. If the filename given as an argument is not
1327 found in our current list, add it to the list and assign it the next
1328 available unique index number. In order to speed up searches, we remember
1329 the index of the filename was looked up last. This handles the majority of
1333 lookup_filename (const char *file_name
)
1335 static unsigned int last_file_lookup_index
= 0;
1337 register unsigned i
;
1347 fnam
= full_name (file_name
);
1348 flen
= strlen (fnam
);
1350 /* Check to see if the file name that was searched on the previous call
1351 matches this file name. If so, return the index. */
1352 if (last_file_lookup_index
!= 0)
1354 fn
= file_info_table
[last_file_lookup_index
].file_name
;
1355 if (strcmp (fnam
, fn
) == 0)
1356 return last_file_lookup_index
;
1359 /* Didn't match the previous lookup, search the table */
1360 for (i
= 1; i
< file_info_table_in_use
; ++i
)
1362 fn
= file_info_table
[i
].file_name
;
1363 if (strcmp (fnam
, fn
) == 0)
1365 last_file_lookup_index
= i
;
1370 /* Prepare to add a new table entry by making sure there is enough space in
1371 the table to do so. If not, expand the current table. */
1372 if (file_info_table_in_use
== file_info_table_allocated
)
1375 file_info_table_allocated
+= FILE_TABLE_INCREMENT
;
1376 file_info_table
= XRESIZEVEC (dst_file_info_entry
, file_info_table
,
1377 file_info_table_allocated
);
1380 if (vms_file_stats_name (file_name
, &cdt
, &siz
, &rfo
, &ver
) == 0)
1382 ebk
= siz
/ 512 + 1;
1383 ffb
= siz
- ((siz
/ 512) * 512);
1386 /* Add the new entry to the end of the filename table. */
1387 file_info_table
[file_info_table_in_use
].file_name
= xstrdup (fnam
);
1388 file_info_table
[file_info_table_in_use
].max_line
= 0;
1389 file_info_table
[file_info_table_in_use
].cdt
= cdt
;
1390 file_info_table
[file_info_table_in_use
].ebk
= ebk
;
1391 file_info_table
[file_info_table_in_use
].ffb
= ffb
;
1392 file_info_table
[file_info_table_in_use
].rfo
= rfo
;
1393 file_info_table
[file_info_table_in_use
].flen
= flen
;
1395 last_file_lookup_index
= file_info_table_in_use
++;
1396 return last_file_lookup_index
;
1399 /* Output a label to mark the beginning of a source code line entry
1400 and record information relating to this source line, in
1401 'line_info_table' for later output of the .debug_line section. */
1404 vmsdbgout_source_line (register unsigned line
, register const char *filename
,
1405 int discriminator
, bool is_stmt
)
1407 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1408 (*dwarf2_debug_hooks
.source_line
) (line
, filename
, discriminator
, is_stmt
);
1410 if (debug_info_level
>= DINFO_LEVEL_TERSE
)
1412 dst_line_info_ref line_info
;
1414 targetm
.asm_out
.internal_label (asm_out_file
, LINE_CODE_LABEL
,
1415 line_info_table_in_use
);
1417 /* Expand the line info table if necessary. */
1418 if (line_info_table_in_use
== line_info_table_allocated
)
1420 line_info_table_allocated
+= LINE_INFO_TABLE_INCREMENT
;
1421 line_info_table
= XRESIZEVEC (dst_line_info_entry
, line_info_table
,
1422 line_info_table_allocated
);
1425 /* Add the new entry at the end of the line_info_table. */
1426 line_info
= &line_info_table
[line_info_table_in_use
++];
1427 line_info
->dst_file_num
= lookup_filename (filename
);
1428 line_info
->dst_line_num
= line
;
1429 if (line
> file_info_table
[line_info
->dst_file_num
].max_line
)
1430 file_info_table
[line_info
->dst_file_num
].max_line
= line
;
1434 /* Record the beginning of a new source file, for later output.
1435 At present, unimplemented. */
1438 vmsdbgout_start_source_file (unsigned int lineno
, const char *filename
)
1440 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1441 (*dwarf2_debug_hooks
.start_source_file
) (lineno
, filename
);
1444 /* Record the end of a source file, for later output.
1445 At present, unimplemented. */
1448 vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED
)
1450 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1451 (*dwarf2_debug_hooks
.end_source_file
) (lineno
);
1454 /* Set up for Debug output at the start of compilation. */
1457 vmsdbgout_init (const char *filename
)
1459 const char *language_string
= lang_hooks
.name
;
1461 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1462 (*dwarf2_debug_hooks
.init
) (filename
);
1464 if (debug_info_level
== DINFO_LEVEL_NONE
)
1467 /* Remember the name of the primary input file. */
1468 primary_filename
= filename
;
1470 /* Allocate the initial hunk of the file_info_table. */
1471 file_info_table
= XCNEWVEC (dst_file_info_entry
, FILE_TABLE_INCREMENT
);
1472 file_info_table_allocated
= FILE_TABLE_INCREMENT
;
1473 /* Skip the first entry - file numbers begin at 1. */
1474 file_info_table_in_use
= 1;
1476 funcnam_table
= VEC_alloc (char_p
, heap
, FUNC_TABLE_INITIAL
);
1477 funcnum_table
= VEC_alloc (unsigned, heap
, FUNC_TABLE_INITIAL
);
1479 /* Allocate the initial hunk of the line_info_table. */
1480 line_info_table
= XCNEWVEC (dst_line_info_entry
, LINE_INFO_TABLE_INCREMENT
);
1481 line_info_table_allocated
= LINE_INFO_TABLE_INCREMENT
;
1482 /* zero-th entry is allocated, but unused */
1483 line_info_table_in_use
= 1;
1485 lookup_filename (primary_filename
);
1487 if (!strcmp (language_string
, "GNU C"))
1488 module_language
= DST_K_C
;
1489 else if (!strcmp (language_string
, "GNU C++"))
1490 module_language
= DST_K_CXX
;
1491 else if (!strcmp (language_string
, "GNU Ada"))
1492 module_language
= DST_K_ADA
;
1493 else if (!strcmp (language_string
, "GNU F77"))
1494 module_language
= DST_K_FORTRAN
;
1496 module_language
= DST_K_UNKNOWN
;
1498 module_producer
= concat (language_string
, " ", version_string
, NULL
);
1500 ASM_GENERATE_INTERNAL_LABEL (text_end_label
, TEXT_END_LABEL
, 0);
1504 /* Not implemented in VMS Debug. */
1507 vmsdbgout_assembly_start (void)
1509 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1510 (*dwarf2_debug_hooks
.assembly_start
) ();
1513 /* Not implemented in VMS Debug. */
1516 vmsdbgout_define (unsigned int lineno
, const char *buffer
)
1518 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1519 (*dwarf2_debug_hooks
.define
) (lineno
, buffer
);
1522 /* Not implemented in VMS Debug. */
1525 vmsdbgout_undef (unsigned int lineno
, const char *buffer
)
1527 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1528 (*dwarf2_debug_hooks
.undef
) (lineno
, buffer
);
1531 /* Not implemented in VMS Debug. */
1534 vmsdbgout_decl (tree decl
)
1536 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1537 (*dwarf2_debug_hooks
.function_decl
) (decl
);
1540 /* Not implemented in VMS Debug. */
1543 vmsdbgout_global_decl (tree decl
)
1545 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1546 (*dwarf2_debug_hooks
.global_decl
) (decl
);
1549 /* Not implemented in VMS Debug. */
1552 vmsdbgout_type_decl (tree decl
, int local
)
1554 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1555 (*dwarf2_debug_hooks
.type_decl
) (decl
, local
);
1558 /* Not implemented in VMS Debug. */
1561 vmsdbgout_abstract_function (tree decl
)
1563 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1564 (*dwarf2_debug_hooks
.outlining_inline_function
) (decl
);
1567 /* Output stuff that Debug requires at the end of every file and generate the
1568 VMS Debug debugging info. */
1571 vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED
)
1573 unsigned int i
, ifunc
;
1576 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1577 (*dwarf2_debug_hooks
.finish
) (filename
);
1579 if (debug_info_level
== DINFO_LEVEL_NONE
)
1582 /* Output a terminator label for the .text section. */
1583 switch_to_section (text_section
);
1584 targetm
.asm_out
.internal_label (asm_out_file
, TEXT_END_LABEL
, 0);
1586 /* Output debugging information.
1587 Warning! Do not change the name of the .vmsdebug section without
1588 changing it in the assembler also. */
1589 switch_to_section (get_named_section (NULL
, ".vmsdebug", 0));
1590 ASM_OUTPUT_ALIGN (asm_out_file
, 0);
1592 totsize
= write_modbeg (1);
1593 FOR_EACH_VEC_ELT (unsigned, funcnum_table
, i
, ifunc
)
1595 totsize
+= write_rtnbeg (i
, 1);
1596 totsize
+= write_rtnend (i
, 1);
1598 totsize
+= write_pclines (1);
1601 FOR_EACH_VEC_ELT (unsigned, funcnum_table
, i
, ifunc
)
1603 write_rtnbeg (i
, 0);
1604 write_rtnend (i
, 0);
1608 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1610 totsize
= write_srccorrs (1);
1614 totsize
= write_modend (1);
1618 /* Need for both Dwarf2 on IVMS and VMS Debug on AVMS */
1621 #define __NEW_STARLET 1
1622 #include <vms/rms.h>
1623 #include <vms/atrdef.h>
1624 #include <vms/fibdef.h>
1625 #include <vms/stsdef.h>
1626 #include <vms/iodef.h>
1627 #include <vms/fatdef.h>
1628 #include <vms/descrip.h>
1629 #include <unixlib.h>
1633 /* descrip.h doesn't have everything ... */
1634 typedef struct fibdef
* __fibdef_ptr32
__attribute__ (( mode (SI
) ));
1635 struct dsc$descriptor_fib
1637 unsigned int fib$l_len
;
1638 __fibdef_ptr32 fib$l_addr
;
1641 /* I/O Status Block. */
1644 unsigned short status
, count
;
1645 unsigned int devdep
;
1648 static char *tryfile
;
1650 /* Variable length string. */
1654 char string
[NAM$C_MAXRSS
+1];
1657 static char filename_buff
[MAXPATH
];
1658 static char vms_filespec
[MAXPATH
];
1660 /* Callback function for filespec style conversion. */
1663 translate_unix (char *name
, int type ATTRIBUTE_UNUSED
)
1665 strncpy (filename_buff
, name
, MAXPATH
);
1666 filename_buff
[MAXPATH
- 1] = (char) 0;
1670 /* Wrapper for DECC function that converts a Unix filespec
1671 to VMS style filespec. */
1674 to_vms_file_spec (char *filespec
)
1676 strncpy (vms_filespec
, "", MAXPATH
);
1677 decc$
to_vms (filespec
, translate_unix
, 1, 1);
1678 strncpy (vms_filespec
, filename_buff
, MAXPATH
);
1680 vms_filespec
[MAXPATH
- 1] = (char) 0;
1682 return vms_filespec
;
1686 #define VMS_EPOCH_OFFSET 35067168000000000
1687 #define VMS_GRANULARITY_FACTOR 10000000
1690 /* Return VMS file date, size, format, version given a name. */
1693 vms_file_stats_name (const char *filename
, long long *cdt
, long *siz
, char *rfo
,
1700 unsigned long long create
;
1702 char ascnamebuff
[256];
1706 { ATR$S_CREDATE
, ATR$C_CREDATE
, &create
},
1707 { ATR$S_RECATTR
, ATR$C_RECATTR
, &recattr
},
1708 { ATR$S_ASCNAME
, ATR$C_ASCNAME
, &ascnamebuff
},
1713 struct dsc$descriptor_fib fibdsc
= {sizeof (fib
), (void *) &fib
};
1718 unsigned short chan
;
1720 struct vstring file
;
1721 struct dsc$descriptor_s filedsc
1722 = {NAM$C_MAXRSS
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, (void *) file
.string
};
1723 struct vstring device
;
1724 struct dsc$descriptor_s devicedsc
1725 = {NAM$C_MAXRSS
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, (void *) device
.string
};
1726 struct vstring result
;
1727 struct dsc$descriptor_s resultdsc
1728 = {NAM$C_MAXRSS
, DSC$K_DTYPE_VT
, DSC$K_CLASS_VS
, (void *) result
.string
};
1730 if (strcmp (filename
, "<internal>") == 0
1731 || strcmp (filename
, "<built-in>") == 0)
1748 tryfile
= to_vms_file_spec (filename
);
1750 /* Allocate and initialize a FAB and NAM structures. */
1754 nam
.nam$l_esa
= file
.string
;
1755 nam
.nam$b_ess
= NAM$C_MAXRSS
;
1756 nam
.nam$l_rsa
= result
.string
;
1757 nam
.nam$b_rss
= NAM$C_MAXRSS
;
1758 fab
.fab$l_fna
= tryfile
;
1759 fab
.fab$b_fns
= strlen (tryfile
);
1760 fab
.fab$l_nam
= &nam
;
1762 /* Validate filespec syntax and device existence. */
1763 status
= SYS$
PARSE (&fab
, 0, 0);
1764 if ((status
& 1) != 1)
1767 file
.string
[nam
.nam$b_esl
] = 0;
1769 /* Find matching filespec. */
1770 status
= SYS$
SEARCH (&fab
, 0, 0);
1771 if ((status
& 1) != 1)
1774 file
.string
[nam
.nam$b_esl
] = 0;
1775 result
.string
[result
.length
=nam
.nam$b_rsl
] = 0;
1777 /* Get the device name and assign an IO channel. */
1778 strncpy (device
.string
, nam
.nam$l_dev
, nam
.nam$b_dev
);
1779 devicedsc
.dsc$w_length
= nam
.nam$b_dev
;
1781 status
= SYS$
ASSIGN (&devicedsc
, &chan
, 0, 0, 0);
1782 if ((status
& 1) != 1)
1785 /* Initialize the FIB and fill in the directory id field. */
1786 memset (&fib
, 0, sizeof (fib
));
1787 fib
.fib$w_did
[0] = nam
.nam$w_did
[0];
1788 fib
.fib$w_did
[1] = nam
.nam$w_did
[1];
1789 fib
.fib$w_did
[2] = nam
.nam$w_did
[2];
1790 fib
.fib$l_acctl
= 0;
1792 strcpy (file
.string
, (strrchr (result
.string
, ']') + 1));
1793 filedsc
.dsc$w_length
= strlen (file
.string
);
1794 result
.string
[result
.length
= 0] = 0;
1796 /* Open and close the file to fill in the attributes. */
1798 = SYS$
QIOW (0, chan
, IO$_ACCESS
|IO$M_ACCESS
, &iosb
, 0, 0,
1799 &fibdsc
, &filedsc
, &result
.length
, &resultdsc
, &atrlst
, 0);
1800 if ((status
& 1) != 1)
1802 if ((iosb
.status
& 1) != 1)
1805 result
.string
[result
.length
] = 0;
1806 status
= SYS$
QIOW (0, chan
, IO$_DEACCESS
, &iosb
, 0, 0, &fibdsc
, 0, 0, 0,
1808 if ((status
& 1) != 1)
1810 if ((iosb
.status
& 1) != 1)
1813 /* Deassign the channel and exit. */
1814 status
= SYS$
DASSGN (chan
);
1815 if ((status
& 1) != 1)
1818 if (cdt
) *cdt
= create
;
1819 if (siz
) *siz
= (512 * 65536 * recattr
.fat$w_efblkh
) +
1820 (512 * (recattr
.fat$w_efblkl
- 1)) +
1821 recattr
.fat$w_ffbyte
;
1822 if (rfo
) *rfo
= recattr
.fat$v_rtype
;
1823 if (ver
) *ver
= strtol (strrchr (ascnamebuff
, ';')+1, 0, 10);
1829 if ((stat (filename
, &buff
)) != 0)
1833 *cdt
= (long long) (buff
.st_mtime
* VMS_GRANULARITY_FACTOR
)
1837 *siz
= buff
.st_size
;
1840 *rfo
= 2; /* Stream LF format */