]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/vmsdbgout.c
alias.c [...]: Remove unnecessary casts.
[thirdparty/gcc.git] / gcc / vmsdbgout.c
CommitLineData
54a7b573 1/* Output VMS debug format symbol table information from GCC.
487c9b1a 2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
2e1eedd6 3 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
7a0c8d71
DR
4 Contributed by Douglas B. Rupp (rupp@gnat.com).
5
54a7b573 6This file is part of GCC.
7a0c8d71 7
487c9b1a
RK
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
7a0c8d71 12
487c9b1a
RK
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
7a0c8d71
DR
17
18You should have received a copy of the GNU General Public License
487c9b1a
RK
19along with GCC; see the file COPYING. If not, write to the Free
20Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA. */
7a0c8d71
DR
22
23#include "config.h"
4977bab6
ZW
24#include "system.h"
25#include "coretypes.h"
26#include "tm.h"
7a0c8d71
DR
27
28#ifdef VMS_DEBUGGING_INFO
7a0c8d71
DR
29#include "tree.h"
30#include "flags.h"
31#include "rtl.h"
32#include "output.h"
33#include "vmsdbg.h"
34#include "debug.h"
35#include "langhooks.h"
dd86aabf 36#include "function.h"
4977bab6 37#include "target.h"
7a0c8d71
DR
38
39/* Difference in seconds between the VMS Epoch and the Unix Epoch */
40static const long long vms_epoch_offset = 3506716800ll;
41
42/* NOTE: In the comments in this file, many references are made to "Debug
43 Symbol Table". This term is abbreviated as `DST' throughout the remainder
44 of this file. */
45
46typedef struct dst_line_info_struct *dst_line_info_ref;
47
48/* Each entry in the line_info_table maintains the file and
49 line number associated with the label generated for that
50 entry. The label gives the PC value associated with
51 the line number entry. */
52typedef struct dst_line_info_struct
53{
54 unsigned long dst_file_num;
55 unsigned long dst_line_num;
56}
57dst_line_info_entry;
58
59typedef struct dst_file_info_struct *dst_file_info_ref;
60
61typedef struct dst_file_info_struct
62{
63 char *file_name;
64 unsigned int max_line;
65 unsigned int listing_line_start;
66 long long cdt;
67 long ebk;
68 short ffb;
69 char rfo;
70 char flen;
71}
72dst_file_info_entry;
73
74/* How to start an assembler comment. */
75#ifndef ASM_COMMENT_START
76#define ASM_COMMENT_START ";#"
77#endif
78
3ef42a0c 79/* Maximum size (in bytes) of an artificially generated label. */
7a0c8d71
DR
80#define MAX_ARTIFICIAL_LABEL_BYTES 30
81
82/* Make sure we know the sizes of the various types debug can describe. These
83 are only defaults. If the sizes are different for your target, you should
84 override these values by defining the appropriate symbols in your tm.h
85 file. */
7a0c8d71
DR
86#ifndef PTR_SIZE
87#define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
88#endif
89
09da1532 90/* Pointer to a structure of filenames referenced by this compilation unit. */
7a0c8d71
DR
91static dst_file_info_ref file_info_table;
92
93/* Total number of entries in the table (i.e. array) pointed to by
94 `file_info_table'. This is the *total* and includes both used and unused
95 slots. */
96static unsigned int file_info_table_allocated;
97
98/* Number of entries in the file_info_table which are actually in use. */
99static unsigned int file_info_table_in_use;
100
101/* Size (in elements) of increments by which we may expand the filename
102 table. */
103#define FILE_TABLE_INCREMENT 64
104
105static char **func_table;
106static unsigned int func_table_allocated;
107static unsigned int func_table_in_use;
108#define FUNC_TABLE_INCREMENT 256
109
110/* Local pointer to the name of the main input file. Initialized in
111 avmdbgout_init. */
112static const char *primary_filename;
113
114static char *module_producer;
115static unsigned int module_language;
116
117/* A pointer to the base of a table that contains line information
118 for each source code line in .text in the compilation unit. */
119static dst_line_info_ref line_info_table;
120
121/* Number of elements currently allocated for line_info_table. */
122static unsigned int line_info_table_allocated;
123
124/* Number of elements in line_info_table currently in use. */
125static unsigned int line_info_table_in_use;
126
127/* Size (in elements) of increments by which we may expand line_info_table. */
128#define LINE_INFO_TABLE_INCREMENT 1024
129
7a0c8d71 130/* Forward declarations for functions defined in this file. */
2e1eedd6
AJ
131static char *full_name (const char *);
132static unsigned int lookup_filename (const char *);
133static void addr_const_to_string (char *, rtx);
134static int write_debug_header (DST_HEADER *, const char *, int);
135static int write_debug_addr (char *, const char *, int);
136static int write_debug_data1 (unsigned int, const char *, int);
137static int write_debug_data2 (unsigned int, const char *, int);
138static int write_debug_data4 (unsigned long, const char *, int);
139static int write_debug_data8 (unsigned long long, const char *, int);
140static int write_debug_delta4 (char *, char *, const char *, int);
141static int write_debug_string (char *, const char *, int);
142static int write_modbeg (int);
143static int write_modend (int);
144static int write_rtnbeg (int, int);
145static int write_rtnend (int, int);
146static int write_pclines (int);
147static int write_srccorr (int, dst_file_info_entry, int);
148static int write_srccorrs (int);
149
150static void vmsdbgout_init (const char *);
151static void vmsdbgout_finish (const char *);
152static void vmsdbgout_define (unsigned int, const char *);
153static void vmsdbgout_undef (unsigned int, const char *);
154static void vmsdbgout_start_source_file (unsigned int, const char *);
155static void vmsdbgout_end_source_file (unsigned int);
156static void vmsdbgout_begin_block (unsigned int, unsigned int);
157static void vmsdbgout_end_block (unsigned int, unsigned int);
158static bool vmsdbgout_ignore_block (tree);
159static void vmsdbgout_source_line (unsigned int, const char *);
160static void vmsdbgout_begin_prologue (unsigned int, const char *);
161static void vmsdbgout_end_prologue (unsigned int, const char *);
162static void vmsdbgout_end_function (unsigned int);
163static void vmsdbgout_end_epilogue (unsigned int, const char *);
164static void vmsdbgout_begin_function (tree);
165static void vmsdbgout_decl (tree);
166static void vmsdbgout_global_decl (tree);
167static void vmsdbgout_abstract_function (tree);
7a0c8d71 168
7a0c8d71
DR
169/* The debug hooks structure. */
170
54b6670a 171const struct gcc_debug_hooks vmsdbg_debug_hooks
7a0c8d71
DR
172= {vmsdbgout_init,
173 vmsdbgout_finish,
174 vmsdbgout_define,
175 vmsdbgout_undef,
176 vmsdbgout_start_source_file,
177 vmsdbgout_end_source_file,
178 vmsdbgout_begin_block,
179 vmsdbgout_end_block,
180 vmsdbgout_ignore_block,
181 vmsdbgout_source_line,
182 vmsdbgout_begin_prologue,
702ada3d
DR
183 vmsdbgout_end_prologue,
184 vmsdbgout_end_epilogue,
185 vmsdbgout_begin_function,
186 vmsdbgout_end_function,
7a0c8d71
DR
187 vmsdbgout_decl,
188 vmsdbgout_global_decl,
189 debug_nothing_tree, /* deferred_inline_function */
190 vmsdbgout_abstract_function,
33b49800
GK
191 debug_nothing_rtx, /* label */
192 debug_nothing_int /* handle_pch */
7a0c8d71
DR
193};
194
195/* Definitions of defaults for assembler-dependent names of various
196 pseudo-ops and section names.
197 Theses may be overridden in the tm.h file (if necessary) for a particular
198 assembler. */
199#ifdef UNALIGNED_SHORT_ASM_OP
200#undef UNALIGNED_SHORT_ASM_OP
201#endif
202#define UNALIGNED_SHORT_ASM_OP ".word"
203
204#ifdef UNALIGNED_INT_ASM_OP
205#undef UNALIGNED_INT_ASM_OP
206#endif
207#define UNALIGNED_INT_ASM_OP ".long"
208
209#ifdef UNALIGNED_LONG_ASM_OP
210#undef UNALIGNED_LONG_ASM_OP
211#endif
212#define UNALIGNED_LONG_ASM_OP ".long"
213
214#ifdef UNALIGNED_DOUBLE_INT_ASM_OP
215#undef UNALIGNED_DOUBLE_INT_ASM_OP
216#endif
217#define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
218
219#ifdef ASM_BYTE_OP
220#undef ASM_BYTE_OP
221#endif
222#define ASM_BYTE_OP ".byte"
223
224#define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
225
226#define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
227
228#ifndef UNALIGNED_PTR_ASM_OP
229#define UNALIGNED_PTR_ASM_OP \
230 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
231#endif
232
233#ifndef UNALIGNED_OFFSET_ASM_OP
234#define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
235 (NUMBYTES(OFFSET) == 4 \
236 ? UNALIGNED_LONG_ASM_OP \
237 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
238#endif
239
7a0c8d71
DR
240/* Definitions of defaults for formats and names of various special
241 (artificial) labels which may be generated within this file (when the -g
242 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
243 may be overridden from within the tm.h file, but typically, overriding these
244 defaults is unnecessary. */
245
246static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
247
248#ifndef TEXT_END_LABEL
249#define TEXT_END_LABEL "Lvetext"
250#endif
251#ifndef FUNC_BEGIN_LABEL
252#define FUNC_BEGIN_LABEL "LVFB"
253#endif
254#ifndef FUNC_PROLOG_LABEL
255#define FUNC_PROLOG_LABEL "LVFP"
256#endif
257#ifndef FUNC_END_LABEL
258#define FUNC_END_LABEL "LVFE"
259#endif
260#ifndef BLOCK_BEGIN_LABEL
261#define BLOCK_BEGIN_LABEL "LVBB"
262#endif
263#ifndef BLOCK_END_LABEL
264#define BLOCK_END_LABEL "LVBE"
265#endif
266#ifndef LINE_CODE_LABEL
267#define LINE_CODE_LABEL "LVM"
268#endif
269
270#ifndef ASM_OUTPUT_DEBUG_DELTA2
c203e7fe
KH
271#define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
272 do \
273 { \
274 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
275 assemble_name (FILE, LABEL1); \
276 fprintf (FILE, "-"); \
277 assemble_name (FILE, LABEL2); \
278 } \
279 while (0)
7a0c8d71
DR
280#endif
281
282#ifndef ASM_OUTPUT_DEBUG_DELTA4
c203e7fe
KH
283#define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
284 do \
285 { \
286 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
287 assemble_name (FILE, LABEL1); \
288 fprintf (FILE, "-"); \
289 assemble_name (FILE, LABEL2); \
290 } \
291 while (0)
7a0c8d71
DR
292#endif
293
294#ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
c203e7fe
KH
295#define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
296 do \
297 { \
298 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
299 assemble_name (FILE, LABEL1); \
300 fprintf (FILE, "-"); \
301 assemble_name (FILE, LABEL2); \
302 } \
303 while (0)
7a0c8d71
DR
304#endif
305
306#ifndef ASM_OUTPUT_DEBUG_ADDR
c203e7fe
KH
307#define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
308 do \
309 { \
310 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
311 assemble_name (FILE, LABEL); \
312 } \
313 while (0)
7a0c8d71
DR
314#endif
315
316#ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
317#define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
318 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
319#endif
320
321#ifndef ASM_OUTPUT_DEBUG_DATA1
322#define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
323 fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned char) VALUE)
324#endif
325
326#ifndef ASM_OUTPUT_DEBUG_DATA2
327#define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
328 fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, \
329 (unsigned short) VALUE)
330#endif
331
332#ifndef ASM_OUTPUT_DEBUG_DATA4
333#define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
334 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
335#endif
336
337#ifndef ASM_OUTPUT_DEBUG_DATA
338#define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
339 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
340#endif
341
342#ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
343#define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
344 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_PTR_ASM_OP, \
345 (unsigned long) VALUE)
346#endif
347
348#ifndef ASM_OUTPUT_DEBUG_DATA8
349#define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
350 fprintf ((FILE), "\t%s\t0x%llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
351 (unsigned long long) VALUE)
352#endif
353
354/* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
3d042e77 355 newline is produced. When flag_verbose_asm is asserted, we add commentary
7a0c8d71
DR
356 at the end of the line, so we must avoid output of a newline here. */
357#ifndef ASM_OUTPUT_DEBUG_STRING
c203e7fe
KH
358#define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
359 do \
360 { \
361 register int slen = strlen(P); \
362 register char *p = (P); \
363 register int i; \
364 fprintf (FILE, "\t.ascii \""); \
365 for (i = 0; i < slen; i++) \
366 { \
367 register int c = p[i]; \
368 if (c == '\"' || c == '\\') \
369 putc ('\\', FILE); \
370 if (c >= ' ' && c < 0177) \
371 putc (c, FILE); \
372 else \
373 fprintf (FILE, "\\%o", c); \
374 } \
375 fprintf (FILE, "\""); \
376 } \
7a0c8d71
DR
377 while (0)
378#endif
379
380/* Convert a reference to the assembler name of a C-level name. This
381 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
382 a string rather than writing to a file. */
383#ifndef ASM_NAME_TO_STRING
2e1eedd6 384#define ASM_NAME_TO_STRING(STR, NAME) \
c203e7fe
KH
385 do \
386 { \
387 if ((NAME)[0] == '*') \
388 strcpy (STR, NAME+1); \
389 else \
390 strcpy (STR, NAME); \
391 } \
7a0c8d71
DR
392 while (0)
393#endif
394
395\f
396/* General utility functions. */
397
398/* Convert an integer constant expression into assembler syntax. Addition and
399 subtraction are the only arithmetic that may appear in these expressions.
400 This is an adaptation of output_addr_const in final.c. Here, the target
401 of the conversion is a string buffer. We can't use output_addr_const
402 directly, because it writes to a file. */
403
404static void
2e1eedd6 405addr_const_to_string (char *str, rtx x)
7a0c8d71
DR
406{
407 char buf1[256];
408 char buf2[256];
409
410restart:
411 str[0] = '\0';
412 switch (GET_CODE (x))
413 {
414 case PC:
415 if (flag_pic)
416 strcat (str, ",");
417 else
418 abort ();
419 break;
420
421 case SYMBOL_REF:
422 ASM_NAME_TO_STRING (buf1, XSTR (x, 0));
423 strcat (str, buf1);
424 break;
425
426 case LABEL_REF:
427 ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
428 ASM_NAME_TO_STRING (buf2, buf1);
429 strcat (str, buf2);
430 break;
431
432 case CODE_LABEL:
433 ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (x));
434 ASM_NAME_TO_STRING (buf2, buf1);
435 strcat (str, buf2);
436 break;
437
438 case CONST_INT:
439 sprintf (buf1, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
440 strcat (str, buf1);
441 break;
442
443 case CONST:
41077ce4 444 /* This used to output parentheses around the expression, but that does
7a0c8d71
DR
445 not work on the 386 (either ATT or BSD assembler). */
446 addr_const_to_string (buf1, XEXP (x, 0));
447 strcat (str, buf1);
448 break;
449
450 case CONST_DOUBLE:
451 if (GET_MODE (x) == VOIDmode)
452 {
453 /* We can use %d if the number is one word and positive. */
454 if (CONST_DOUBLE_HIGH (x))
455 sprintf (buf1, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
456 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
457 else if (CONST_DOUBLE_LOW (x) < 0)
458 sprintf (buf1, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
459 else
460 sprintf (buf1, HOST_WIDE_INT_PRINT_DEC,
461 CONST_DOUBLE_LOW (x));
462 strcat (str, buf1);
463 }
464 else
465 /* We can't handle floating point constants; PRINT_OPERAND must
466 handle them. */
467 output_operand_lossage ("floating constant misused");
468 break;
469
470 case PLUS:
471 /* Some assemblers need integer constants to appear last (eg masm). */
472 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
473 {
474 addr_const_to_string (buf1, XEXP (x, 1));
475 strcat (str, buf1);
476 if (INTVAL (XEXP (x, 0)) >= 0)
477 strcat (str, "+");
478 addr_const_to_string (buf1, XEXP (x, 0));
479 strcat (str, buf1);
480 }
481 else
482 {
483 addr_const_to_string (buf1, XEXP (x, 0));
484 strcat (str, buf1);
485 if (INTVAL (XEXP (x, 1)) >= 0)
486 strcat (str, "+");
487 addr_const_to_string (buf1, XEXP (x, 1));
488 strcat (str, buf1);
489 }
490 break;
491
492 case MINUS:
493 /* Avoid outputting things like x-x or x+5-x, since some assemblers
494 can't handle that. */
495 x = simplify_subtraction (x);
496 if (GET_CODE (x) != MINUS)
497 goto restart;
498
499 addr_const_to_string (buf1, XEXP (x, 0));
500 strcat (str, buf1);
501 strcat (str, "-");
502 if (GET_CODE (XEXP (x, 1)) == CONST_INT
503 && INTVAL (XEXP (x, 1)) < 0)
504 {
505 strcat (str, "(");
506 addr_const_to_string (buf1, XEXP (x, 1));
507 strcat (str, buf1);
508 strcat (str, ")");
509 }
510 else
511 {
512 addr_const_to_string (buf1, XEXP (x, 1));
513 strcat (str, buf1);
514 }
515 break;
516
517 case ZERO_EXTEND:
518 case SIGN_EXTEND:
519 addr_const_to_string (buf1, XEXP (x, 0));
520 strcat (str, buf1);
521 break;
522
523 default:
524 output_operand_lossage ("invalid expression as operand");
525 }
526}
527
5f98259a
RK
528/* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
529 set. Return the header size. Just return the size if DOSIZEONLY is
0e9e1e0a 530 nonzero. */
5f98259a 531
7a0c8d71 532static int
2e1eedd6 533write_debug_header (DST_HEADER *header, const char *comment, int dosizeonly)
7a0c8d71 534{
5f98259a
RK
535 if (!dosizeonly)
536 {
537 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
538 header->dst__header_length.dst_w_length);
539
540 if (flag_verbose_asm)
541 fprintf (asm_out_file, "\t%s record length", ASM_COMMENT_START);
542 fputc ('\n', asm_out_file);
7a0c8d71 543
5f98259a
RK
544 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
545 header->dst__header_type.dst_w_type);
7a0c8d71 546
5f98259a
RK
547 if (flag_verbose_asm)
548 fprintf (asm_out_file, "\t%s record type (%s)", ASM_COMMENT_START,
549 comment);
7a0c8d71 550
5f98259a
RK
551 fputc ('\n', asm_out_file);
552 }
7a0c8d71
DR
553
554 return 4;
555}
556
5f98259a
RK
557/* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
558 set. Return the address size. Just return the size if DOSIZEONLY is
0e9e1e0a 559 nonzero. */
5f98259a 560
7a0c8d71 561static int
2e1eedd6 562write_debug_addr (char *symbol, const char *comment, int dosizeonly)
7a0c8d71 563{
5f98259a
RK
564 if (!dosizeonly)
565 {
566 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, symbol);
567 if (flag_verbose_asm)
568 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
569 fputc ('\n', asm_out_file);
570 }
7a0c8d71 571
7a0c8d71
DR
572 return PTR_SIZE;
573}
574
5f98259a
RK
575/* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
576 set. Return the data size. Just return the size if DOSIZEONLY is
0e9e1e0a 577 nonzero. */
5f98259a 578
7a0c8d71 579static int
2e1eedd6 580write_debug_data1 (unsigned int data1, const char *comment, int dosizeonly)
7a0c8d71 581{
5f98259a
RK
582 if (!dosizeonly)
583 {
584 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file, data1);
585 if (flag_verbose_asm)
586 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
587 fputc ('\n', asm_out_file);
588 }
7a0c8d71 589
7a0c8d71
DR
590 return 1;
591}
592
5f98259a
RK
593/* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
594 set. Return the data size. Just return the size if DOSIZEONLY is
0e9e1e0a 595 nonzero. */
5f98259a 596
7a0c8d71 597static int
2e1eedd6 598write_debug_data2 (unsigned int data2, const char *comment, int dosizeonly)
7a0c8d71 599{
5f98259a
RK
600 if (!dosizeonly)
601 {
602 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file, data2);
603 if (flag_verbose_asm)
604 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
605 fputc ('\n', asm_out_file);
606 }
7a0c8d71 607
7a0c8d71
DR
608 return 2;
609}
610
5f98259a 611/* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
0e9e1e0a 612 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
5f98259a 613
7a0c8d71 614static int
2e1eedd6 615write_debug_data4 (unsigned long data4, const char *comment, int dosizeonly)
7a0c8d71 616{
5f98259a
RK
617 if (!dosizeonly)
618 {
619 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file, data4);
620 if (flag_verbose_asm)
621 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
622 fputc ('\n', asm_out_file);
623 }
41077ce4 624
7a0c8d71
DR
625 return 4;
626}
627
5f98259a 628/* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
0e9e1e0a 629 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
5f98259a 630
7a0c8d71 631static int
2e1eedd6
AJ
632write_debug_data8 (unsigned long long data8, const char *comment,
633 int dosizeonly)
7a0c8d71 634{
5f98259a
RK
635 if (!dosizeonly)
636 {
637 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file, data8);
638 if (flag_verbose_asm)
639 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
640 fputc ('\n', asm_out_file);
641 }
7a0c8d71 642
7a0c8d71
DR
643 return 8;
644}
645
5f98259a
RK
646/* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
647 flag_verbose_asm is set. Return the data size. Just return the size if
0e9e1e0a 648 DOSIZEONLY is nonzero. */
5f98259a 649
7a0c8d71 650static int
2e1eedd6
AJ
651write_debug_delta4 (char *label1, char *label2, const char *comment,
652 int dosizeonly)
7a0c8d71 653{
5f98259a
RK
654 if (!dosizeonly)
655 {
656 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file, label1, label2);
657 if (flag_verbose_asm)
658 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
659 fputc ('\n', asm_out_file);
660 }
7a0c8d71 661
7a0c8d71
DR
662 return 4;
663}
664
5f98259a
RK
665/* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
666 set. Return the string length. Just return the length if DOSIZEONLY is
0e9e1e0a 667 nonzero. */
5f98259a 668
7a0c8d71 669static int
2e1eedd6 670write_debug_string (char *string, const char *comment, int dosizeonly)
7a0c8d71 671{
5f98259a
RK
672 if (!dosizeonly)
673 {
674 ASM_OUTPUT_DEBUG_STRING (asm_out_file, string);
675 if (flag_verbose_asm)
676 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
677 fputc ('\n', asm_out_file);
678 }
41077ce4 679
7a0c8d71
DR
680 return strlen (string);
681}
682
5f98259a 683/* Output a module begin header and return the header size. Just return the
0e9e1e0a 684 size if DOSIZEONLY is nonzero. */
5f98259a 685
cadf4f29 686static int
2e1eedd6 687write_modbeg (int dosizeonly)
7a0c8d71 688{
7a0c8d71
DR
689 DST_MODULE_BEGIN modbeg;
690 DST_MB_TRLR mb_trlr;
691 int i;
692 char *module_name, *m;
693 int modnamelen;
694 int prodnamelen;
695 int totsize = 0;
696
23d1aac4 697 /* Assumes primary filename has Unix syntax file spec. */
7a0c8d71
DR
698 module_name = xstrdup (basename ((char *) primary_filename));
699
700 m = strrchr (module_name, '.');
701 if (m)
702 *m = 0;
703
704 modnamelen = strlen (module_name);
705 for (i = 0; i < modnamelen; i++)
706 module_name[i] = TOUPPER (module_name[i]);
707
708 prodnamelen = strlen (module_producer);
709
710 modbeg.dst_a_modbeg_header.dst__header_length.dst_w_length
711 = DST_K_MODBEG_SIZE + modnamelen + DST_K_MB_TRLR_SIZE + prodnamelen - 1;
712 modbeg.dst_a_modbeg_header.dst__header_type.dst_w_type = DST_K_MODBEG;
713 modbeg.dst_b_modbeg_flags.dst_v_modbeg_hide = 0;
714 modbeg.dst_b_modbeg_flags.dst_v_modbeg_version = 1;
715 modbeg.dst_b_modbeg_flags.dst_v_modbeg_unused = 0;
716 modbeg.dst_b_modbeg_unused = 0;
717 modbeg.dst_l_modbeg_language = module_language;
718 modbeg.dst_w_version_major = DST_K_VERSION_MAJOR;
719 modbeg.dst_w_version_minor = DST_K_VERSION_MINOR;
720 modbeg.dst_b_modbeg_name = strlen (module_name);
721
722 mb_trlr.dst_b_compiler = strlen (module_producer);
723
724 totsize += write_debug_header (&modbeg.dst_a_modbeg_header,
725 "modbeg", dosizeonly);
726 totsize += write_debug_data1 (*((char *) &modbeg.dst_b_modbeg_flags),
727 "flags", dosizeonly);
728 totsize += write_debug_data1 (modbeg.dst_b_modbeg_unused,
729 "unused", dosizeonly);
730 totsize += write_debug_data4 (modbeg.dst_l_modbeg_language,
731 "language", dosizeonly);
732 totsize += write_debug_data2 (modbeg.dst_w_version_major,
733 "DST major version", dosizeonly);
734 totsize += write_debug_data2 (modbeg.dst_w_version_minor,
735 "DST minor version", dosizeonly);
736 totsize += write_debug_data1 (modbeg.dst_b_modbeg_name,
737 "length of module name", dosizeonly);
738 totsize += write_debug_string (module_name, "module name", dosizeonly);
739 totsize += write_debug_data1 (mb_trlr.dst_b_compiler,
740 "length of compiler name", dosizeonly);
741 totsize += write_debug_string (module_producer, "compiler name", dosizeonly);
742
743 return totsize;
744}
745
5f98259a 746/* Output a module end trailer and return the trailer size. Just return
0e9e1e0a 747 the size if DOSIZEONLY is nonzero. */
5f98259a 748
7a0c8d71 749static int
2e1eedd6 750write_modend (int dosizeonly)
7a0c8d71
DR
751{
752 DST_MODULE_END modend;
753 int totsize = 0;
754
755 modend.dst_a_modend_header.dst__header_length.dst_w_length
756 = DST_K_MODEND_SIZE - 1;
757 modend.dst_a_modend_header.dst__header_type.dst_w_type = DST_K_MODEND;
758
759 totsize += write_debug_header (&modend.dst_a_modend_header, "modend",
760 dosizeonly);
761
762 return totsize;
763}
764
5f98259a 765/* Output a routine begin header routine RTNNUM and return the header size.
0e9e1e0a 766 Just return the size if DOSIZEONLY is nonzero. */
5f98259a 767
7a0c8d71 768static int
2e1eedd6 769write_rtnbeg (int rtnnum, int dosizeonly)
7a0c8d71
DR
770{
771 char *rtnname;
1dcd444b 772 int rtnnamelen;
7a0c8d71
DR
773 char *rtnentryname;
774 int totsize = 0;
775 char label[MAX_ARTIFICIAL_LABEL_BYTES];
776 DST_ROUTINE_BEGIN rtnbeg;
777 DST_PROLOG prolog;
778
779 rtnname = func_table[rtnnum];
780 rtnnamelen = strlen (rtnname);
1dcd444b 781 rtnentryname = concat (rtnname, "..en", NULL);
7a0c8d71
DR
782
783 if (!strcmp (rtnname, "main"))
784 {
785 DST_HEADER header;
786 const char *go = "TRANSFER$BREAK$GO";
787
788 /* This command isn't documented in DSTRECORDS, so it's made to
789 look like what DEC C does */
790
791 /* header size - 1st byte + flag byte + STO_LW size
792 + string count byte + string length */
793 header.dst__header_length.dst_w_length
41077ce4 794 = DST_K_DST_HEADER_SIZE - 1 + 1 + 4 + 1 + strlen (go);
7a0c8d71
DR
795 header.dst__header_type.dst_w_type = 0x17;
796
797 totsize += write_debug_header (&header, "transfer", dosizeonly);
798
799 /* I think this is a flag byte, but I don't know what this flag means */
800 totsize += write_debug_data1 (0x1, "flags ???", dosizeonly);
801
802 /* Routine Begin PD Address */
803 totsize += write_debug_addr (rtnname, "main procedure descriptor",
804 dosizeonly);
805 totsize += write_debug_data1 (strlen (go), "length of main_name",
806 dosizeonly);
807 totsize += write_debug_string ((char *) go, "main name", dosizeonly);
808 }
809
f9da5064 810 /* The header length never includes the length byte. */
7a0c8d71
DR
811 rtnbeg.dst_a_rtnbeg_header.dst__header_length.dst_w_length
812 = DST_K_RTNBEG_SIZE + rtnnamelen - 1;
813 rtnbeg.dst_a_rtnbeg_header.dst__header_type.dst_w_type = DST_K_RTNBEG;
814 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unused = 0;
815 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unalloc = 0;
816 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_prototype = 0;
817 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_inlined = 0;
818 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_no_call = 1;
819 rtnbeg.dst_b_rtnbeg_name = rtnnamelen;
820
821 totsize += write_debug_header (&rtnbeg.dst_a_rtnbeg_header, "rtnbeg",
822 dosizeonly);
823 totsize += write_debug_data1 (*((char *) &rtnbeg.dst_b_rtnbeg_flags),
824 "flags", dosizeonly);
825
826 /* Routine Begin Address */
827 totsize += write_debug_addr (rtnentryname, "routine entry name", dosizeonly);
828
829 /* Routine Begin PD Address */
830 totsize += write_debug_addr (rtnname, "routine procedure descriptor",
831 dosizeonly);
832
833 /* Routine Begin Name */
834 totsize += write_debug_data1 (rtnbeg.dst_b_rtnbeg_name,
835 "length of routine name", dosizeonly);
836
837 totsize += write_debug_string (rtnname, "routine name", dosizeonly);
838
839 free (rtnentryname);
840
841 if (debug_info_level > DINFO_LEVEL_TERSE)
842 {
843 prolog.dst_a_prolog_header.dst__header_length.dst_w_length
844 = DST_K_PROLOG_SIZE - 1;
845 prolog.dst_a_prolog_header.dst__header_type.dst_w_type = DST_K_PROLOG;
846
847 totsize += write_debug_header (&prolog.dst_a_prolog_header, "prolog",
848 dosizeonly);
849
850 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, rtnnum);
851 totsize += write_debug_addr (label, "prolog breakpoint addr",
852 dosizeonly);
853 }
854
855 return totsize;
856}
857
5f98259a 858/* Output a routine end trailer for routine RTNNUM and return the header size.
0e9e1e0a 859 Just return the size if DOSIZEONLY is nonzero. */
5f98259a 860
7a0c8d71 861static int
2e1eedd6 862write_rtnend (int rtnnum, int dosizeonly)
7a0c8d71
DR
863{
864 DST_ROUTINE_END rtnend;
865 char label1[MAX_ARTIFICIAL_LABEL_BYTES];
866 char label2[MAX_ARTIFICIAL_LABEL_BYTES];
867 int totsize;
868
869 totsize = 0;
870
871 rtnend.dst_a_rtnend_header.dst__header_length.dst_w_length
872 = DST_K_RTNEND_SIZE - 1;
873 rtnend.dst_a_rtnend_header.dst__header_type.dst_w_type = DST_K_RTNEND;
874 rtnend.dst_b_rtnend_unused = 0;
875 rtnend.dst_l_rtnend_size = 0; /* Calculated below. */
876
877 totsize += write_debug_header (&rtnend.dst_a_rtnend_header, "rtnend",
878 dosizeonly);
879 totsize += write_debug_data1 (rtnend.dst_b_rtnend_unused, "unused",
880 dosizeonly);
881
882 ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, rtnnum);
883 ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, rtnnum);
884 totsize += write_debug_delta4 (label2, label1, "routine size", dosizeonly);
885
886 return totsize;
887}
888
889#define K_DELTA_PC(I) \
890 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
891
892#define K_SET_LINUM(I) \
893 ((I) < 256 ? DST_K_SET_LINUM_B \
894 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
895
896#define K_INCR_LINUM(I) \
897 ((I) < 256 ? DST_K_INCR_LINUM \
898 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
899
5f98259a 900/* Output the PC to line number correlations and return the size. Just return
0e9e1e0a 901 the size if DOSIZEONLY is nonzero */
5f98259a 902
7a0c8d71 903static int
2e1eedd6 904write_pclines (int dosizeonly)
7a0c8d71
DR
905{
906 unsigned i;
907 int fn;
908 int ln, lastln;
909 int linestart = 0;
910 int max_line;
911 DST_LINE_NUM_HEADER line_num;
912 DST_PCLINE_COMMANDS pcline;
913 char label[MAX_ARTIFICIAL_LABEL_BYTES];
914 char lastlabel[MAX_ARTIFICIAL_LABEL_BYTES];
915 int totsize = 0;
916 char buff[256];
917
918 max_line = file_info_table[1].max_line;
919 file_info_table[1].listing_line_start = linestart;
920 linestart = linestart + ((max_line / 100000) + 1) * 100000;
921
922 for (i = 2; i < file_info_table_in_use; i++)
923 {
924 max_line = file_info_table[i].max_line;
925 file_info_table[i].listing_line_start = linestart;
926 linestart = linestart + ((max_line / 10000) + 1) * 10000;
927 }
928
f9da5064 929 /* Set starting address to beginning of text section. */
7a0c8d71
DR
930 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 8;
931 line_num.dst_a_line_num_header.dst__header_type.dst_w_type = DST_K_LINE_NUM;
932 pcline.dst_b_pcline_command = DST_K_SET_ABS_PC;
933
934 totsize += write_debug_header (&line_num.dst_a_line_num_header,
935 "line_num", dosizeonly);
936 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
937 "line_num (SET ABS PC)", dosizeonly);
938
939 if (dosizeonly)
940 totsize += 4;
941 else
942 {
943 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, TEXT_SECTION_ASM_OP);
944 if (flag_verbose_asm)
945 fprintf (asm_out_file, "\t%s line_num", ASM_COMMENT_START);
946 fputc ('\n', asm_out_file);
947 }
948
949 fn = line_info_table[1].dst_file_num;
950 ln = (file_info_table[fn].listing_line_start
951 + line_info_table[1].dst_line_num);
952 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 4 + 4;
953 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
954
955 totsize += write_debug_header (&line_num.dst_a_line_num_header,
956 "line_num", dosizeonly);
957 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
958 "line_num (SET LINUM LONG)", dosizeonly);
959
702ada3d
DR
960 sprintf (buff, "line_num (%d)", ln ? ln - 1 : 0);
961 totsize += write_debug_data4 (ln ? ln - 1 : 0, buff, dosizeonly);
7a0c8d71
DR
962
963 lastln = ln;
964 strcpy (lastlabel, TEXT_SECTION_ASM_OP);
965 for (i = 1; i < line_info_table_in_use; i++)
966 {
967 int extrabytes;
968
969 fn = line_info_table[i].dst_file_num;
970 ln = (file_info_table[fn].listing_line_start
971 + line_info_table[i].dst_line_num);
972
973 if (ln - lastln > 1)
974 extrabytes = 5; /* NUMBYTES (ln - lastln - 1) + 1; */
975 else if (ln <= lastln)
976 extrabytes = 5; /* NUMBYTES (ln - 1) + 1; */
977 else
978 extrabytes = 0;
979
980 line_num.dst_a_line_num_header.dst__header_length.dst_w_length
981 = 8 + extrabytes;
982
983 totsize += write_debug_header
984 (&line_num.dst_a_line_num_header, "line_num", dosizeonly);
985
986 if (ln - lastln > 1)
987 {
988 int lndif = ln - lastln - 1;
989
990 /* K_INCR_LINUM (lndif); */
991 pcline.dst_b_pcline_command = DST_K_INCR_LINUM_L;
992
993 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
994 "line_num (INCR LINUM LONG)",
995 dosizeonly);
996
997 sprintf (buff, "line_num (%d)", lndif);
998 totsize += write_debug_data4 (lndif, buff, dosizeonly);
999 }
1000 else if (ln <= lastln)
1001 {
1002 /* K_SET_LINUM (ln-1); */
1003 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
1004
1005 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1006 "line_num (SET LINUM LONG)",
1007 dosizeonly);
1008
1009 sprintf (buff, "line_num (%d)", ln - 1);
1010 totsize += write_debug_data4 (ln - 1, buff, dosizeonly);
1011 }
1012
1013 pcline.dst_b_pcline_command = DST_K_DELTA_PC_L;
1014
1015 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1016 "line_num (DELTA PC LONG)", dosizeonly);
1017
1018 ASM_GENERATE_INTERNAL_LABEL (label, LINE_CODE_LABEL, i);
1019 totsize += write_debug_delta4 (label, lastlabel, "increment line_num",
1020 dosizeonly);
1021
1022 lastln = ln;
1023 strcpy (lastlabel, label);
1024 }
1025
1026 return totsize;
1027}
1028
5f98259a
RK
1029/* Output a source correlation for file FILEID using information saved in
1030 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
0e9e1e0a 1031 nonzero. */
5f98259a 1032
7a0c8d71 1033static int
2e1eedd6
AJ
1034write_srccorr (int fileid, dst_file_info_entry file_info_entry,
1035 int dosizeonly)
7a0c8d71
DR
1036{
1037 int src_command_size;
1038 int linesleft = file_info_entry.max_line;
1039 int linestart = file_info_entry.listing_line_start;
1040 int flen = file_info_entry.flen;
1041 int linestodo = 0;
1042 DST_SOURCE_CORR src_header;
1043 DST_SRC_COMMAND src_command;
1044 DST_SRC_COMMAND src_command_sf;
1045 DST_SRC_COMMAND src_command_sl;
1046 DST_SRC_COMMAND src_command_sr;
1047 DST_SRC_COMMAND src_command_dl;
1048 DST_SRC_CMDTRLR src_cmdtrlr;
1049 char buff[256];
1050 int totsize = 0;
1051
1052 if (fileid == 1)
1053 {
1054 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1055 = DST_K_SOURCE_CORR_HEADER_SIZE + 1 - 1;
1056 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1057 = DST_K_SOURCE;
1058 src_command.dst_b_src_command = DST_K_SRC_FORMFEED;
1059
1060 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1061 "source corr", dosizeonly);
1062
1063 totsize += write_debug_data1 (src_command.dst_b_src_command,
1064 "source_corr (SRC FORMFEED)",
1065 dosizeonly);
1066 }
1067
1068 src_command_size
1069 = DST_K_SRC_COMMAND_SIZE + flen + DST_K_SRC_CMDTRLR_SIZE;
1070 src_command.dst_b_src_command = DST_K_SRC_DECLFILE;
1071 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length
1072 = src_command_size - 2;
1073 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags = 0;
1074 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid
1075 = fileid;
1076 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt
1077 = file_info_entry.cdt;
1078 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk
1079 = file_info_entry.ebk;
1080 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb
1081 = file_info_entry.ffb;
1082 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo
1083 = file_info_entry.rfo;
1084 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename
1085 = file_info_entry.flen;
1086
1087 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1088 = DST_K_SOURCE_CORR_HEADER_SIZE + src_command_size - 1;
1089 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1090 = DST_K_SOURCE;
1091
1092 src_cmdtrlr.dst_b_src_df_libmodname = 0;
41077ce4 1093
7a0c8d71
DR
1094 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1095 "source corr", dosizeonly);
1096 totsize += write_debug_data1 (src_command.dst_b_src_command,
1097 "source_corr (DECL SRC FILE)", dosizeonly);
1098 totsize += write_debug_data1
1099 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length,
1100 "source_corr (length)", dosizeonly);
1101
1102 totsize += write_debug_data1
1103 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags,
1104 "source_corr (flags)", dosizeonly);
1105
1106 totsize += write_debug_data2
1107 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid,
1108 "source_corr (fileid)", dosizeonly);
1109
1110 totsize += write_debug_data8
1111 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt,
1112 "source_corr (creation date)", dosizeonly);
41077ce4 1113
7a0c8d71
DR
1114 totsize += write_debug_data4
1115 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk,
1116 "source_corr (EOF block number)", dosizeonly);
1117
1118 totsize += write_debug_data2
1119 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb,
1120 "source_corr (first free byte)", dosizeonly);
1121
1122 totsize += write_debug_data1
1123 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo,
1124 "source_corr (record and file organization)", dosizeonly);
1125
1126 totsize += write_debug_data1
1127 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename,
1128 "source_corr (filename length)", dosizeonly);
1129
1130 totsize += write_debug_string (file_info_entry.file_name,
1131 "source file name", dosizeonly);
1132 totsize += write_debug_data1 (src_cmdtrlr.dst_b_src_df_libmodname,
1133 "source_corr (libmodname)", dosizeonly);
1134
1135 src_command_sf.dst_b_src_command = DST_K_SRC_SETFILE;
1136 src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword = fileid;
1137
1138 src_command_sr.dst_b_src_command = DST_K_SRC_SETREC_W;
1139 src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword = 1;
1140
1141 src_command_sl.dst_b_src_command = DST_K_SRC_SETLNUM_L;
1142 src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong = linestart + 1;
1143
1144 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1145
1146 if (linesleft > 65534)
1147 linesleft = linesleft - 65534, linestodo = 65534;
1148 else
1149 linestodo = linesleft, linesleft = 0;
1150
1151 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1152
1153 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1154 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 + 3 + 5 + 3 - 1;
1155 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1156 = DST_K_SOURCE;
1157
702ada3d
DR
1158 if (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword)
1159 {
1160 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1161 "source corr", dosizeonly);
7a0c8d71 1162
702ada3d
DR
1163 totsize += write_debug_data1 (src_command_sf.dst_b_src_command,
1164 "source_corr (src setfile)", dosizeonly);
7a0c8d71 1165
702ada3d
DR
1166 totsize += write_debug_data2
1167 (src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword,
1168 "source_corr (fileid)", dosizeonly);
7a0c8d71 1169
702ada3d
DR
1170 totsize += write_debug_data1 (src_command_sr.dst_b_src_command,
1171 "source_corr (setrec)", dosizeonly);
7a0c8d71 1172
702ada3d
DR
1173 totsize += write_debug_data2
1174 (src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword,
1175 "source_corr (recnum)", dosizeonly);
7a0c8d71 1176
702ada3d
DR
1177 totsize += write_debug_data1 (src_command_sl.dst_b_src_command,
1178 "source_corr (setlnum)", dosizeonly);
7a0c8d71 1179
702ada3d
DR
1180 totsize += write_debug_data4
1181 (src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong,
1182 "source_corr (linenum)", dosizeonly);
7a0c8d71 1183
7a0c8d71
DR
1184 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1185 "source_corr (deflines)", dosizeonly);
702ada3d 1186
7a0c8d71
DR
1187 sprintf (buff, "source_corr (%d)",
1188 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1189 totsize += write_debug_data2
1190 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1191 buff, dosizeonly);
702ada3d
DR
1192
1193 while (linesleft > 0)
1194 {
1195 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1196 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 - 1;
1197 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1198 = DST_K_SOURCE;
1199 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1200
1201 if (linesleft > 65534)
1202 linesleft = linesleft - 65534, linestodo = 65534;
1203 else
1204 linestodo = linesleft, linesleft = 0;
1205
1206 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1207
1208 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1209 "source corr", dosizeonly);
1210 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1211 "source_corr (deflines)", dosizeonly);
1212 sprintf (buff, "source_corr (%d)",
1213 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1214 totsize += write_debug_data2
1215 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1216 buff, dosizeonly);
1217 }
7a0c8d71
DR
1218 }
1219
1220 return totsize;
1221}
1222
5f98259a 1223/* Output all the source correlation entries and return the size. Just return
0e9e1e0a 1224 the size if DOSIZEONLY is nonzero. */
5f98259a 1225
7a0c8d71 1226static int
2e1eedd6 1227write_srccorrs (int dosizeonly)
7a0c8d71
DR
1228{
1229 unsigned int i;
1230 int totsize = 0;
1231
1232 for (i = 1; i < file_info_table_in_use; i++)
1233 totsize += write_srccorr (i, file_info_table[i], dosizeonly);
1234
1235 return totsize;
41077ce4 1236}
7a0c8d71
DR
1237\f
1238/* Output a marker (i.e. a label) for the beginning of a function, before
1239 the prologue. */
1240
1241static void
2e1eedd6 1242vmsdbgout_begin_prologue (unsigned int line, const char *file)
7a0c8d71
DR
1243{
1244 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1245
1246 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1247 (*dwarf2_debug_hooks.begin_prologue) (line, file);
1248
1249 if (debug_info_level > DINFO_LEVEL_NONE)
1250 {
7a0c8d71 1251 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
df696a75 1252 current_function_funcdef_no);
7a0c8d71
DR
1253 ASM_OUTPUT_LABEL (asm_out_file, label);
1254 }
1255}
1256
1257/* Output a marker (i.e. a label) for the beginning of a function, after
1258 the prologue. */
1259
702ada3d 1260static void
2e1eedd6 1261vmsdbgout_end_prologue (unsigned int line, const char *file)
7a0c8d71
DR
1262{
1263 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1264
702ada3d
DR
1265 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1266 (*dwarf2_debug_hooks.end_prologue) (line, file);
1267
7a0c8d71
DR
1268 if (debug_info_level > DINFO_LEVEL_TERSE)
1269 {
1270 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL,
df696a75 1271 current_function_funcdef_no);
7a0c8d71 1272 ASM_OUTPUT_LABEL (asm_out_file, label);
702ada3d 1273
f9da5064 1274 /* VMS PCA expects every PC range to correlate to some line and file. */
702ada3d 1275 vmsdbgout_source_line (line, file);
7a0c8d71
DR
1276 }
1277}
1278
702ada3d
DR
1279/* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1280
1281static void
2e1eedd6 1282vmsdbgout_end_function (unsigned int line)
702ada3d
DR
1283{
1284 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1285 (*dwarf2_debug_hooks.end_function) (line);
1286}
1287
7a0c8d71
DR
1288/* Output a marker (i.e. a label) for the absolute end of the generated code
1289 for a function definition. This gets called *after* the epilogue code has
1290 been generated. */
1291
1292static void
2e1eedd6 1293vmsdbgout_end_epilogue (unsigned int line, const char *file)
7a0c8d71
DR
1294{
1295 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1296
1297 if (write_symbols == VMS_AND_DWARF2_DEBUG)
702ada3d 1298 (*dwarf2_debug_hooks.end_epilogue) (line, file);
7a0c8d71
DR
1299
1300 if (debug_info_level > DINFO_LEVEL_NONE)
1301 {
1302 /* Output a label to mark the endpoint of the code generated for this
3ef42a0c 1303 function. */
7a0c8d71 1304 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
df696a75 1305 current_function_funcdef_no);
7a0c8d71 1306 ASM_OUTPUT_LABEL (asm_out_file, label);
702ada3d 1307
f9da5064 1308 /* VMS PCA expects every PC range to correlate to some line and file. */
702ada3d 1309 vmsdbgout_source_line (line, file);
7a0c8d71
DR
1310 }
1311}
1312
1313/* Output a marker (i.e. a label) for the beginning of the generated code for
1314 a lexical block. */
1315
1316static void
2e1eedd6 1317vmsdbgout_begin_block (register unsigned line, register unsigned blocknum)
7a0c8d71
DR
1318{
1319 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1320 (*dwarf2_debug_hooks.begin_block) (line, blocknum);
1321
1322 if (debug_info_level > DINFO_LEVEL_TERSE)
4977bab6 1323 (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
7a0c8d71
DR
1324}
1325
1326/* Output a marker (i.e. a label) for the end of the generated code for a
1327 lexical block. */
1328
1329static void
2e1eedd6 1330vmsdbgout_end_block (register unsigned line, register unsigned blocknum)
7a0c8d71
DR
1331{
1332 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1333 (*dwarf2_debug_hooks.end_block) (line, blocknum);
1334
1335 if (debug_info_level > DINFO_LEVEL_TERSE)
4977bab6 1336 (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_END_LABEL, blocknum);
7a0c8d71
DR
1337}
1338
5f98259a
RK
1339/* Not implemented in VMS Debug. */
1340
7a0c8d71 1341static bool
2e1eedd6 1342vmsdbgout_ignore_block (tree block)
7a0c8d71
DR
1343{
1344 bool retval = 0;
1345
1346 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1347 retval = (*dwarf2_debug_hooks.ignore_block) (block);
1348
1349 return retval;
1350}
1351
5f98259a
RK
1352/* Add an entry for function DECL into the func_table. */
1353
7a0c8d71 1354static void
2e1eedd6 1355vmsdbgout_begin_function (tree decl)
7a0c8d71
DR
1356{
1357 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1358
1359 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1360 (*dwarf2_debug_hooks.begin_function) (decl);
1361
1362 if (func_table_in_use == func_table_allocated)
1363 {
1364 func_table_allocated += FUNC_TABLE_INCREMENT;
703ad42b
KG
1365 func_table = xrealloc (func_table,
1366 func_table_allocated * sizeof (char *));
7a0c8d71
DR
1367 }
1368
1369 /* Add the new entry to the end of the function name table. */
1370 func_table[func_table_in_use++] = xstrdup (name);
1371}
1372
1373static char fullname_buff [4096];
1374
5f98259a 1375/* Return the full file specification for FILENAME. The specification must be
23d1aac4 1376 in VMS syntax in order to be processed by VMS Debug. */
5f98259a 1377
7a0c8d71 1378static char *
2e1eedd6 1379full_name (const char *filename)
7a0c8d71
DR
1380{
1381#ifdef VMS
1382 FILE *fp = fopen (filename, "r");
1383
1384 fgetname (fp, fullname_buff, 1);
1385 fclose (fp);
1386#else
1387 getcwd (fullname_buff, sizeof (fullname_buff));
1388
1389 strcat (fullname_buff, "/");
1390 strcat (fullname_buff, filename);
1391
1392 /* ??? Insert hairy code here to translate Unix style file specification
1393 to VMS style. */
1394#endif
1395
1396 return fullname_buff;
1397}
1398
1399/* Lookup a filename (in the list of filenames that we know about here in
1400 vmsdbgout.c) and return its "index". The index of each (known) filename is
1401 just a unique number which is associated with only that one filename. We
5f98259a
RK
1402 need such numbers for the sake of generating labels and references
1403 to those files numbers. If the filename given as an argument is not
7a0c8d71
DR
1404 found in our current list, add it to the list and assign it the next
1405 available unique index number. In order to speed up searches, we remember
1406 the index of the filename was looked up last. This handles the majority of
1407 all searches. */
1408
1409static unsigned int
2e1eedd6 1410lookup_filename (const char *file_name)
7a0c8d71
DR
1411{
1412 static unsigned int last_file_lookup_index = 0;
1413 register char *fn;
1414 register unsigned i;
1415 char *fnam;
1416 long long cdt;
1417 long ebk;
1418 short ffb;
1419 char rfo;
1420 char flen;
1421 struct stat statbuf;
1422
1423 if (stat (file_name, &statbuf) == 0)
1424 {
6f1fd286 1425 long gmtoff;
7a0c8d71 1426#ifdef VMS
6f1fd286
DR
1427 struct tm *ts;
1428
f9da5064 1429 /* Adjust for GMT. */
6f1fd286
DR
1430 ts = (struct tm *) localtime (&statbuf.st_ctime);
1431 gmtoff = ts->tm_gmtoff;
1432
f9da5064 1433 /* VMS has multiple file format types. */
7a0c8d71
DR
1434 rfo = statbuf.st_fab_rfm;
1435#else
6f1fd286
DR
1436 /* Is GMT adjustment an issue with a cross-compiler? */
1437 gmtoff = 0;
1438
f9da5064 1439 /* Assume stream LF type file. */
7a0c8d71
DR
1440 rfo = 2;
1441#endif
6f1fd286
DR
1442 cdt = 10000000 * (statbuf.st_ctime + gmtoff + vms_epoch_offset);
1443 ebk = statbuf.st_size / 512 + 1;
1444 ffb = statbuf.st_size - ((statbuf.st_size / 512) * 512);
7a0c8d71
DR
1445 fnam = full_name (file_name);
1446 flen = strlen (fnam);
1447 }
1448 else
1449 {
1450 cdt = 0;
1451 ebk = 0;
1452 ffb = 0;
1453 rfo = 0;
c6bc7526 1454 fnam = (char *) "";
7a0c8d71
DR
1455 flen = 0;
1456 }
1457
1458 /* Check to see if the file name that was searched on the previous call
1459 matches this file name. If so, return the index. */
1460 if (last_file_lookup_index != 0)
1461 {
1462 fn = file_info_table[last_file_lookup_index].file_name;
1463 if (strcmp (fnam, fn) == 0)
1464 return last_file_lookup_index;
1465 }
1466
1467 /* Didn't match the previous lookup, search the table */
1468 for (i = 1; i < file_info_table_in_use; ++i)
1469 {
1470 fn = file_info_table[i].file_name;
1471 if (strcmp (fnam, fn) == 0)
1472 {
1473 last_file_lookup_index = i;
1474 return i;
1475 }
1476 }
1477
41077ce4 1478 /* Prepare to add a new table entry by making sure there is enough space in
7a0c8d71
DR
1479 the table to do so. If not, expand the current table. */
1480 if (file_info_table_in_use == file_info_table_allocated)
1481 {
1482
1483 file_info_table_allocated += FILE_TABLE_INCREMENT;
703ad42b
KG
1484 file_info_table = xrealloc (file_info_table,
1485 (file_info_table_allocated
1486 * sizeof (dst_file_info_entry)));
7a0c8d71
DR
1487 }
1488
1489 /* Add the new entry to the end of the filename table. */
1490 file_info_table[file_info_table_in_use].file_name = xstrdup (fnam);
1491 file_info_table[file_info_table_in_use].max_line = 0;
1492 file_info_table[file_info_table_in_use].cdt = cdt;
1493 file_info_table[file_info_table_in_use].ebk = ebk;
1494 file_info_table[file_info_table_in_use].ffb = ffb;
1495 file_info_table[file_info_table_in_use].rfo = rfo;
1496 file_info_table[file_info_table_in_use].flen = flen;
1497
1498 last_file_lookup_index = file_info_table_in_use++;
1499 return last_file_lookup_index;
1500}
1501
1502/* Output a label to mark the beginning of a source code line entry
1503 and record information relating to this source line, in
1504 'line_info_table' for later output of the .debug_line section. */
1505
1506static void
2e1eedd6 1507vmsdbgout_source_line (register unsigned line, register const char *filename)
7a0c8d71
DR
1508{
1509 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1510 (*dwarf2_debug_hooks.source_line) (line, filename);
1511
1512 if (debug_info_level >= DINFO_LEVEL_TERSE)
1513 {
1514 dst_line_info_ref line_info;
1515
4977bab6 1516 (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
7a0c8d71
DR
1517 line_info_table_in_use);
1518
1519 /* Expand the line info table if necessary. */
1520 if (line_info_table_in_use == line_info_table_allocated)
1521 {
1522 line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
703ad42b
KG
1523 line_info_table = xrealloc (line_info_table,
1524 (line_info_table_allocated
1525 * sizeof (dst_line_info_entry)));
41077ce4 1526 }
7a0c8d71
DR
1527
1528 /* Add the new entry at the end of the line_info_table. */
1529 line_info = &line_info_table[line_info_table_in_use++];
1530 line_info->dst_file_num = lookup_filename (filename);
1531 line_info->dst_line_num = line;
1532 if (line > file_info_table[line_info->dst_file_num].max_line)
1533 file_info_table[line_info->dst_file_num].max_line = line;
1534 }
1535}
1536
1537/* Record the beginning of a new source file, for later output.
1538 At present, unimplemented. */
1539
1540static void
2e1eedd6 1541vmsdbgout_start_source_file (unsigned int lineno, const char *filename)
7a0c8d71
DR
1542{
1543 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1544 (*dwarf2_debug_hooks.start_source_file) (lineno, filename);
1545}
1546
1547/* Record the end of a source file, for later output.
1548 At present, unimplemented. */
1549
1550static void
2e1eedd6 1551vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
7a0c8d71
DR
1552{
1553 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1554 (*dwarf2_debug_hooks.end_source_file) (lineno);
1555}
1556
1557/* Set up for Debug output at the start of compilation. */
1558
1559static void
2e1eedd6 1560vmsdbgout_init (const char *main_input_filename)
7a0c8d71
DR
1561{
1562 const char *language_string = lang_hooks.name;
1563
1564 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1565 (*dwarf2_debug_hooks.init) (main_input_filename);
1566
1567 if (debug_info_level == DINFO_LEVEL_NONE)
1568 return;
1569
1570 /* Remember the name of the primary input file. */
1571 primary_filename = main_input_filename;
1572
1573 /* Allocate the initial hunk of the file_info_table. */
1574 file_info_table
703ad42b 1575 = xcalloc (FILE_TABLE_INCREMENT, sizeof (dst_file_info_entry));
7a0c8d71
DR
1576 file_info_table_allocated = FILE_TABLE_INCREMENT;
1577
1578 /* Skip the first entry - file numbers begin at 1 */
1579 file_info_table_in_use = 1;
1580
703ad42b 1581 func_table = xcalloc (FUNC_TABLE_INCREMENT, sizeof (char *));
7a0c8d71
DR
1582 func_table_allocated = FUNC_TABLE_INCREMENT;
1583 func_table_in_use = 1;
1584
1585 /* Allocate the initial hunk of the line_info_table. */
1586 line_info_table
703ad42b 1587 = xcalloc (LINE_INFO_TABLE_INCREMENT, sizeof (dst_line_info_entry));
7a0c8d71
DR
1588 line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
1589 /* zero-th entry is allocated, but unused */
1590 line_info_table_in_use = 1;
1591
1592 lookup_filename (primary_filename);
1593
1594 if (!strcmp (language_string, "GNU C"))
1595 module_language = DST_K_C;
1596 else if (!strcmp (language_string, "GNU C++"))
1597 module_language = DST_K_CXX;
1598 else if (!strcmp (language_string, "GNU Ada"))
1599 module_language = DST_K_ADA;
1600 else if (!strcmp (language_string, "GNU F77"))
1601 module_language = DST_K_FORTRAN;
1602 else
1603 module_language = DST_K_UNKNOWN;
1604
1dcd444b 1605 module_producer = concat (language_string, " ", version_string, NULL);
7a0c8d71
DR
1606
1607 ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
1608
1609}
1610
5f98259a
RK
1611/* Not implemented in VMS Debug. */
1612
7a0c8d71 1613static void
2e1eedd6 1614vmsdbgout_define (unsigned int lineno, const char *buffer)
7a0c8d71
DR
1615{
1616 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1617 (*dwarf2_debug_hooks.define) (lineno, buffer);
1618}
1619
5f98259a
RK
1620/* Not implemented in VMS Debug. */
1621
7a0c8d71 1622static void
2e1eedd6 1623vmsdbgout_undef (unsigned int lineno, const char *buffer)
7a0c8d71
DR
1624{
1625 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1626 (*dwarf2_debug_hooks.undef) (lineno, buffer);
1627}
1628
5f98259a
RK
1629/* Not implemented in VMS Debug. */
1630
7a0c8d71 1631static void
2e1eedd6 1632vmsdbgout_decl (tree decl)
7a0c8d71
DR
1633{
1634 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1635 (*dwarf2_debug_hooks.function_decl) (decl);
1636}
1637
5f98259a
RK
1638/* Not implemented in VMS Debug. */
1639
7a0c8d71 1640static void
2e1eedd6 1641vmsdbgout_global_decl (tree decl)
7a0c8d71
DR
1642{
1643 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1644 (*dwarf2_debug_hooks.global_decl) (decl);
1645}
1646
5f98259a
RK
1647/* Not implemented in VMS Debug. */
1648
7a0c8d71 1649static void
2e1eedd6 1650vmsdbgout_abstract_function (tree decl)
7a0c8d71
DR
1651{
1652 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1653 (*dwarf2_debug_hooks.outlining_inline_function) (decl);
1654}
1655
5f98259a
RK
1656/* Output stuff that Debug requires at the end of every file and generate the
1657 VMS Debug debugging info. */
7a0c8d71
DR
1658
1659static void
2e1eedd6 1660vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED)
7a0c8d71
DR
1661{
1662 unsigned int i;
1663 int totsize;
1664
1665 if (write_symbols == VMS_AND_DWARF2_DEBUG)
64c1652c 1666 (*dwarf2_debug_hooks.finish) (main_input_filename);
7a0c8d71
DR
1667
1668 if (debug_info_level == DINFO_LEVEL_NONE)
1669 return;
1670
1671 /* Output a terminator label for the .text section. */
1672 text_section ();
4977bab6 1673 (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
7a0c8d71
DR
1674
1675 /* Output debugging information.
1676 Warning! Do not change the name of the .vmsdebug section without
23d1aac4 1677 changing it in the assembler also. */
7a0c8d71
DR
1678 named_section (NULL_TREE, ".vmsdebug", 0);
1679 ASM_OUTPUT_ALIGN (asm_out_file, 0);
1680
1681 totsize = write_modbeg (1);
1682 for (i = 1; i < func_table_in_use; i++)
1683 {
1684 totsize += write_rtnbeg (i, 1);
1685 totsize += write_rtnend (i, 1);
1686 }
1687 totsize += write_pclines (1);
1688
1689 write_modbeg (0);
1690 for (i = 1; i < func_table_in_use; i++)
1691 {
1692 write_rtnbeg (i, 0);
1693 write_rtnend (i, 0);
1694 }
1695 write_pclines (0);
1696
1697 if (debug_info_level > DINFO_LEVEL_TERSE)
1698 {
1699 totsize = write_srccorrs (1);
1700 write_srccorrs (0);
1701 }
1702
1703 totsize = write_modend (1);
1704 write_modend (0);
1705}
1706#endif /* VMS_DEBUGGING_INFO */