OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

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

powered by: WebSVN 2.1.0

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