OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [vmsdbgout.c] - Blame information for rev 298

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.