1/* vms.c -- Write out a VAX/VMS object file
2   Copyright 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001,
3   2002, 2003
4   Free Software Foundation, Inc.
5
6   This file is part of GAS, the GNU Assembler.
7
8   GAS is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   GAS is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with GAS; see the file COPYING.  If not, write to the Free
20   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21   02111-1307, USA.  */
22
23/* Written by David L. Kashtan */
24/* Modified by Eric Youngdale to write VMS debug records for program
25   variables */
26
27/* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h).  */
28#define WANT_VMS_OBJ_DEFS
29
30#include "as.h"
31#include "config.h"
32#include "safe-ctype.h"
33#include "subsegs.h"
34#include "obstack.h"
35#include <fcntl.h>
36
37/* What we do if there is a goof.  */
38#define error as_fatal
39
40#ifdef VMS			/* These are of no use if we are cross assembling.  */
41#include <fab.h>		/* Define File Access Block.  */
42#include <nam.h>		/* Define NAM Block.  */
43#include <xab.h>		/* Define XAB - all different types.  */
44extern int sys$open(), sys$close(), sys$asctim();
45#endif
46
47/* Version string of the compiler that produced the code we are
48   assembling.  (And this assembler, if we do not have compiler info).  */
49char *compiler_version_string;
50
51extern int flag_hash_long_names;	/* -+ */
52extern int flag_one;			/* -1; compatibility with gcc 1.x */
53extern int flag_show_after_trunc;	/* -H */
54extern int flag_no_hash_mixed_case;	/* -h NUM */
55
56/* Flag that determines how we map names.  This takes several values, and
57   is set with the -h switch.  A value of zero implies names should be
58   upper case, and the presence of the -h switch inhibits the case hack.
59   No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
60   A value of 2 (set with -h2) implies names should be
61   all lower case, with no case hack.  A value of 3 (set with -h3) implies
62   that case should be preserved.  */
63
64/* If the -+ switch is given, then the hash is appended to any name that is
65   longer than 31 characters, regardless of the setting of the -h switch.  */
66
67char vms_name_mapping = 0;
68
69static symbolS *Entry_Point_Symbol = 0;	/* Pointer to "_main" */
70
71/* We augment the "gas" symbol structure with this.  */
72
73struct VMS_Symbol
74{
75  struct VMS_Symbol *Next;
76  symbolS *Symbol;
77  int Size;
78  int Psect_Index;
79  int Psect_Offset;
80};
81
82struct VMS_Symbol *VMS_Symbols = 0;
83struct VMS_Symbol *Ctors_Symbols = 0;
84struct VMS_Symbol *Dtors_Symbols = 0;
85
86/* We need this to keep track of the various input files, so that we can
87   give the debugger the correct source line.  */
88
89struct input_file
90{
91  struct input_file *next;
92  struct input_file *same_file_fpnt;
93  int file_number;
94  int max_line;
95  int min_line;
96  int offset;
97  char flag;
98  char *name;
99  symbolS *spnt;
100};
101
102static struct input_file *file_root = (struct input_file *) NULL;
103
104/* Styles of PSECTS (program sections) that we generate; just shorthand
105   to avoid lists of section attributes.  Used by VMS_Psect_Spec().  */
106enum ps_type
107{
108  ps_TEXT, ps_DATA, ps_COMMON, ps_CONST, ps_CTORS, ps_DTORS
109};
110
111/* This enum is used to keep track of the various types of variables that
112   may be present.  */
113
114enum advanced_type
115{
116  BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN
117};
118
119/* This structure contains the information from the stabs directives, and the
120   information is filled in by VMS_typedef_parse.  Everything that is needed
121   to generate the debugging record for a given symbol is present here.
122   This could be done more efficiently, using nested struct/unions, but for
123   now I am happy that it works.  */
124
125struct VMS_DBG_Symbol
126{
127  struct VMS_DBG_Symbol *next;
128  /* Description of what this is.  */
129  enum advanced_type advanced;
130  /* This record is for this type.  */
131  int dbx_type;
132  /* For advanced types this is the type referred to.  I.e., the type
133     a pointer points to, or the type of object that makes up an
134     array.  */
135  int type2;
136  /* Use this type when generating a variable def.  */
137  int VMS_type;
138  /* Used for arrays - this will be present for all.  */
139  int index_min;
140  /* Entries, but will be meaningless for non-arrays.  */
141  int index_max;
142  /* Size in bytes of the data type.  For an array, this is the size
143     of one element in the array.  */
144  int data_size;
145  /* Number of the structure/union/enum - used for ref.  */
146  int struc_numb;
147};
148
149#define SYMTYPLST_SIZE (1<<4)	/* 16; Must be power of two.  */
150#define SYMTYP_HASH(x) ((unsigned) (x) & (SYMTYPLST_SIZE - 1))
151
152struct VMS_DBG_Symbol *VMS_Symbol_type_list[SYMTYPLST_SIZE];
153
154/* We need this structure to keep track of forward references to
155   struct/union/enum that have not been defined yet.  When they are
156   ultimately defined, then we can go back and generate the TIR
157   commands to make a back reference.  */
158
159struct forward_ref
160{
161  struct forward_ref *next;
162  int dbx_type;
163  int struc_numb;
164  char resolved;
165};
166
167struct forward_ref *f_ref_root = (struct forward_ref *) NULL;
168
169/* This routine is used to compare the names of certain types to various
170   fixed types that are known by the debugger.  */
171
172#define type_check(X)  !strcmp (symbol_name, X)
173
174/* This variable is used to keep track of the name of the symbol we are
175   working on while we are parsing the stabs directives.  */
176
177static const char *symbol_name;
178
179/* We use this counter to assign numbers to all of the structures, unions
180   and enums that we define.  When we actually declare a variable to the
181   debugger, we can simply do it by number, rather than describing the
182   whole thing each time.  */
183
184static int structure_count = 0;
185
186/* This variable is used to indicate that we are making the last attempt to
187   parse the stabs, and that we should define as much as we can, and ignore
188   the rest.  */
189
190static int final_pass;
191
192/* This variable is used to keep track of the current structure number
193   for a given variable.  If this is < 0, that means that the structure
194   has not yet been defined to the debugger.  This is still cool, since
195   the VMS object language has ways of fixing things up after the fact,
196   so we just make a note of this, and generate fixups at the end.  */
197
198static int struct_number;
199
200/* This is used to distinguish between D_float and G_float for telling
201   the debugger about doubles.  gcc outputs the same .stabs regardless
202   of whether -mg is used to select alternate doubles.  */
203
204static int vax_g_doubles = 0;
205
206/* Local symbol references (used to handle N_ABS symbols; gcc does not
207   generate those, but they're possible with hand-coded assembler input)
208   are always made relative to some particular environment.  If the current
209   input has any such symbols, then we expect this to get incremented
210   exactly once and end up having all of them be in environment #0.  */
211
212static int Current_Environment = -1;
213
214/* Every object file must specify an module name, which is also used by
215   traceback records.  Set in Write_VMS_MHD_Records().  */
216
217static char Module_Name[255+1];
218
219/* Variable descriptors are used tell the debugger the data types of certain
220   more complicated variables (basically anything involving a structure,
221   union, enum, array or pointer).  Some non-pointer variables of the
222   basic types that the debugger knows about do not require a variable
223   descriptor.
224
225   Since it is impossible to have a variable descriptor longer than 128
226   bytes by virtue of the way that the VMS object language is set up,
227   it makes not sense to make the arrays any longer than this, or worrying
228   about dynamic sizing of the array.
229
230   These are the arrays and counters that we use to build a variable
231   descriptor.  */
232
233#define MAX_DEBUG_RECORD 128
234static char Local[MAX_DEBUG_RECORD];	/* Buffer for variable descriptor.  */
235static char Asuffix[MAX_DEBUG_RECORD];	/* Buffer for array descriptor.  */
236static int Lpnt;		/* Index into Local.  */
237static int Apoint;		/* Index into Asuffix.  */
238static char overflow;		/* Flag to indicate we have written too much.  */
239static int total_len;		/* Used to calculate the total length of
240				   variable descriptor plus array descriptor
241				   - used for len byte.  */
242
243/* Flag if we have told user about finding global constants in the text
244   section.  */
245static int gave_compiler_message = 0;
246
247/* Global data (Object records limited to 512 bytes by VAX-11 "C" runtime).  */
248
249static int VMS_Object_File_FD;		/* File Descriptor for object file.  */
250static char Object_Record_Buffer[512];	/* Buffer for object file records.  */
251static size_t Object_Record_Offset;	/* Offset to end of data.  */
252static int Current_Object_Record_Type;	/* Type of record in above.  */
253
254/* Macros for moving data around.  Must work on big-endian systems.  */
255
256#ifdef VMS  /* These are more efficient for VMS->VMS systems.  */
257#define COPY_LONG(dest,val)	( *(long *) (dest) = (val) )
258#define COPY_SHORT(dest,val)	( *(short *) (dest) = (val) )
259#else
260#define COPY_LONG(dest,val)	md_number_to_chars ((dest), (val), 4)
261#define COPY_SHORT(dest,val)	md_number_to_chars ((dest), (val), 2)
262#endif
263
264/* Macros for placing data into the object record buffer.  */
265
266#define PUT_LONG(val) \
267	( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \
268	  Object_Record_Offset += 4 )
269
270#define PUT_SHORT(val) \
271	( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \
272	  Object_Record_Offset += 2 )
273
274#define PUT_CHAR(val) (Object_Record_Buffer[Object_Record_Offset++] = (val))
275
276#define PUT_COUNTED_STRING(cp)			\
277  do 						\
278    { 						\
279      const char *p = (cp);			\
280      						\
281      PUT_CHAR ((char) strlen (p)); 		\
282      while (*p)				\
283	PUT_CHAR (*p++);			\
284    }						\
285  while (0)
286
287/* Macro for determining if a Name has psect attributes attached
288   to it.   */
289
290#define PSECT_ATTRIBUTES_STRING		"$$PsectAttributes_"
291#define PSECT_ATTRIBUTES_STRING_LENGTH	18
292
293#define HAS_PSECT_ATTRIBUTES(Name) \
294		(strncmp ((*Name == '_' ? Name + 1 : Name), \
295			  PSECT_ATTRIBUTES_STRING, \
296			  PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
297
298
299 /* in: segT   out: N_TYPE bits */
300const short seg_N_TYPE[] =
301{
302  N_ABS,
303  N_TEXT,
304  N_DATA,
305  N_BSS,
306  N_UNDF,			/* unknown */
307  N_UNDF,			/* error */
308  N_UNDF,			/* expression */
309  N_UNDF,			/* debug */
310  N_UNDF,			/* ntv */
311  N_UNDF,			/* ptv */
312  N_REGISTER,			/* register */
313};
314
315const segT N_TYPE_seg[N_TYPE + 2] =
316{				/* N_TYPE == 0x1E = 32-2 */
317  SEG_UNKNOWN,			/* N_UNDF == 0 */
318  SEG_GOOF,
319  SEG_ABSOLUTE,			/* N_ABS == 2 */
320  SEG_GOOF,
321  SEG_TEXT,			/* N_TEXT == 4 */
322  SEG_GOOF,
323  SEG_DATA,			/* N_DATA == 6 */
324  SEG_GOOF,
325  SEG_BSS,			/* N_BSS == 8 */
326  SEG_GOOF,
327  SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
328  SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
329  SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
330  SEG_REGISTER,			/* dummy N_REGISTER for regs = 30 */
331  SEG_GOOF,
332};
333
334
335/* The following code defines the special types of pseudo-ops that we
336   use with VMS.  */
337
338unsigned char const_flag = IN_DEFAULT_SECTION;
339
340static void
341s_const (int arg)
342{
343  /* Since we don't need `arg', use it as our scratch variable so that
344     we won't get any "not used" warnings about it.  */
345  arg = get_absolute_expression ();
346  subseg_set (SEG_DATA, (subsegT) arg);
347  const_flag = 1;
348  demand_empty_rest_of_line ();
349}
350
351const pseudo_typeS obj_pseudo_table[] =
352{
353  {"const", s_const, 0},
354  {0, 0, 0},
355};				/* obj_pseudo_table */
356
357/* Routine to perform RESOLVE_SYMBOL_REDEFINITION().  */
358
359int
360vms_resolve_symbol_redef (symbolS *sym)
361{
362  /* If the new symbol is .comm AND it has a size of zero,
363     we ignore it (i.e. the old symbol overrides it).  */
364  if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)
365      && frag_now_fix () == 0)
366    {
367      as_warn (_("compiler emitted zero-size common symbol `%s' already defined"),
368	       S_GET_NAME (sym));
369      return 1;
370    }
371  /* If the old symbol is .comm and it has a size of zero,
372     we override it with the new symbol value.  */
373  if (S_IS_EXTERNAL (sym) && S_IS_DEFINED (sym) && S_GET_VALUE (sym) == 0)
374    {
375      as_warn (_("compiler redefined zero-size common symbol `%s'"),
376	       S_GET_NAME (sym));
377      sym->sy_frag  = frag_now;
378      S_SET_OTHER (sym, const_flag);
379      S_SET_VALUE (sym, frag_now_fix ());
380      /* Keep N_EXT bit.  */
381      sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg);
382      return 1;
383    }
384
385  return 0;
386}
387
388/* `tc_frob_label' handler for colon(symbols.c), used to examine the
389   dummy label(s) gcc inserts at the beginning of each file it generates.
390   gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.7) puts "gcc2_compiled."
391   and "__gnu_language_<name>" and possibly "__vax_<type>_doubles".  */
392
393void
394vms_check_for_special_label (symbolS *symbolP)
395{
396  /* Special labels only occur prior to explicit section directives.  */
397  if ((const_flag & IN_DEFAULT_SECTION) != 0)
398    {
399      char *sym_name = S_GET_NAME (symbolP);
400
401      if (*sym_name == '_')
402	++sym_name;
403
404      if (!strcmp (sym_name, "__vax_g_doubles"))
405	vax_g_doubles = 1;
406#if 0	/* not necessary */
407      else if (!strcmp (sym_name, "__vax_d_doubles"))
408	vax_g_doubles = 0;
409#endif
410#if 0	/* These are potential alternatives to tc-vax.c's md_parse_options().  */
411      else if (!strcmp (sym_name, "gcc_compiled."))
412	flag_one = 1;
413      else if (!strcmp (sym_name, "__gnu_language_cplusplus"))
414	flag_hash_long_names = 1;
415#endif
416    }
417}
418
419void
420obj_read_begin_hook (void)
421{
422}
423
424void
425obj_crawl_symbol_chain (object_headers *headers)
426{
427  symbolS *symbolP;
428  symbolS **symbolPP;
429  int symbol_number = 0;
430
431  symbolPP = &symbol_rootP;	/* -> last symbol chain link.  */
432  while ((symbolP = *symbolPP) != NULL)
433    {
434      resolve_symbol_value (symbolP);
435
436     /* OK, here is how we decide which symbols go out into the
437	brave new symtab.  Symbols that do are:
438
439	* symbols with no name (stabd's?)
440	* symbols with debug info in their N_TYPE
441	* symbols with \1 as their 3rd character (numeric labels)
442	* "local labels" needed for PIC fixups
443
444	Symbols that don't are:
445	* symbols that are registers
446
447	All other symbols are output.  We complain if a deleted
448	symbol was marked external.  */
449
450      if (!S_IS_REGISTER (symbolP))
451	{
452	  symbolP->sy_number = symbol_number++;
453	  symbolP->sy_name_offset = 0;
454	  symbolPP = &symbolP->sy_next;
455	}
456      else
457	{
458	  if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
459	    as_bad (_("Local symbol %s never defined"),
460		    S_GET_NAME (symbolP));
461
462	  /* Unhook it from the chain.  */
463	  *symbolPP = symbol_next (symbolP);
464	}
465    }
466
467  H_SET_STRING_SIZE (headers, string_byte_count);
468  H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
469}
470
471
472/* VMS OBJECT FILE HACKING ROUTINES.  */
473
474/* Create the VMS object file.  */
475
476static void
477Create_VMS_Object_File (void)
478{
479#ifdef eunice
480  VMS_Object_File_FD = creat (out_file_name, 0777, "var");
481#else
482#ifndef VMS
483  VMS_Object_File_FD = creat (out_file_name, 0777);
484#else	/* VMS */
485  VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var",
486			      "ctx=bin", "mbc=16", "deq=64", "fop=tef",
487			      "shr=nil");
488#endif	/* !VMS */
489#endif	/* !eunice */
490  /* Deal with errors.  */
491  if (VMS_Object_File_FD < 0)
492    as_fatal (_("Couldn't create VMS object file \"%s\""), out_file_name);
493  /* Initialize object file hacking variables.  */
494  Object_Record_Offset = 0;
495  Current_Object_Record_Type = -1;
496}
497
498/* Flush the object record buffer to the object file.  */
499
500static void
501Flush_VMS_Object_Record_Buffer (void)
502{
503  /* If the buffer is empty, there's nothing to do.  */
504  if (Object_Record_Offset == 0)
505    return;
506
507#ifndef VMS			/* For cross-assembly purposes.  */
508  {
509    char RecLen[2];
510
511    /* "Variable-length record" files have a two byte length field
512       prepended to each record.  It's normally out-of-band, and native
513       VMS output will insert it automatically for this type of file.
514       When cross-assembling, we must write it explicitly.  */
515    md_number_to_chars (RecLen, Object_Record_Offset, 2);
516    if (write (VMS_Object_File_FD, RecLen, 2) != 2)
517      error (_("I/O error writing VMS object file (length prefix)"));
518    /* We also need to force the actual record to be an even number of
519       bytes.  For native output, that's automatic; when cross-assembling,
520       pad with a NUL byte if length is odd.  Do so _after_ writing the
521       pre-padded length.  Since our buffer is defined with even size,
522       an odd offset implies that it has some room left.  */
523    if ((Object_Record_Offset & 1) != 0)
524      Object_Record_Buffer[Object_Record_Offset++] = '\0';
525  }
526#endif /* not VMS */
527
528  /* Write the data to the file.  */
529  if ((size_t) write (VMS_Object_File_FD, Object_Record_Buffer,
530		      Object_Record_Offset) != Object_Record_Offset)
531    error (_("I/O error writing VMS object file"));
532
533  /* The buffer is now empty.  */
534  Object_Record_Offset = 0;
535}
536
537/* Declare a particular type of object file record.  */
538
539static void
540Set_VMS_Object_File_Record (int Type)
541{
542  /* If the type matches, we are done.  */
543  if (Type == Current_Object_Record_Type)
544    return;
545  /* Otherwise: flush the buffer.  */
546  Flush_VMS_Object_Record_Buffer ();
547  /* Remember the new type.  */
548  Current_Object_Record_Type = Type;
549}
550
551/* Close the VMS Object file.  */
552
553static void
554Close_VMS_Object_File (void)
555{
556  /* Flush (should never be necessary) and reset saved record-type context.  */
557  Set_VMS_Object_File_Record (-1);
558
559#ifndef VMS			/* For cross-assembly purposes.  */
560  {
561    char RecLen[2];
562    int minus_one = -1;
563
564    /* Write a 2 byte record-length field of -1 into the file, which
565       means end-of-block when read, hence end-of-file when occurring
566       in the file's last block.  It is only needed for variable-length
567       record files transferred to VMS as fixed-length record files
568       (typical for binary FTP; NFS shouldn't need it, but it won't hurt).  */
569    md_number_to_chars (RecLen, minus_one, 2);
570    write (VMS_Object_File_FD, RecLen, 2);
571  }
572#else
573    /* When written on a VMS system, the file header (cf inode) will record
574       the actual end-of-file position and no inline marker is needed.  */
575#endif
576
577  close (VMS_Object_File_FD);
578}
579
580/* Text Information and Relocation routines. */
581
582/* Stack Psect base followed by signed, varying-sized offset.
583   Common to several object records.  */
584
585static void
586vms_tir_stack_psect (int Psect_Index, int Offset, int Force)
587{
588  int psect_width, offset_width;
589
590  psect_width = ((unsigned) Psect_Index > 255) ? 2 : 1;
591  offset_width = (Force || Offset > 32767 || Offset < -32768) ? 4
592		 : (Offset > 127 || Offset < -128) ? 2 : 1;
593#define Sta_P(p,o) (((o)<<1) | ((p)-1))
594  /* Byte or word psect; byte, word, or longword offset.  */
595  switch (Sta_P(psect_width,offset_width))
596    {
597      case Sta_P(1,1):	PUT_CHAR (TIR_S_C_STA_PB);
598			PUT_CHAR ((char) (unsigned char) Psect_Index);
599			PUT_CHAR ((char) Offset);
600			break;
601      case Sta_P(1,2):	PUT_CHAR (TIR_S_C_STA_PW);
602			PUT_CHAR ((char) (unsigned char) Psect_Index);
603			PUT_SHORT (Offset);
604			break;
605      case Sta_P(1,4):	PUT_CHAR (TIR_S_C_STA_PL);
606			PUT_CHAR ((char) (unsigned char) Psect_Index);
607			PUT_LONG (Offset);
608			break;
609      case Sta_P(2,1):	PUT_CHAR (TIR_S_C_STA_WPB);
610			PUT_SHORT (Psect_Index);
611			PUT_CHAR ((char) Offset);
612			break;
613      case Sta_P(2,2):	PUT_CHAR (TIR_S_C_STA_WPW);
614			PUT_SHORT (Psect_Index);
615			PUT_SHORT (Offset);
616			break;
617      case Sta_P(2,4):	PUT_CHAR (TIR_S_C_STA_WPL);
618			PUT_SHORT (Psect_Index);
619			PUT_LONG (Offset);
620			break;
621    }
622#undef Sta_P
623}
624
625/* Store immediate data in current Psect.  */
626
627static void
628VMS_Store_Immediate_Data (const char *Pointer, int Size, int Record_Type)
629{
630  int i;
631
632  Set_VMS_Object_File_Record (Record_Type);
633  /* We can only store as most 128 bytes at a time due to the way that
634     TIR commands are encoded.  */
635  while (Size > 0)
636    {
637      i = (Size > 128) ? 128 : Size;
638      Size -= i;
639      /* If we cannot accommodate this record, flush the buffer.  */
640      if ((Object_Record_Offset + i + 1) >= sizeof Object_Record_Buffer)
641	Flush_VMS_Object_Record_Buffer ();
642      /* If the buffer is empty we must insert record type.  */
643      if (Object_Record_Offset == 0)
644	PUT_CHAR (Record_Type);
645      /* Store the count.  The Store Immediate TIR command is implied by
646         a negative command byte, and the length of the immediate data
647         is abs(command_byte).  So, we write the negated length value.  */
648      PUT_CHAR ((char) (-i & 0xff));
649      /* Now store the data.  */
650      while (--i >= 0)
651	PUT_CHAR (*Pointer++);
652    }
653  /* Flush the buffer if it is more than 75% full.  */
654  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
655    Flush_VMS_Object_Record_Buffer ();
656}
657
658/* Make a data reference.  */
659
660static void
661VMS_Set_Data (int Psect_Index, int Offset, int Record_Type, int Force)
662{
663  Set_VMS_Object_File_Record (Record_Type);
664  /* If the buffer is empty we must insert the record type.  */
665  if (Object_Record_Offset == 0)
666    PUT_CHAR (Record_Type);
667  /* Stack the Psect base with its offset.  */
668  vms_tir_stack_psect (Psect_Index, Offset, Force);
669  /* Set relocation base.  */
670  PUT_CHAR (TIR_S_C_STO_PIDR);
671  /* Flush the buffer if it is more than 75% full.  */
672  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
673    Flush_VMS_Object_Record_Buffer ();
674}
675
676/* Make a debugger reference to a struct, union or enum.  */
677
678static void
679VMS_Store_Struct (int Struct_Index)
680{
681  /* We are writing a debug record.  */
682  Set_VMS_Object_File_Record (OBJ_S_C_DBG);
683  /* If the buffer is empty we must insert the record type.  */
684  if (Object_Record_Offset == 0)
685    PUT_CHAR (OBJ_S_C_DBG);
686  PUT_CHAR (TIR_S_C_STA_UW);
687  PUT_SHORT (Struct_Index);
688  PUT_CHAR (TIR_S_C_CTL_STKDL);
689  PUT_CHAR (TIR_S_C_STO_L);
690  /* Flush the buffer if it is more than 75% full.  */
691  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
692    Flush_VMS_Object_Record_Buffer ();
693}
694
695/* Make a debugger reference to partially define a struct, union or enum.  */
696
697static void
698VMS_Def_Struct (int Struct_Index)
699{
700  /* We are writing a debug record.  */
701  Set_VMS_Object_File_Record (OBJ_S_C_DBG);
702  /* If the buffer is empty we must insert the record type.  */
703  if (Object_Record_Offset == 0)
704    PUT_CHAR (OBJ_S_C_DBG);
705  PUT_CHAR (TIR_S_C_STA_UW);
706  PUT_SHORT (Struct_Index);
707  PUT_CHAR (TIR_S_C_CTL_DFLOC);
708  /* Flush the buffer if it is more than 75% full.  */
709  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
710    Flush_VMS_Object_Record_Buffer ();
711}
712
713static void
714VMS_Set_Struct (int Struct_Index)
715{
716  Set_VMS_Object_File_Record (OBJ_S_C_DBG);
717  if (Object_Record_Offset == 0)
718    PUT_CHAR (OBJ_S_C_DBG);
719  PUT_CHAR (TIR_S_C_STA_UW);
720  PUT_SHORT (Struct_Index);
721  PUT_CHAR (TIR_S_C_CTL_STLOC);
722  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
723    Flush_VMS_Object_Record_Buffer ();
724}
725
726/* Traceback Information routines.  */
727
728/* Write the Traceback Module Begin record.  */
729
730static void
731VMS_TBT_Module_Begin (void)
732{
733  char *cp, *cp1;
734  int Size;
735  char Local[256];
736
737  /* Arrange to store the data locally (leave room for size byte).  */
738  cp = &Local[1];
739  /* Begin module.  */
740  *cp++ = DST_S_C_MODBEG;
741  *cp++ = 0;		/* flags; not used */
742  /* Language type == "C"
743    (FIXME:  this should be based on the input...)  */
744  COPY_LONG (cp, DST_S_C_C);
745  cp += 4;
746  /* Store the module name.  */
747  *cp++ = (char) strlen (Module_Name);
748  cp1 = Module_Name;
749  while (*cp1)
750    *cp++ = *cp1++;
751  /* Now we can store the record size.  */
752  Size = (cp - Local);
753  Local[0] = Size - 1;
754  /* Put it into the object record.  */
755  VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
756}
757
758/* Write the Traceback Module End record.  */
759
760static void
761VMS_TBT_Module_End (void)
762{
763  char Local[2];
764
765  /* End module.  */
766  Local[0] = 1;
767  Local[1] = DST_S_C_MODEND;
768  /* Put it into the object record.  */
769  VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT);
770}
771
772/* Write a Traceback Routine Begin record.  */
773
774static void
775VMS_TBT_Routine_Begin (symbolS *symbolP, int Psect)
776{
777  char *cp, *cp1;
778  char *Name;
779  int Offset;
780  int Size;
781  char Local[512];
782
783  /* Strip the leading "_" from the name.  */
784  Name = S_GET_NAME (symbolP);
785  if (*Name == '_')
786    Name++;
787  /* Get the text psect offset.  */
788  Offset = S_GET_VALUE (symbolP);
789  /* Set the record size.  */
790  Size = 1 + 1 + 4 + 1 + strlen (Name);
791  Local[0] = Size;
792  /* DST type "routine begin".  */
793  Local[1] = DST_S_C_RTNBEG;
794  /* Uses CallS/CallG.  */
795  Local[2] = 0;
796  /* Store the data so far.  */
797  VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
798  /* Make sure we are still generating a OBJ_S_C_TBT record.  */
799  if (Object_Record_Offset == 0)
800    PUT_CHAR (OBJ_S_C_TBT);
801  /* Stack the address.  */
802  vms_tir_stack_psect (Psect, Offset, 0);
803  /* Store the data reference.  */
804  PUT_CHAR (TIR_S_C_STO_PIDR);
805  /* Store the counted string as data.  */
806  cp = Local;
807  cp1 = Name;
808  Size = strlen (cp1) + 1;
809  *cp++ = Size - 1;
810  while (*cp1)
811    *cp++ = *cp1++;
812  VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
813}
814
815/* Write a Traceback Routine End record.
816
817   We *must* search the symbol table to find the next routine, since the
818   assembler has a way of reassembling the symbol table OUT OF ORDER Thus
819   the next routine in the symbol list is not necessarily the next one in
820   memory.  For debugging to work correctly we must know the size of the
821   routine.  */
822
823static void
824VMS_TBT_Routine_End (int Max_Size, symbolS *sp)
825{
826  symbolS *symbolP;
827  unsigned long Size = 0x7fffffff;
828  char Local[16];
829  valueT sym_value, sp_value = S_GET_VALUE (sp);
830
831  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
832    {
833      if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
834	{
835	  if (*S_GET_NAME (symbolP) == 'L')
836	    continue;
837	  sym_value = S_GET_VALUE (symbolP);
838	  if (sym_value > sp_value && sym_value < Size)
839	    Size = sym_value;
840
841	  /* Dummy labels like "gcc_compiled." should no longer reach here.  */
842#if 0
843	  else
844	    /* Check if gcc_compiled. has size of zero.  */
845	    if (sym_value == sp_value &&
846		sp != symbolP &&
847		(!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
848		 !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
849	      Size = sym_value;
850#endif
851	}
852    }
853  if (Size == 0x7fffffff)
854    Size = Max_Size;
855  Size -= sp_value;		/* and get the size of the routine */
856  /* Record Size.  */
857  Local[0] = 6;
858  /* DST type is "routine end".  */
859  Local[1] = DST_S_C_RTNEND;
860  Local[2] = 0;		/* unused */
861  /* Size of routine.  */
862  COPY_LONG (&Local[3], Size);
863  /* Store the record.  */
864  VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
865}
866
867/* Write a Traceback Block Begin record.  */
868
869static void
870VMS_TBT_Block_Begin (symbolS *symbolP, int Psect, char *Name)
871{
872  char *cp, *cp1;
873  int Offset;
874  int Size;
875  char Local[512];
876
877  /* Set the record size.  */
878  Size = 1 + 1 + 4 + 1 + strlen (Name);
879  Local[0] = Size;
880  /* DST type is "begin block"; we simulate with a phony routine.  */
881  Local[1] = DST_S_C_BLKBEG;
882  /* Uses CallS/CallG.  */
883  Local[2] = 0;
884  /* Store the data so far.  */
885  VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG);
886  /* Make sure we are still generating a debug record.  */
887  if (Object_Record_Offset == 0)
888    PUT_CHAR (OBJ_S_C_DBG);
889  /* Now get the symbol address.  */
890  PUT_CHAR (TIR_S_C_STA_WPL);
891  PUT_SHORT (Psect);
892  /* Get the text psect offset.  */
893  Offset = S_GET_VALUE (symbolP);
894  PUT_LONG (Offset);
895  /* Store the data reference.  */
896  PUT_CHAR (TIR_S_C_STO_PIDR);
897  /* Store the counted string as data.  */
898  cp = Local;
899  cp1 = Name;
900  Size = strlen (cp1) + 1;
901  *cp++ = Size - 1;
902  while (*cp1)
903    *cp++ = *cp1++;
904  VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG);
905}
906
907/* Write a Traceback Block End record.  */
908
909static void
910VMS_TBT_Block_End (valueT Size)
911{
912  char Local[16];
913
914  Local[0] = 6;		/* record length */
915  /* DST type is "block end"; simulate with a phony end routine.  */
916  Local[1] = DST_S_C_BLKEND;
917  Local[2] = 0;		/* unused, must be zero */
918  COPY_LONG (&Local[3], Size);
919  VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG);
920}
921
922
923/* Write a Line number <-> Program Counter correlation record.  */
924
925static void
926VMS_TBT_Line_PC_Correlation (int Line_Number, int Offset,
927			     int Psect, int Do_Delta)
928{
929  char *cp;
930  char Local[64];
931
932  if (Do_Delta == 0)
933    {
934      /* If not delta, set our PC/Line number correlation.  */
935      cp = &Local[1];	/* Put size in Local[0] later.  */
936      /* DST type is "Line Number/PC correlation".  */
937      *cp++ = DST_S_C_LINE_NUM;
938      /* Set Line number.  */
939      if (Line_Number - 1 <= 255)
940	{
941	  *cp++ = DST_S_C_SET_LINUM_B;
942	  *cp++ = (char) (Line_Number - 1);
943	}
944      else if (Line_Number - 1 <= 65535)
945	{
946	  *cp++ = DST_S_C_SET_LINE_NUM;
947	  COPY_SHORT (cp, Line_Number - 1),  cp += 2;
948	}
949      else
950	{
951	  *cp++ = DST_S_C_SET_LINUM_L;
952	  COPY_LONG (cp, Line_Number - 1),  cp += 4;
953	}
954      /* Set PC.  */
955      *cp++ = DST_S_C_SET_ABS_PC;
956      /* Store size now that we know it, then output the data.  */
957      Local[0] = cp - &Local[1];
958	/* Account for the space that TIR_S_C_STO_PIDR will use for the PC.  */
959	Local[0] += 4;		/* size includes length of another longword */
960      VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
961      /* Make sure we are still generating a OBJ_S_C_TBT record.  */
962      if (Object_Record_Offset == 0)
963	PUT_CHAR (OBJ_S_C_TBT);
964      vms_tir_stack_psect (Psect, Offset, 0);
965      PUT_CHAR (TIR_S_C_STO_PIDR);
966      /* Do a PC offset of 0 to register the line number.  */
967      Local[0] = 2;
968      Local[1] = DST_S_C_LINE_NUM;
969      Local[2] = 0;		/* Increment PC by 0 and register line # */
970      VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
971    }
972  else
973    {
974      if (Do_Delta < 0)
975	{
976	  /* When delta is negative, terminate the line numbers.  */
977	  Local[0] = 1 + 1 + 4;
978	  Local[1] = DST_S_C_LINE_NUM;
979	  Local[2] = DST_S_C_TERM_L;
980	  COPY_LONG (&Local[3], Offset);
981	  VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
982	  return;
983	}
984      /* Do a PC/Line delta.  */
985      cp = &Local[1];
986      *cp++ = DST_S_C_LINE_NUM;
987      if (Line_Number > 1)
988	{
989	  /* We need to increment the line number.  */
990	  if (Line_Number - 1 <= 255)
991	    {
992	      *cp++ = DST_S_C_INCR_LINUM;
993	      *cp++ = Line_Number - 1;
994	    }
995	  else if (Line_Number - 1 <= 65535)
996	    {
997	      *cp++ = DST_S_C_INCR_LINUM_W;
998	      COPY_SHORT (cp, Line_Number - 1),  cp += 2;
999	    }
1000	  else
1001	    {
1002	      *cp++ = DST_S_C_INCR_LINUM_L;
1003	      COPY_LONG (cp, Line_Number - 1),  cp += 4;
1004	    }
1005	}
1006      /* Increment the PC.  */
1007      if (Offset <= 128)
1008	{
1009	  /* Small offsets are encoded as negative numbers, rather than the
1010	     usual non-negative type code followed by another data field.  */
1011	  *cp++ = (char) -Offset;
1012	}
1013      else if (Offset <= 65535)
1014	{
1015	  *cp++ = DST_S_C_DELTA_PC_W;
1016	  COPY_SHORT (cp, Offset),  cp += 2;
1017	}
1018      else
1019	{
1020	  *cp++ = DST_S_C_DELTA_PC_L;
1021	  COPY_LONG (cp, Offset),  cp += 4;
1022	}
1023      /* Set size now that be know it, then output the data.  */
1024      Local[0] = cp - &Local[1];
1025      VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1026    }
1027}
1028
1029
1030/* Describe a source file to the debugger.  */
1031
1032static int
1033VMS_TBT_Source_File (char *Filename, int ID_Number)
1034{
1035  char *cp;
1036  int len, rfo, ffb, ebk;
1037  char cdt[8];
1038  char Local[512];
1039#ifdef VMS			/* Used for native assembly */
1040  unsigned Status;
1041  struct FAB fab;		/* RMS file access block */
1042  struct NAM nam;		/* file name information */
1043  struct XABDAT xabdat;		/* date+time fields */
1044  struct XABFHC xabfhc;		/* file header characteristics */
1045  char resultant_string_buffer[255 + 1];
1046
1047  /* Set up RMS structures:  */
1048  /* FAB -- file access block */
1049  memset ((char *) &fab, 0, sizeof fab);
1050  fab.fab$b_bid = FAB$C_BID;
1051  fab.fab$b_bln = (unsigned char) sizeof fab;
1052  fab.fab$l_fna = Filename;
1053  fab.fab$b_fns = (unsigned char) strlen (Filename);
1054  fab.fab$l_nam = (char *) &nam;
1055  fab.fab$l_xab = (char *) &xabdat;
1056  /* NAM -- file name block.  */
1057  memset ((char *) &nam, 0, sizeof nam);
1058  nam.nam$b_bid = NAM$C_BID;
1059  nam.nam$b_bln = (unsigned char) sizeof nam;
1060  nam.nam$l_rsa = resultant_string_buffer;
1061  nam.nam$b_rss = (unsigned char) (sizeof resultant_string_buffer - 1);
1062  /* XABs -- extended attributes blocks.  */
1063  memset ((char *) &xabdat, 0, sizeof xabdat);
1064  xabdat.xab$b_cod = XAB$C_DAT;
1065  xabdat.xab$b_bln = (unsigned char) sizeof xabdat;
1066  xabdat.xab$l_nxt = (char *) &xabfhc;
1067  memset ((char *) &xabfhc, 0, sizeof xabfhc);
1068  xabfhc.xab$b_cod = XAB$C_FHC;
1069  xabfhc.xab$b_bln = (unsigned char) sizeof xabfhc;
1070  xabfhc.xab$l_nxt = 0;
1071
1072  /* Get the file information.  */
1073  Status = sys$open (&fab);
1074  if (!(Status & 1))
1075    {
1076      as_tsktsk (_("Couldn't find source file \"%s\", status=%%X%x"),
1077		 Filename, Status);
1078      return 0;
1079    }
1080  sys$close (&fab);
1081  /* Now extract fields of interest.  */
1082  memcpy (cdt, (char *) &xabdat.xab$q_cdt, 8);	/* creation date */
1083  ebk = xabfhc.xab$l_ebk;		/* end-of-file block */
1084  ffb = xabfhc.xab$w_ffb;		/* first free byte of last block */
1085  rfo = xabfhc.xab$b_rfo;		/* record format */
1086  len = nam.nam$b_rsl;			/* length of Filename */
1087  resultant_string_buffer[len] = '\0';
1088  Filename = resultant_string_buffer;	/* full filename */
1089#else				/* Cross-assembly */
1090  /* [Perhaps we ought to use actual values derived from stat() here?]  */
1091  memset (cdt, 0, 8);			/* null VMS quadword binary time */
1092  ebk = ffb = rfo = 0;
1093  len = strlen (Filename);
1094  if (len > 255)	/* a single byte is used as count prefix */
1095    {
1096      Filename += (len - 255);		/* tail end is more significant */
1097      len = 255;
1098    }
1099#endif /* VMS */
1100
1101  cp = &Local[1];			/* fill in record length later */
1102  *cp++ = DST_S_C_SOURCE;		/* DST type is "source file" */
1103  *cp++ = DST_S_C_SRC_FORMFEED;		/* formfeeds count as source records */
1104  *cp++ = DST_S_C_SRC_DECLFILE;		/* declare source file */
1105  know (cp == &Local[4]);
1106  *cp++ = 0;				/* fill in this length below */
1107  *cp++ = 0;				/* flags; must be zero */
1108  COPY_SHORT (cp, ID_Number),  cp += 2;	/* file ID number */
1109  memcpy (cp, cdt, 8),  cp += 8;	/* creation date+time */
1110  COPY_LONG (cp, ebk),  cp += 4;	/* end-of-file block */
1111  COPY_SHORT (cp, ffb),  cp += 2;	/* first free byte of last block */
1112  *cp++ = (char) rfo;			/* RMS record format */
1113  /* Filename.  */
1114  *cp++ = (char) len;
1115  while (--len >= 0)
1116    *cp++ = *Filename++;
1117  /* Library module name (none).  */
1118  *cp++ = 0;
1119  /* Now that size is known, fill it in and write out the record.  */
1120  Local[4] = cp - &Local[5];		/* source file declaration size */
1121  Local[0] = cp - &Local[1];		/* TBT record size */
1122  VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1123  return 1;
1124}
1125
1126/* Traceback information is described in terms of lines from compiler
1127   listing files, not lines from source files.  We need to set up the
1128   correlation between listing line numbers and source line numbers.
1129   Since gcc's .stabn directives refer to the source lines, we just
1130   need to describe a one-to-one correspondence.  */
1131
1132static void
1133VMS_TBT_Source_Lines (int ID_Number, int Starting_Line_Number,
1134		      int Number_Of_Lines)
1135{
1136  char *cp;
1137  int chunk_limit;
1138  char Local[128];	/* room enough to describe 1310700 lines...  */
1139
1140  cp = &Local[1];	/* Put size in Local[0] later.  */
1141  *cp++ = DST_S_C_SOURCE;		/* DST type is "source file".  */
1142  *cp++ = DST_S_C_SRC_SETFILE;		/* Set Source File.  */
1143  COPY_SHORT (cp, ID_Number),  cp += 2;	/* File ID Number.  */
1144  /* Set record number and define lines.  Since no longword form of
1145     SRC_DEFLINES is available, we need to be able to cope with any huge
1146     files a chunk at a time.  It doesn't matter for tracebacks, since
1147     unspecified lines are mapped one-to-one and work out right, but it
1148     does matter within the debugger.  Without this explicit mapping,
1149     it will complain about lines not existing in the module.  */
1150  chunk_limit = (sizeof Local - 5) / 6;
1151  if (Number_Of_Lines > 65535 * chunk_limit)	/* avoid buffer overflow */
1152    Number_Of_Lines = 65535 * chunk_limit;
1153  while (Number_Of_Lines > 65535)
1154    {
1155      *cp++ = DST_S_C_SRC_SETREC_L;
1156      COPY_LONG (cp, Starting_Line_Number),  cp += 4;
1157      *cp++ = DST_S_C_SRC_DEFLINES_W;
1158      COPY_SHORT (cp, 65535),  cp += 2;
1159      Starting_Line_Number += 65535;
1160      Number_Of_Lines -= 65535;
1161    }
1162  /* Set record number and define lines, normal case.  */
1163  if (Starting_Line_Number <= 65535)
1164    {
1165      *cp++ = DST_S_C_SRC_SETREC_W;
1166      COPY_SHORT (cp, Starting_Line_Number),  cp += 2;
1167    }
1168  else
1169    {
1170      *cp++ = DST_S_C_SRC_SETREC_L;
1171      COPY_LONG (cp, Starting_Line_Number),  cp += 4;
1172    }
1173  *cp++ = DST_S_C_SRC_DEFLINES_W;
1174  COPY_SHORT (cp, Number_Of_Lines),  cp += 2;
1175  /* Set size now that be know it, then output the data.  */
1176  Local[0] = cp - &Local[1];
1177  VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1178}
1179
1180
1181/* Debugger Information support routines. */
1182
1183/* This routine locates a file in the list of files.  If an entry does
1184   not exist, one is created.  For include files, a new entry is always
1185   created such that inline functions can be properly debugged.  */
1186
1187static struct input_file *
1188find_file (symbolS *sp)
1189{
1190  struct input_file *same_file = 0;
1191  struct input_file *fpnt, *last = 0;
1192  char *sp_name;
1193
1194  for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1195    {
1196      if (fpnt->spnt == sp)
1197	return fpnt;
1198      last = fpnt;
1199    }
1200  sp_name = S_GET_NAME (sp);
1201  for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1202    {
1203      if (strcmp (sp_name, fpnt->name) == 0)
1204	{
1205	  if (fpnt->flag == 1)
1206	    return fpnt;
1207	  same_file = fpnt;
1208	  break;
1209	}
1210    }
1211  fpnt = xmalloc (sizeof (struct input_file));
1212  if (!file_root)
1213    file_root = fpnt;
1214  else
1215    last->next = fpnt;
1216  fpnt->next = 0;
1217  fpnt->name = sp_name;
1218  fpnt->min_line = 0x7fffffff;
1219  fpnt->max_line = 0;
1220  fpnt->offset = 0;
1221  fpnt->flag = 0;
1222  fpnt->file_number = 0;
1223  fpnt->spnt = sp;
1224  fpnt->same_file_fpnt = same_file;
1225  return fpnt;
1226}
1227
1228/* This routine converts a number string into an integer, and stops when
1229   it sees an invalid character.  The return value is the address of the
1230   character just past the last character read.  No error is generated.  */
1231
1232static char *
1233cvt_integer (char *str, int *rtn)
1234{
1235  int ival = 0, sgn = 1;
1236
1237  if (*str == '-')
1238    sgn = -1,  ++str;
1239  while (*str >= '0' && *str <= '9')
1240    ival = 10 * ival + *str++ - '0';
1241  *rtn = sgn * ival;
1242  return str;
1243}
1244
1245
1246/* The following functions and definitions are used to generate object
1247   records that will describe program variables to the VMS debugger.
1248
1249   This file contains many of the routines needed to output debugging info
1250   into the object file that the VMS debugger needs to understand symbols.
1251   These routines are called very late in the assembly process, and thus
1252   we can be fairly lax about changing things, since the GSD and the TIR
1253   sections have already been output.  */
1254
1255/* This routine fixes the names that are generated by C++, ".this" is a good
1256   example.  The period does not work for the debugger, since it looks like
1257   the syntax for a structure element, and thus it gets mightily confused.
1258
1259   We also use this to strip the PsectAttribute hack from the name before we
1260   write a debugger record.  */
1261
1262static char *
1263fix_name (char *pnt)
1264{
1265  char *pnt1;
1266
1267  /* Kill any leading "_".  */
1268  if (*pnt == '_')
1269    pnt++;
1270
1271  /* Is there a Psect Attribute to skip??  */
1272  if (HAS_PSECT_ATTRIBUTES (pnt))
1273    {
1274      /* Yes: Skip it.  */
1275      pnt += PSECT_ATTRIBUTES_STRING_LENGTH;
1276      while (*pnt)
1277	{
1278	  if ((pnt[0] == '$') && (pnt[1] == '$'))
1279	    {
1280	      pnt += 2;
1281	      break;
1282	    }
1283	  pnt++;
1284	}
1285    }
1286
1287  /* Here we fix the .this -> $this conversion.  */
1288  for (pnt1 = pnt; *pnt1 != 0; pnt1++)
1289    if (*pnt1 == '.')
1290      *pnt1 = '$';
1291
1292  return pnt;
1293}
1294
1295/* When defining a structure, this routine is called to find the name of
1296   the actual structure.  It is assumed that str points to the equal sign
1297   in the definition, and it moves backward until it finds the start of the
1298   name.  If it finds a 0, then it knows that this structure def is in the
1299   outermost level, and thus symbol_name points to the symbol name.  */
1300
1301static char *
1302get_struct_name (char *str)
1303{
1304  char *pnt;
1305  pnt = str;
1306  while ((*pnt != ':') && (*pnt != '\0'))
1307    pnt--;
1308  if (*pnt == '\0')
1309    return (char *) symbol_name;
1310  *pnt-- = '\0';
1311  while ((*pnt != ';') && (*pnt != '='))
1312    pnt--;
1313  if (*pnt == ';')
1314    return pnt + 1;
1315  while ((*pnt < '0') || (*pnt > '9'))
1316    pnt++;
1317  while ((*pnt >= '0') && (*pnt <= '9'))
1318    pnt++;
1319  return pnt;
1320}
1321
1322/* Search symbol list for type number dbx_type.
1323   Return a pointer to struct.  */
1324
1325static struct VMS_DBG_Symbol *
1326find_symbol (int dbx_type)
1327{
1328  struct VMS_DBG_Symbol *spnt;
1329
1330  spnt = VMS_Symbol_type_list[SYMTYP_HASH (dbx_type)];
1331  while (spnt)
1332    {
1333      if (spnt->dbx_type == dbx_type)
1334	break;
1335      spnt = spnt->next;
1336    }
1337  if (!spnt || spnt->advanced != ALIAS)
1338    return spnt;
1339  return find_symbol (spnt->type2);
1340}
1341
1342#if 0		/* obsolete */
1343/* This routine puts info into either Local or Asuffix, depending on the sign
1344   of size.  The reason is that it is easier to build the variable descriptor
1345   backwards, while the array descriptor is best built forwards.  In the end
1346   they get put together, if there is not a struct/union/enum along the way.  */
1347
1348static void
1349push (int value, int size1)
1350{
1351  if (size1 < 0)
1352    {
1353      size1 = -size1;
1354      if (Lpnt < size1)
1355	{
1356	  overflow = 1;
1357	  Lpnt = 1;
1358	  return;
1359	}
1360      Lpnt -= size1;
1361      md_number_to_chars (&Local[Lpnt + 1], value, size1);
1362    }
1363  else
1364    {
1365      if (Apoint + size1 >= MAX_DEBUG_RECORD)
1366	{
1367	  overflow = 1;
1368	  Apoint = MAX_DEBUG_RECORD - 1;
1369	  return;
1370	}
1371      md_number_to_chars (&Asuffix[Apoint], value, size1);
1372      Apoint += size1;
1373    }
1374}
1375#endif
1376
1377static void
1378fpush (int value, int size)
1379{
1380  if (Apoint + size >= MAX_DEBUG_RECORD)
1381    {
1382      overflow = 1;
1383      Apoint = MAX_DEBUG_RECORD - 1;
1384      return;
1385    }
1386  if (size == 1)
1387    Asuffix[Apoint++] = (char) value;
1388  else
1389    {
1390      md_number_to_chars (&Asuffix[Apoint], value, size);
1391      Apoint += size;
1392    }
1393}
1394
1395static void
1396rpush (int value, int size)
1397{
1398  if (Lpnt < size)
1399    {
1400      overflow = 1;
1401      Lpnt = 1;
1402      return;
1403    }
1404  if (size == 1)
1405      Local[Lpnt--] = (char) value;
1406  else
1407    {
1408      Lpnt -= size;
1409      md_number_to_chars (&Local[Lpnt + 1], value, size);
1410    }
1411}
1412
1413/* This routine generates the array descriptor for a given array.  */
1414
1415static void
1416array_suffix (struct VMS_DBG_Symbol *spnt2)
1417{
1418  struct VMS_DBG_Symbol *spnt;
1419  struct VMS_DBG_Symbol *spnt1;
1420  int rank;
1421  int total_size;
1422
1423  rank = 0;
1424  spnt = spnt2;
1425  while (spnt->advanced != ARRAY)
1426    {
1427      spnt = find_symbol (spnt->type2);
1428      if (!spnt)
1429	return;
1430    }
1431  spnt1 = spnt;
1432  total_size = 1;
1433  while (spnt1->advanced == ARRAY)
1434    {
1435      rank++;
1436      total_size *= (spnt1->index_max - spnt1->index_min + 1);
1437      spnt1 = find_symbol (spnt1->type2);
1438    }
1439  total_size = total_size * spnt1->data_size;
1440  fpush (spnt1->data_size, 2);	/* element size */
1441  if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
1442    fpush (0, 1);
1443  else
1444    fpush (spnt1->VMS_type, 1);	/* element type */
1445  fpush (DSC_K_CLASS_A, 1);	/* descriptor class */
1446  fpush (0, 4);			/* base address */
1447  fpush (0, 1);			/* scale factor -- not applicable */
1448  fpush (0, 1);			/* digit count -- not applicable */
1449  fpush (0xc0, 1);		/* flags: multiplier block & bounds present */
1450  fpush (rank, 1);		/* number of dimensions */
1451  fpush (total_size, 4);
1452  fpush (0, 4);			/* pointer to element [0][0]...[0] */
1453  spnt1 = spnt;
1454  while (spnt1->advanced == ARRAY)
1455    {
1456      fpush (spnt1->index_max - spnt1->index_min + 1, 4);
1457      spnt1 = find_symbol (spnt1->type2);
1458    }
1459  spnt1 = spnt;
1460  while (spnt1->advanced == ARRAY)
1461    {
1462      fpush (spnt1->index_min, 4);
1463      fpush (spnt1->index_max, 4);
1464      spnt1 = find_symbol (spnt1->type2);
1465    }
1466}
1467
1468/* This routine generates the start of a variable descriptor based upon
1469   a struct/union/enum that has yet to be defined.  We define this spot as
1470   a new location, and save four bytes for the address.  When the struct is
1471   finally defined, then we can go back and plug in the correct address.  */
1472
1473static void
1474new_forward_ref (int dbx_type)
1475{
1476  struct forward_ref *fpnt;
1477
1478  fpnt = xmalloc (sizeof (struct forward_ref));
1479  fpnt->next = f_ref_root;
1480  f_ref_root = fpnt;
1481  fpnt->dbx_type = dbx_type;
1482  fpnt->struc_numb = ++structure_count;
1483  fpnt->resolved = 'N';
1484  rpush (DST_K_TS_IND, 1);	/* indirect type specification */
1485  total_len = 5;
1486  rpush (total_len, 2);
1487  struct_number = -fpnt->struc_numb;
1488}
1489
1490/* This routine generates the variable descriptor used to describe non-basic
1491   variables.  It calls itself recursively until it gets to the bottom of it
1492   all, and then builds the descriptor backwards.  It is easiest to do it
1493   this way since we must periodically write length bytes, and it is easiest
1494   if we know the value when it is time to write it.  */
1495
1496static int
1497gen1 (struct VMS_DBG_Symbol *spnt, int array_suffix_len)
1498{
1499  struct VMS_DBG_Symbol *spnt1;
1500  int i;
1501
1502  switch (spnt->advanced)
1503    {
1504    case VOID:
1505      rpush (DBG_S_C_VOID, 1);
1506      total_len += 1;
1507      rpush (total_len, 2);
1508      return 0;
1509    case BASIC:
1510    case FUNCTION:
1511      if (array_suffix_len == 0)
1512	{
1513	  rpush (spnt->VMS_type, 1);
1514	  rpush (DBG_S_C_BASIC, 1);
1515	  total_len = 2;
1516	  rpush (total_len, 2);
1517	  return 1;
1518	}
1519      rpush (0, 4);
1520      rpush (DST_K_VFLAGS_DSC, 1);
1521      rpush (DST_K_TS_DSC, 1);	/* Descriptor type specification.  */
1522      total_len = -2;
1523      return 1;
1524    case STRUCT:
1525    case UNION:
1526    case ENUM:
1527      struct_number = spnt->struc_numb;
1528      if (struct_number < 0)
1529	{
1530	  new_forward_ref (spnt->dbx_type);
1531	  return 1;
1532	}
1533      rpush (DBG_S_C_STRUCT, 1);
1534      total_len = 5;
1535      rpush (total_len, 2);
1536      return 1;
1537    case POINTER:
1538      spnt1 = find_symbol (spnt->type2);
1539      i = 1;
1540      if (!spnt1)
1541	new_forward_ref (spnt->type2);
1542      else
1543	i = gen1 (spnt1, 0);
1544      if (i)
1545	{
1546	  /* (*void) is a special case, do not put pointer suffix.  */
1547	  rpush (DBG_S_C_POINTER, 1);
1548	  total_len += 3;
1549	  rpush (total_len, 2);
1550	}
1551      return 1;
1552    case ARRAY:
1553      spnt1 = spnt;
1554      while (spnt1->advanced == ARRAY)
1555	{
1556	  spnt1 = find_symbol (spnt1->type2);
1557	  if (!spnt1)
1558	    {
1559	      as_tsktsk (_("debugger forward reference error, dbx type %d"),
1560			 spnt->type2);
1561	      return 0;
1562	    }
1563	}
1564      /* It is too late to generate forward references, so the user
1565	 gets a message.  This should only happen on a compiler error.  */
1566      (void) gen1 (spnt1, 1);
1567      i = Apoint;
1568      array_suffix (spnt);
1569      array_suffix_len = Apoint - i;
1570      switch (spnt1->advanced)
1571	{
1572	case BASIC:
1573	case FUNCTION:
1574	  break;
1575	default:
1576	  rpush (0, 2);
1577	  total_len += 2;
1578	  rpush (total_len, 2);
1579	  rpush (DST_K_VFLAGS_DSC, 1);
1580	  rpush (1, 1);		/* Flags: element value spec included.  */
1581	  rpush (1, 1);		/* One dimension.  */
1582	  rpush (DBG_S_C_COMPLEX_ARRAY, 1);
1583	}
1584      total_len += array_suffix_len + 8;
1585      rpush (total_len, 2);
1586      break;
1587    default:
1588      break;
1589    }
1590  return 0;
1591}
1592
1593/* This generates a suffix for a variable.  If it is not a defined type yet,
1594   then dbx_type contains the type we are expecting so we can generate a
1595   forward reference.  This calls gen1 to build most of the descriptor, and
1596   then it puts the icing on at the end.  It then dumps whatever is needed
1597   to get a complete descriptor (i.e. struct reference, array suffix).  */
1598
1599static void
1600generate_suffix (struct VMS_DBG_Symbol *spnt, int dbx_type)
1601{
1602  static const char pvoid[6] =
1603    {
1604      5,		/* record.length == 5 */
1605      DST_K_TYPSPEC,	/* record.type == 1 (type specification) */
1606      0,		/* name.length == 0, no name follows */
1607      1, 0,		/* type.length == 1 {2 bytes, little endian} */
1608      DBG_S_C_VOID	/* type.type == 5 (pointer to unspecified) */
1609    };
1610  int i;
1611
1612  Apoint = 0;
1613  Lpnt = MAX_DEBUG_RECORD - 1;
1614  total_len = 0;
1615  struct_number = 0;
1616  overflow = 0;
1617  if (!spnt)
1618    new_forward_ref (dbx_type);
1619  else
1620    {
1621      if (spnt->VMS_type != DBG_S_C_ADVANCED_TYPE)
1622	return;		/* no suffix needed */
1623      gen1 (spnt, 0);
1624    }
1625  rpush (0, 1);		/* no name (len==0) */
1626  rpush (DST_K_TYPSPEC, 1);
1627  total_len += 4;
1628  rpush (total_len, 1);
1629  /* If the variable descriptor overflows the record, output a descriptor
1630     for a pointer to void.  */
1631  if ((total_len >= MAX_DEBUG_RECORD) || overflow)
1632    {
1633      as_warn (_("Variable descriptor %d too complicated.  Defined as `void *'."),
1634		spnt->dbx_type);
1635      VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG);
1636      return;
1637    }
1638  i = 0;
1639  while (Lpnt < MAX_DEBUG_RECORD - 1)
1640    Local[i++] = Local[++Lpnt];
1641  Lpnt = i;
1642  /* We use this for reference to structure that has already been defined.  */
1643  if (struct_number > 0)
1644    {
1645      VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1646      Lpnt = 0;
1647      VMS_Store_Struct (struct_number);
1648    }
1649  /* We use this for a forward reference to a structure that has yet to
1650     be defined.  We store four bytes of zero to make room for the actual
1651     address once it is known.  */
1652  if (struct_number < 0)
1653    {
1654      struct_number = -struct_number;
1655      VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1656      Lpnt = 0;
1657      VMS_Def_Struct (struct_number);
1658      COPY_LONG (&Local[Lpnt], 0L);
1659      Lpnt += 4;
1660      VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1661      Lpnt = 0;
1662    }
1663  i = 0;
1664  while (i < Apoint)
1665    Local[Lpnt++] = Asuffix[i++];
1666  if (Lpnt != 0)
1667    VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1668  Lpnt = 0;
1669}
1670
1671/* "novel length" type doesn't work for simple atomic types.  */
1672#define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
1673#undef SETUP_BASIC_TYPES
1674
1675/* This routine generates a type description for a bitfield.  */
1676
1677static void
1678bitfield_suffix (struct VMS_DBG_Symbol *spnt, int width)
1679{
1680  Local[Lpnt++] = 13;			/* rec.len==13 */
1681  Local[Lpnt++] = DST_K_TYPSPEC;	/* a type specification record */
1682  Local[Lpnt++] = 0;			/* not named */
1683  COPY_SHORT (&Local[Lpnt], 9);		/* typ.len==9 */
1684  Lpnt += 2;
1685  Local[Lpnt++] = DST_K_TS_NOV_LENG;	/* This type is a "novel length"
1686					   incarnation of some other type.  */
1687  COPY_LONG (&Local[Lpnt], width);	/* size in bits == novel length */
1688  Lpnt += 4;
1689  VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1690  Lpnt = 0;
1691  /* assert( spnt->struc_numb > 0 ); */
1692  VMS_Store_Struct (spnt->struc_numb);	/* output 4 more bytes */
1693}
1694
1695/* Formally define a builtin type, so that it can serve as the target of
1696   an indirect reference.  It makes bitfield_suffix() easier by avoiding
1697   the need to use a forward reference for the first occurrence of each
1698   type used in a bitfield.  */
1699
1700static void
1701setup_basic_type (struct VMS_DBG_Symbol *spnt ATTRIBUTE_UNUSED)
1702{
1703#ifdef SETUP_BASIC_TYPES
1704  /* This would be very useful if "novel length" fields actually worked
1705     with basic types like they do with enumerated types.  However,
1706     they do not, so this isn't worth doing just so that you can use
1707     EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD.  */
1708  char *p;
1709#ifndef SETUP_SYNONYM_TYPES
1710  /* This determines whether compatible things like `int' and `long int'
1711     ought to have distinct type records rather than sharing one.  */
1712  struct VMS_DBG_Symbol *spnt2;
1713
1714  /* First check whether this type has already been seen by another name.  */
1715  for (spnt2 = VMS_Symbol_type_list[SYMTYP_HASH (spnt->VMS_type)];
1716       spnt2;
1717       spnt2 = spnt2->next)
1718    if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type)
1719      {
1720	spnt->struc_numb = spnt2->struc_numb;
1721	return;
1722      }
1723#endif
1724
1725  /* `structure number' doesn't really mean `structure'; it means an index
1726     into a linker maintained set of saved locations which can be referenced
1727     again later.  */
1728  spnt->struc_numb = ++structure_count;
1729  VMS_Def_Struct (spnt->struc_numb);	/* remember where this type lives */
1730  /* define the simple scalar type */
1731  Local[Lpnt++] = 6 + strlen (symbol_name) + 2;	/* rec.len */
1732  Local[Lpnt++] = DST_K_TYPSPEC;	/* rec.typ==type specification */
1733  Local[Lpnt++] = strlen (symbol_name) + 2;
1734  Local[Lpnt++] = '_';			/* prefix name with "__" */
1735  Local[Lpnt++] = '_';
1736  for (p = symbol_name; *p; p++)
1737    Local[Lpnt++] = *p == ' ' ? '_' : *p;
1738  COPY_SHORT (&Local[Lpnt], 2);		/* typ.len==2 */
1739  Lpnt += 2;
1740  Local[Lpnt++] = DST_K_TS_ATOM;	/* typ.kind is simple type */
1741  Local[Lpnt++] = spnt->VMS_type;	/* typ.type */
1742  VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1743  Lpnt = 0;
1744#endif	/* SETUP_BASIC_TYPES */
1745}
1746
1747/* This routine generates a symbol definition for a C symbol for the
1748   debugger.  It takes a psect and offset for global symbols; if psect < 0,
1749   then this is a local variable and the offset is relative to FP.  In this
1750   case it can be either a variable (Offset < 0) or a parameter (Offset > 0).  */
1751
1752static void
1753VMS_DBG_record (struct VMS_DBG_Symbol *spnt, int Psect,
1754		int Offset, char *Name)
1755{
1756  char *Name_pnt;
1757  int len;
1758  int i = 0;
1759
1760  /* If there are bad characters in name, convert them.  */
1761  Name_pnt = fix_name (Name);
1762
1763  len = strlen (Name_pnt);
1764  if (Psect < 0)
1765    {
1766      /* This is a local variable, referenced to SP.  */
1767      Local[i++] = 7 + len;
1768      Local[i++] = spnt->VMS_type;
1769      Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM;
1770      COPY_LONG (&Local[i], Offset);
1771      i += 4;
1772    }
1773  else
1774    {
1775      Local[i++] = 7 + len;
1776      Local[i++] = spnt->VMS_type;
1777      Local[i++] = DST_K_VALKIND_ADDR;
1778      VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
1779      i = 0;
1780      VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
1781    }
1782  Local[i++] = len;
1783  while (*Name_pnt != '\0')
1784    Local[i++] = *Name_pnt++;
1785  VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
1786  if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
1787    generate_suffix (spnt, 0);
1788}
1789
1790/* This routine parses the stabs entries in order to make the definition
1791   for the debugger of local symbols and function parameters.  */
1792
1793static void
1794VMS_local_stab_Parse (symbolS *sp)
1795{
1796  struct VMS_DBG_Symbol *spnt;
1797  char *pnt;
1798  char *pnt1;
1799  char *str;
1800  int dbx_type;
1801
1802  dbx_type = 0;
1803  str = S_GET_NAME (sp);
1804  pnt = (char *) strchr (str, ':');
1805  if (!pnt)
1806    return;
1807
1808  /* Save this for later, and skip colon.  */
1809  pnt1 = pnt++;
1810
1811  /* Ignore static constants.  */
1812  if (*pnt == 'c')
1813    return;
1814
1815  /* There is one little catch that we must be aware of.  Sometimes function
1816     parameters are optimized into registers, and the compiler, in its
1817     infiite wisdom outputs stabs records for *both*.  In general we want to
1818     use the register if it is present, so we must search the rest of the
1819     symbols for this function to see if this parameter is assigned to a
1820     register.  */
1821  {
1822    symbolS *sp1;
1823    char *str1;
1824    char *pnt2;
1825
1826    if (*pnt == 'p')
1827      {
1828	for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1))
1829	  {
1830	    if (!S_IS_DEBUG (sp1))
1831	      continue;
1832	    if (S_GET_RAW_TYPE (sp1) == N_FUN)
1833	      {
1834		pnt2 = (char *) strchr (S_GET_NAME (sp1), ':') + 1;
1835		if (*pnt2 == 'F' || *pnt2 == 'f')
1836		  break;
1837	      }
1838	    if (S_GET_RAW_TYPE (sp1) != N_RSYM)
1839	      continue;
1840	    str1 = S_GET_NAME (sp1);	/* and get the name */
1841	    pnt2 = str;
1842	    while (*pnt2 != ':')
1843	      {
1844		if (*pnt2 != *str1)
1845		  break;
1846		pnt2++;
1847		str1++;
1848	      }
1849	    if (*str1 == ':' && *pnt2 == ':')
1850	      return;	/* They are the same!  Let's skip this one.  */
1851	  }
1852
1853	/* Skip p in case no register.  */
1854	pnt++;
1855      }
1856  }
1857
1858  pnt = cvt_integer (pnt, &dbx_type);
1859
1860  spnt = find_symbol (dbx_type);
1861  if (!spnt)
1862    /* Dunno what this is.  */
1863    return;
1864
1865  *pnt1 = '\0';
1866  VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
1867
1868  /* ...and restore the string.  */
1869  *pnt1 = ':';
1870}
1871
1872/* This routine parses a stabs entry to find the information required
1873   to define a variable.  It is used for global and static variables.
1874   Basically we need to know the address of the symbol.  With older
1875   versions of the compiler, const symbols are treated differently, in
1876   that if they are global they are written into the text psect.  The
1877   global symbol entry for such a const is actually written as a program
1878   entry point (Yuk!!), so if we cannot find a symbol in the list of
1879   psects, we must search the entry points as well.  static consts are
1880   even harder, since they are never assigned a memory address.  The
1881   compiler passes a stab to tell us the value, but I am not sure what
1882   to do with it.  */
1883
1884static void
1885VMS_stab_parse (symbolS *sp, int expected_type,
1886		int type1, int type2, int Text_Psect)
1887{
1888  char *pnt;
1889  char *pnt1;
1890  char *str;
1891  symbolS *sp1;
1892  struct VMS_DBG_Symbol *spnt;
1893  struct VMS_Symbol *vsp;
1894  int dbx_type;
1895
1896  dbx_type = 0;
1897  str = S_GET_NAME (sp);
1898
1899  pnt = (char *) strchr (str, ':');
1900  if (!pnt)
1901    /* No colon present.  */
1902    return;
1903
1904  /* Save this for later. */
1905  pnt1 = pnt;
1906  pnt++;
1907  if (*pnt == expected_type)
1908    {
1909      pnt = cvt_integer (pnt + 1, &dbx_type);
1910      spnt = find_symbol (dbx_type);
1911      if (!spnt)
1912	return;		/*Dunno what this is*/
1913      /* Now we need to search the symbol table to find the psect and
1914         offset for this variable.  */
1915      *pnt1 = '\0';
1916      vsp = VMS_Symbols;
1917      while (vsp)
1918	{
1919	  pnt = S_GET_NAME (vsp->Symbol);
1920	  if (pnt && *pnt++ == '_'
1921	      /* make sure name is the same and symbol type matches */
1922	      && strcmp (pnt, str) == 0
1923	      && (S_GET_RAW_TYPE (vsp->Symbol) == type1
1924		  || S_GET_RAW_TYPE (vsp->Symbol) == type2))
1925	    break;
1926	  vsp = vsp->Next;
1927	}
1928      if (vsp)
1929	{
1930	  VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str);
1931	  *pnt1 = ':';		/* and restore the string */
1932	  return;
1933	}
1934      /* The symbol was not in the symbol list, but it may be an
1935         "entry point" if it was a constant.  */
1936      for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
1937	{
1938	  /* Dispatch on STAB type.  */
1939	  if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT))
1940	    continue;
1941	  pnt = S_GET_NAME (sp1);
1942	  if (*pnt == '_')
1943	    pnt++;
1944	  if (strcmp (pnt, str) == 0)
1945	    {
1946	      if (!gave_compiler_message && expected_type == 'G')
1947		{
1948		  char *long_const_msg = _("\
1949***Warning - the assembly code generated by the compiler has placed \n\
1950 global constant(s) in the text psect.  These will not be available to \n\
1951 other modules, since this is not the correct way to handle this. You \n\
1952 have two options: 1) get a patched compiler that does not put global \n\
1953 constants in the text psect, or 2) remove the 'const' keyword from \n\
1954 definitions of global variables in your source module(s).  Don't say \n\
1955 I didn't warn you! \n");
1956
1957		  as_tsktsk (long_const_msg);
1958		  gave_compiler_message = 1;
1959		}
1960	      VMS_DBG_record (spnt,
1961			      Text_Psect,
1962			      S_GET_VALUE (sp1),
1963			      str);
1964	      *pnt1 = ':';
1965	      /* Fool assembler to not output this as a routine in the TBT.  */
1966	      pnt1 = S_GET_NAME (sp1);
1967	      *pnt1 = 'L';
1968	      S_SET_NAME (sp1, pnt1);
1969	      return;
1970	    }
1971	}
1972    }
1973
1974  /* ...and restore the string.  */
1975  *pnt1 = ':';
1976}
1977
1978/* Simpler interfaces into VMS_stab_parse().  */
1979
1980static void
1981VMS_GSYM_Parse (symbolS *sp, int Text_Psect)
1982{				/* Global variables */
1983  VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect);
1984}
1985
1986static void
1987VMS_LCSYM_Parse (symbolS *sp, int Text_Psect)
1988{
1989  VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
1990}
1991
1992static void
1993VMS_STSYM_Parse (symbolS *sp, int Text_Psect)
1994{
1995  VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect);
1996}
1997
1998/* For register symbols, we must figure out what range of addresses
1999   within the psect are valid.  We will use the brackets in the stab
2000   directives to give us guidance as to the PC range that this variable
2001   is in scope.  I am still not completely comfortable with this but
2002   as I learn more, I seem to get a better handle on what is going on.
2003   Caveat Emptor.  */
2004
2005static void
2006VMS_RSYM_Parse (symbolS *sp, symbolS *Current_Routine ATTRIBUTE_UNUSED,
2007		int Text_Psect)
2008{
2009  symbolS *symbolP;
2010  struct VMS_DBG_Symbol *spnt;
2011  char *pnt;
2012  char *pnt1;
2013  char *str;
2014  int dbx_type;
2015  int len;
2016  int i = 0;
2017  int bcnt = 0;
2018  int Min_Offset = -1;		/* min PC of validity */
2019  int Max_Offset = 0;		/* max PC of validity */
2020
2021  for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
2022    {
2023      /* Dispatch on STAB type.  */
2024      switch (S_GET_RAW_TYPE (symbolP))
2025	{
2026	case N_LBRAC:
2027	  if (bcnt++ == 0)
2028	    Min_Offset = S_GET_VALUE (symbolP);
2029	  break;
2030	case N_RBRAC:
2031	  if (--bcnt == 0)
2032	    Max_Offset = S_GET_VALUE (symbolP) - 1;
2033	  break;
2034	}
2035      if ((Min_Offset != -1) && (bcnt == 0))
2036	break;
2037      if (S_GET_RAW_TYPE (symbolP) == N_FUN)
2038	{
2039	  pnt = (char *) strchr (S_GET_NAME (symbolP), ':') + 1;
2040	  if (*pnt == 'F' || *pnt == 'f') break;
2041	}
2042    }
2043
2044  /* Check to see that the addresses were defined.  If not, then there
2045     were no brackets in the function, and we must try to search for
2046     the next function.  Since functions can be in any order, we should
2047     search all of the symbol list to find the correct ending address.  */
2048  if (Min_Offset == -1)
2049    {
2050      int Max_Source_Offset;
2051      int This_Offset;
2052
2053      Min_Offset = S_GET_VALUE (sp);
2054      Max_Source_Offset = Min_Offset;	/* just in case no N_SLINEs found */
2055      for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2056	switch (S_GET_RAW_TYPE (symbolP))
2057	  {
2058	  case N_TEXT | N_EXT:
2059	    This_Offset = S_GET_VALUE (symbolP);
2060	    if (This_Offset > Min_Offset && This_Offset < Max_Offset)
2061	      Max_Offset = This_Offset;
2062	    break;
2063	  case N_SLINE:
2064	    This_Offset = S_GET_VALUE (symbolP);
2065	    if (This_Offset > Max_Source_Offset)
2066	      Max_Source_Offset = This_Offset;
2067	    break;
2068	  }
2069      /* If this is the last routine, then we use the PC of the last source
2070         line as a marker of the max PC for which this reg is valid.  */
2071      if (Max_Offset == 0x7fffffff)
2072	Max_Offset = Max_Source_Offset;
2073    }
2074
2075  dbx_type = 0;
2076  str = S_GET_NAME (sp);
2077  if ((pnt = (char *) strchr (str, ':')) == 0)
2078    return;			/* no colon present */
2079  pnt1 = pnt;			/* save this for later*/
2080  pnt++;
2081  if (*pnt != 'r')
2082    return;
2083  pnt = cvt_integer (pnt + 1, &dbx_type);
2084  spnt = find_symbol (dbx_type);
2085  if (!spnt)
2086    return;			/*Dunno what this is yet*/
2087  *pnt1 = '\0';
2088  pnt = fix_name (S_GET_NAME (sp));	/* if there are bad characters in name, convert them */
2089  len = strlen (pnt);
2090  Local[i++] = 25 + len;
2091  Local[i++] = spnt->VMS_type;
2092  Local[i++] = DST_K_VFLAGS_TVS;	/* trailing value specified */
2093  COPY_LONG (&Local[i], 1 + len);	/* relative offset, beyond name */
2094  i += 4;
2095  Local[i++] = len;			/* name length (ascic prefix) */
2096  while (*pnt != '\0')
2097    Local[i++] = *pnt++;
2098  Local[i++] = DST_K_VS_FOLLOWS;	/* value specification follows */
2099  COPY_SHORT (&Local[i], 15);		/* length of rest of record */
2100  i += 2;
2101  Local[i++] = DST_K_VS_ALLOC_SPLIT;	/* split lifetime */
2102  Local[i++] = 1;			/* one binding follows */
2103  VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2104  i = 0;
2105  VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
2106  VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
2107  Local[i++] = DST_K_VALKIND_REG;		/* nested value spec */
2108  COPY_LONG (&Local[i], S_GET_VALUE (sp));
2109  i += 4;
2110  VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2111  *pnt1 = ':';
2112  if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
2113    generate_suffix (spnt, 0);
2114}
2115
2116/* This function examines a structure definition, checking all of the elements
2117   to make sure that all of them are fully defined.  The only thing that we
2118   kick out are arrays of undefined structs, since we do not know how big
2119   they are.  All others we can handle with a normal forward reference.  */
2120
2121static int
2122forward_reference (char *pnt)
2123{
2124  struct VMS_DBG_Symbol *spnt, *spnt1;
2125  int i;
2126
2127  pnt = cvt_integer (pnt + 1, &i);
2128  if (*pnt == ';')
2129    return 0;			/* no forward references */
2130  do
2131    {
2132      pnt = (char *) strchr (pnt, ':');
2133      pnt = cvt_integer (pnt + 1, &i);
2134      spnt = find_symbol (i);
2135      while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
2136	{
2137	  spnt1 = find_symbol (spnt->type2);
2138	  if (spnt->advanced == ARRAY && !spnt1)
2139	    return 1;
2140	  spnt = spnt1;
2141	}
2142      pnt = cvt_integer (pnt + 1, &i);
2143      pnt = cvt_integer (pnt + 1, &i);
2144    } while (*++pnt != ';');
2145  return 0;			/* no forward references found */
2146}
2147
2148/* Used to check a single element of a structure on the final pass.  */
2149
2150static int
2151final_forward_reference (struct VMS_DBG_Symbol *spnt)
2152{
2153  struct VMS_DBG_Symbol *spnt1;
2154
2155  while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
2156    {
2157      spnt1 = find_symbol (spnt->type2);
2158      if (spnt->advanced == ARRAY && !spnt1)
2159	return 1;
2160      spnt = spnt1;
2161    }
2162  return 0;	/* no forward references found */
2163}
2164
2165/* This routine parses the stabs directives to find any definitions of dbx
2166   type numbers.  It makes a note of all of them, creating a structure
2167   element of VMS_DBG_Symbol that describes it.  This also generates the
2168   info for the debugger that describes the struct/union/enum, so that
2169   further references to these data types will be by number
2170
2171   We have to process pointers right away, since there can be references
2172   to them later in the same stabs directive.  We cannot have forward
2173   references to pointers, (but we can have a forward reference to a
2174   pointer to a structure/enum/union) and this is why we process them
2175   immediately.  After we process the pointer, then we search for defs
2176   that are nested even deeper.
2177
2178   8/15/92: We have to process arrays right away too, because there can
2179   be multiple references to identical array types in one structure
2180   definition, and only the first one has the definition.  */
2181
2182static int
2183VMS_typedef_parse (char *str)
2184{
2185  char *pnt;
2186  char *pnt1;
2187  const char *pnt2;
2188  int i;
2189  int dtype;
2190  struct forward_ref *fpnt;
2191  int i1, i2, i3, len;
2192  struct VMS_DBG_Symbol *spnt;
2193  struct VMS_DBG_Symbol *spnt1;
2194
2195  /* check for any nested def's */
2196  pnt = (char *) strchr (str + 1, '=');
2197  if (pnt && str[1] != '*' && (str[1] != 'a' || str[2] != 'r')
2198      && VMS_typedef_parse (pnt) == 1)
2199    return 1;
2200  /* now find dbx_type of entry */
2201  pnt = str - 1;
2202  if (*pnt == 'c')
2203    {				/* check for static constants */
2204      *str = '\0';		/* for now we ignore them */
2205      return 0;
2206    }
2207  while ((*pnt <= '9') && (*pnt >= '0'))
2208    pnt--;
2209  pnt++;			/* and get back to the number */
2210  cvt_integer (pnt, &i1);
2211  spnt = find_symbol (i1);
2212  /* First see if this has been defined already, due to forward reference.  */
2213  if (!spnt)
2214    {
2215      i2 = SYMTYP_HASH (i1);
2216      spnt = xmalloc (sizeof (struct VMS_DBG_Symbol));
2217      spnt->next = VMS_Symbol_type_list[i2];
2218      VMS_Symbol_type_list[i2] = spnt;
2219      spnt->dbx_type = i1;	/* and save the type */
2220      spnt->type2 = spnt->VMS_type = spnt->data_size = 0;
2221      spnt->index_min = spnt->index_max = spnt->struc_numb = 0;
2222    }
2223
2224  /* For structs and unions, do a partial parse, otherwise we sometimes get
2225     circular definitions that are impossible to resolve.  We read enough
2226     info so that any reference to this type has enough info to be resolved.  */
2227
2228  /* Point to character past equal sign.  */
2229  pnt = str + 1;
2230
2231  if (*pnt >= '0' && *pnt <= '9')
2232    {
2233      if (type_check ("void"))
2234	{			/* this is the void symbol */
2235	  *str = '\0';
2236	  spnt->advanced = VOID;
2237	  return 0;
2238	}
2239      if (type_check ("unknown type"))
2240	{
2241	  *str = '\0';
2242	  spnt->advanced = UNKNOWN;
2243	  return 0;
2244	}
2245      pnt1 = cvt_integer (pnt, &i1);
2246      if (i1 != spnt->dbx_type)
2247	{
2248	  spnt->advanced = ALIAS;
2249	  spnt->type2 = i1;
2250	  strcpy (str, pnt1);
2251	  return 0;
2252	}
2253      as_tsktsk (_("debugginer output: %d is an unknown untyped variable."),
2254		 spnt->dbx_type);
2255      return 1;			/* do not know what this is */
2256    }
2257
2258  /* Point to character past equal sign.  */
2259  pnt = str + 1;
2260
2261  switch (*pnt)
2262    {
2263    case 'r':
2264      spnt->advanced = BASIC;
2265      if (type_check ("int"))
2266	{
2267	  spnt->VMS_type = DBG_S_C_SLINT;
2268	  spnt->data_size = 4;
2269	}
2270      else if (type_check ("long int"))
2271	{
2272	  spnt->VMS_type = DBG_S_C_SLINT;
2273	  spnt->data_size = 4;
2274	}
2275      else if (type_check ("unsigned int"))
2276	{
2277	  spnt->VMS_type = DBG_S_C_ULINT;
2278	  spnt->data_size = 4;
2279	}
2280      else if (type_check ("long unsigned int"))
2281	{
2282	  spnt->VMS_type = DBG_S_C_ULINT;
2283	  spnt->data_size = 4;
2284	}
2285      else if (type_check ("short int"))
2286	{
2287	  spnt->VMS_type = DBG_S_C_SSINT;
2288	  spnt->data_size = 2;
2289	}
2290      else if (type_check ("short unsigned int"))
2291	{
2292	  spnt->VMS_type = DBG_S_C_USINT;
2293	  spnt->data_size = 2;
2294	}
2295      else if (type_check ("char"))
2296	{
2297	  spnt->VMS_type = DBG_S_C_SCHAR;
2298	  spnt->data_size = 1;
2299	}
2300      else if (type_check ("signed char"))
2301	{
2302	  spnt->VMS_type = DBG_S_C_SCHAR;
2303	  spnt->data_size = 1;
2304	}
2305      else if (type_check ("unsigned char"))
2306	{
2307	  spnt->VMS_type = DBG_S_C_UCHAR;
2308	  spnt->data_size = 1;
2309	}
2310      else if (type_check ("float"))
2311	{
2312	  spnt->VMS_type = DBG_S_C_REAL4;
2313	  spnt->data_size = 4;
2314	}
2315      else if (type_check ("double"))
2316	{
2317	  spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
2318	  spnt->data_size = 8;
2319	}
2320      else if (type_check ("long double"))
2321	{
2322	  /* same as double, at least for now */
2323	  spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
2324	  spnt->data_size = 8;
2325	}
2326      else if (type_check ("long long int"))
2327	{
2328	  spnt->VMS_type = DBG_S_C_SQUAD;	/* signed quadword */
2329	  spnt->data_size = 8;
2330	}
2331      else if (type_check ("long long unsigned int"))
2332	{
2333	  spnt->VMS_type = DBG_S_C_UQUAD;	/* unsigned quadword */
2334	  spnt->data_size = 8;
2335	}
2336      else if (type_check ("complex float"))
2337	{
2338	  spnt->VMS_type = DBG_S_C_COMPLX4;
2339	  spnt->data_size = 2 * 4;
2340	}
2341      else if (type_check ("complex double"))
2342	{
2343	  spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
2344	  spnt->data_size = 2 * 8;
2345	}
2346      else if (type_check ("complex long double"))
2347	{
2348	  /* same as complex double, at least for now */
2349	  spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
2350	  spnt->data_size = 2 * 8;
2351	}
2352      else
2353	{
2354	  /* Shouldn't get here, but if we do, something
2355	     more substantial ought to be done...  */
2356	  spnt->VMS_type = 0;
2357	  spnt->data_size = 0;
2358	}
2359      if (spnt->VMS_type != 0)
2360	setup_basic_type (spnt);
2361      pnt1 = (char *) strchr (str, ';') + 1;
2362      break;
2363    case 's':
2364    case 'u':
2365      spnt->advanced = (*pnt == 's') ? STRUCT : UNION;
2366      spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2367      pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
2368      if (!final_pass && forward_reference (pnt))
2369	{
2370	  spnt->struc_numb = -1;
2371	  return 1;
2372	}
2373      spnt->struc_numb = ++structure_count;
2374      pnt1--;
2375      pnt = get_struct_name (str);
2376      VMS_Def_Struct (spnt->struc_numb);
2377      i = 0;
2378      for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
2379	if (fpnt->dbx_type == spnt->dbx_type)
2380	  {
2381	    fpnt->resolved = 'Y';
2382	    VMS_Set_Struct (fpnt->struc_numb);
2383	    VMS_Store_Struct (spnt->struc_numb);
2384	    i++;
2385	  }
2386      if (i > 0)
2387	VMS_Set_Struct (spnt->struc_numb);
2388      i = 0;
2389      Local[i++] = 11 + strlen (pnt);
2390      Local[i++] = DBG_S_C_STRUCT_START;
2391      Local[i++] = DST_K_VFLAGS_NOVAL;	/* structure definition only */
2392      COPY_LONG (&Local[i], 0L);	/* hence value is unused */
2393      i += 4;
2394      Local[i++] = strlen (pnt);
2395      pnt2 = pnt;
2396      while (*pnt2 != '\0')
2397	Local[i++] = *pnt2++;
2398      i2 = spnt->data_size * 8;	/* number of bits */
2399      COPY_LONG (&Local[i], i2);
2400      i += 4;
2401      VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2402      i = 0;
2403      if (pnt != symbol_name)
2404	{
2405	  pnt += strlen (pnt);
2406	  /* Replace colon for later.  */
2407	  *pnt = ':';
2408	}
2409
2410      while (*++pnt1 != ';')
2411	{
2412	  pnt = (char *) strchr (pnt1, ':');
2413	  *pnt = '\0';
2414	  pnt2 = pnt1;
2415	  pnt1 = cvt_integer (pnt + 1, &dtype);
2416	  pnt1 = cvt_integer (pnt1 + 1, &i2);
2417	  pnt1 = cvt_integer (pnt1 + 1, &i3);
2418	  spnt1 = find_symbol (dtype);
2419	  len = strlen (pnt2);
2420	  if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM)
2421	      && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0)))
2422	    {			/* bitfield */
2423	      if (USE_BITSTRING_DESCRIPTOR (spnt1))
2424		{
2425		  /* This uses a type descriptor, which doesn't work if
2426		     the enclosing structure has been placed in a register.
2427		     Also, enum bitfields degenerate to simple integers.  */
2428		  int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT
2429				    || spnt1->VMS_type == DBG_S_C_USINT
2430				    || spnt1->VMS_type == DBG_S_C_UCHAR
2431				    || spnt1->VMS_type == DBG_S_C_UQUAD
2432				    || spnt1->advanced == ENUM);
2433		  Apoint = 0;
2434		  fpush (19 + len, 1);
2435		  fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
2436		  fpush (DST_K_VFLAGS_DSC, 1);	/* specified by descriptor */
2437		  fpush (1 + len, 4);	/* relative offset to descriptor */
2438		  fpush (len, 1);		/* length byte (ascic prefix) */
2439		  while (*pnt2 != '\0')	/* name bytes */
2440		    fpush (*pnt2++, 1);
2441		  fpush (i3, 2);	/* dsc length == size of bitfield */
2442					/* dsc type == un?signed bitfield */
2443		  fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
2444		  fpush (DSC_K_CLASS_UBS, 1);	/* dsc class == unaligned bitstring */
2445		  fpush (0x00, 4);		/* dsc pointer == zeroes */
2446		  fpush (i2, 4);	/* start position */
2447		  VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
2448		  Apoint = 0;
2449		}
2450	      else
2451		{
2452		  /* Use a "novel length" type specification, which works
2453		     right for register structures and for enum bitfields
2454		     but results in larger object modules.  */
2455		  Local[i++] = 7 + len;
2456		  Local[i++] = DBG_S_C_ADVANCED_TYPE;	/* type spec follows */
2457		  Local[i++] = DBG_S_C_STRUCT_ITEM;	/* value is a bit offset */
2458		  COPY_LONG (&Local[i], i2);		/* bit offset */
2459		  i += 4;
2460		  Local[i++] = strlen (pnt2);
2461		  while (*pnt2 != '\0')
2462		    Local[i++] = *pnt2++;
2463		  VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2464		  i = 0;
2465		  bitfield_suffix (spnt1, i3);
2466	     }
2467	    }
2468	  else /* Not a bitfield.  */
2469	    {
2470	      /* Check if this is a forward reference.  */
2471	      if (final_pass && final_forward_reference (spnt1))
2472		{
2473		  as_tsktsk (_("debugger output: structure element `%s' has undefined type"),
2474			   pnt2);
2475		  continue;
2476		}
2477	      Local[i++] = 7 + len;
2478	      Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE;
2479	      Local[i++] = DBG_S_C_STRUCT_ITEM;
2480	      COPY_LONG (&Local[i], i2);		/* bit offset */
2481	      i += 4;
2482	      Local[i++] = strlen (pnt2);
2483	      while (*pnt2 != '\0')
2484		Local[i++] = *pnt2++;
2485	      VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2486	      i = 0;
2487	      if (!spnt1)
2488		generate_suffix (spnt1, dtype);
2489	      else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
2490		generate_suffix (spnt1, 0);
2491	    }
2492	}
2493      pnt1++;
2494      Local[i++] = 0x01;	/* length byte */
2495      Local[i++] = DBG_S_C_STRUCT_END;
2496      VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2497      i = 0;
2498      break;
2499    case 'e':
2500      spnt->advanced = ENUM;
2501      spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2502      spnt->struc_numb = ++structure_count;
2503      spnt->data_size = 4;
2504      VMS_Def_Struct (spnt->struc_numb);
2505      i = 0;
2506      for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
2507	if (fpnt->dbx_type == spnt->dbx_type)
2508	  {
2509	    fpnt->resolved = 'Y';
2510	    VMS_Set_Struct (fpnt->struc_numb);
2511	    VMS_Store_Struct (spnt->struc_numb);
2512	    i++;
2513	  }
2514      if (i > 0)
2515	VMS_Set_Struct (spnt->struc_numb);
2516      i = 0;
2517      len = strlen (symbol_name);
2518      Local[i++] = 3 + len;
2519      Local[i++] = DBG_S_C_ENUM_START;
2520      Local[i++] = 4 * 8;		/* enum values are 32 bits */
2521      Local[i++] = len;
2522      pnt2 = symbol_name;
2523      while (*pnt2 != '\0')
2524	Local[i++] = *pnt2++;
2525      VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2526      i = 0;
2527      while (*++pnt != ';')
2528	{
2529	  pnt1 = (char *) strchr (pnt, ':');
2530	  *pnt1++ = '\0';
2531	  pnt1 = cvt_integer (pnt1, &i1);
2532	  len = strlen (pnt);
2533	  Local[i++] = 7 + len;
2534	  Local[i++] = DBG_S_C_ENUM_ITEM;
2535	  Local[i++] = DST_K_VALKIND_LITERAL;
2536	  COPY_LONG (&Local[i], i1);
2537	  i += 4;
2538	  Local[i++] = len;
2539	  pnt2 = pnt;
2540	  while (*pnt != '\0')
2541	    Local[i++] = *pnt++;
2542	  VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2543	  i = 0;
2544	  pnt = pnt1;		/* Skip final semicolon */
2545	}
2546      Local[i++] = 0x01;	/* len byte */
2547      Local[i++] = DBG_S_C_ENUM_END;
2548      VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2549      i = 0;
2550      pnt1 = pnt + 1;
2551      break;
2552    case 'a':
2553      spnt->advanced = ARRAY;
2554      spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2555      pnt = (char *) strchr (pnt, ';');
2556      if (!pnt)
2557	return 1;
2558      pnt1 = cvt_integer (pnt + 1, &spnt->index_min);
2559      pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max);
2560      pnt1 = cvt_integer (pnt1 + 1, &spnt->type2);
2561      pnt = (char *) strchr (str + 1, '=');
2562      if (pnt && VMS_typedef_parse (pnt) == 1)
2563	return 1;
2564      break;
2565    case 'f':
2566      spnt->advanced = FUNCTION;
2567      spnt->VMS_type = DBG_S_C_FUNCTION_ADDR;
2568      /* this masquerades as a basic type*/
2569      spnt->data_size = 4;
2570      pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2571      break;
2572    case '*':
2573      spnt->advanced = POINTER;
2574      spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2575      spnt->data_size = 4;
2576      pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2577      pnt = (char *) strchr (str + 1, '=');
2578      if (pnt && VMS_typedef_parse (pnt) == 1)
2579	return 1;
2580      break;
2581    default:
2582      spnt->advanced = UNKNOWN;
2583      spnt->VMS_type = 0;
2584      as_tsktsk (_("debugger output: %d is an unknown type of variable."),
2585		 spnt->dbx_type);
2586      return 1;			/* unable to decipher */
2587    }
2588  /* This removes the evidence of the definition so that the outer levels
2589     of parsing do not have to worry about it.  */
2590  pnt = str;
2591  while (*pnt1 != '\0')
2592    *pnt++ = *pnt1++;
2593  *pnt = '\0';
2594  return 0;
2595}
2596
2597/* This is the root routine that parses the stabs entries for definitions.
2598   it calls VMS_typedef_parse, which can in turn call itself.  We need to
2599   be careful, since sometimes there are forward references to other symbol
2600   types, and these cannot be resolved until we have completed the parse.
2601
2602   Also check and see if we are using continuation stabs, if we are, then
2603   paste together the entire contents of the stab before we pass it to
2604   VMS_typedef_parse.  */
2605
2606static void
2607VMS_LSYM_Parse (void)
2608{
2609  char *pnt;
2610  char *pnt1;
2611  char *pnt2;
2612  char *str;
2613  char *parse_buffer = 0;
2614  char fixit[10];
2615  int incomplete, pass, incom1;
2616  struct forward_ref *fpnt;
2617  symbolS *sp;
2618
2619  pass = 0;
2620  final_pass = 0;
2621  incomplete = 0;
2622  do
2623    {
2624      incom1 = incomplete;
2625      incomplete = 0;
2626      for (sp = symbol_rootP; sp; sp = symbol_next (sp))
2627	{
2628	  /* Deal with STAB symbols.  */
2629	  if (S_IS_DEBUG (sp))
2630	    {
2631	      /* Dispatch on STAB type.  */
2632	      switch (S_GET_RAW_TYPE (sp))
2633		{
2634		case N_GSYM:
2635		case N_LCSYM:
2636		case N_STSYM:
2637		case N_PSYM:
2638		case N_RSYM:
2639		case N_LSYM:
2640		case N_FUN:	/* Sometimes these contain typedefs. */
2641		  str = S_GET_NAME (sp);
2642		  symbol_name = str;
2643		  pnt = str + strlen (str) - 1;
2644		  if (*pnt == '?')  /* Continuation stab.  */
2645		    {
2646		      symbolS *spnext;
2647		      int tlen = 0;
2648
2649		      spnext = sp;
2650		      do
2651			{
2652			  tlen += strlen (str) - 1;
2653			  spnext = symbol_next (spnext);
2654			  str = S_GET_NAME (spnext);
2655			  pnt = str + strlen (str) - 1;
2656			}
2657		      while (*pnt == '?');
2658
2659		      tlen += strlen (str);
2660		      parse_buffer = xmalloc (tlen + 1);
2661		      strcpy (parse_buffer, S_GET_NAME (sp));
2662		      pnt2 = parse_buffer + strlen (parse_buffer) - 1;
2663		      *pnt2 = '\0';
2664		      spnext = sp;
2665
2666		      do
2667			{
2668			  spnext = symbol_next (spnext);
2669			  str = S_GET_NAME (spnext);
2670			  strcat (pnt2, str);
2671			  pnt2 +=  strlen (str) - 1;
2672			  *str = '\0';  /* Erase this string  */
2673			  /* S_SET_NAME (spnext, str); */
2674			  if (*pnt2 != '?') break;
2675			  *pnt2 = '\0';
2676			}
2677		      while (1);
2678
2679		      str = parse_buffer;
2680		      symbol_name = str;
2681		    }
2682
2683		  if ((pnt = (char *) strchr (str, ':')) != 0)
2684		    {
2685		      *pnt = '\0';
2686		      pnt1 = pnt + 1;
2687		      if ((pnt2 = (char *) strchr (pnt1, '=')) != 0)
2688			incomplete += VMS_typedef_parse (pnt2);
2689		      if (parse_buffer)
2690			{
2691			  /*  At this point the parse buffer should just
2692			      contain name:nn.  If it does not, then we
2693			      are in real trouble.  Anyway, this is always
2694			      shorter than the original line.  */
2695			  pnt2 = S_GET_NAME (sp);
2696			  strcpy (pnt2, parse_buffer);
2697			  /* S_SET_NAME (sp, pnt2); */
2698			  free (parse_buffer),  parse_buffer = 0;
2699			}
2700		      /* Put back colon to restore dbx_type.  */
2701		      *pnt = ':';
2702		    }
2703		  break;
2704		}
2705	    }
2706	}
2707      pass++;
2708
2709      /* Make one last pass, if needed, and define whatever we can
2710         that is left.  */
2711      if (final_pass == 0 && incomplete == incom1)
2712	{
2713	  final_pass = 1;
2714	  incom1++;	/* Force one last pass through.  */
2715	}
2716    }
2717  while (incomplete != 0 && incomplete != incom1);
2718
2719  if (incomplete != 0)
2720    as_tsktsk (_("debugger output: Unable to resolve %d circular references."),
2721	       incomplete);
2722
2723  fpnt = f_ref_root;
2724  symbol_name = "\0";
2725  while (fpnt)
2726    {
2727      if (fpnt->resolved != 'Y')
2728	{
2729	  if (find_symbol (fpnt->dbx_type))
2730	    {
2731	      as_tsktsk (_("debugger forward reference error, dbx type %d"),
2732			 fpnt->dbx_type);
2733	      break;
2734	    }
2735	  fixit[0] = 0;
2736	  sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type);
2737	  pnt2 = (char *) strchr (&fixit[1], '=');
2738	  VMS_typedef_parse (pnt2);
2739	}
2740      fpnt = fpnt->next;
2741    }
2742}
2743
2744static void
2745Define_Local_Symbols (symbolS *s0P, symbolS *s2P, symbolS *Current_Routine,
2746		      int Text_Psect)
2747{
2748  symbolS *s1P;		/* Each symbol from s0P .. s2P (exclusive).  */
2749
2750  for (s1P = symbol_next (s0P); s1P != s2P; s1P = symbol_next (s1P))
2751    {
2752      if (!s1P)
2753	break;		/* and return */
2754      if (S_GET_RAW_TYPE (s1P) == N_FUN)
2755	{
2756	  char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1;
2757	  if (*pnt == 'F' || *pnt == 'f') break;
2758	}
2759      if (!S_IS_DEBUG (s1P))
2760	continue;
2761      /* Dispatch on STAB type.  */
2762      switch (S_GET_RAW_TYPE (s1P))
2763	{
2764	default:
2765	  /* Not left or right brace.  */
2766	  continue;
2767
2768	case N_LSYM:
2769	case N_PSYM:
2770	  VMS_local_stab_Parse (s1P);
2771	  break;
2772
2773	case N_RSYM:
2774	  VMS_RSYM_Parse (s1P, Current_Routine, Text_Psect);
2775	  break;
2776	}
2777    }
2778}
2779
2780/* This function crawls the symbol chain searching for local symbols that
2781   need to be described to the debugger.  When we enter a new scope with
2782   a "{", it creates a new "block", which helps the debugger keep track
2783   of which scope we are currently in.  */
2784
2785static symbolS *
2786Define_Routine (symbolS *s0P, int Level, symbolS *Current_Routine,
2787		int Text_Psect)
2788{
2789  symbolS *s1P;
2790  valueT Offset;
2791  int rcount = 0;
2792
2793  for (s1P = symbol_next (s0P); s1P != 0; s1P = symbol_next (s1P))
2794    {
2795      if (S_GET_RAW_TYPE (s1P) == N_FUN)
2796	{
2797	  char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1;
2798	  if (*pnt == 'F' || *pnt == 'f') break;
2799	}
2800      if (!S_IS_DEBUG (s1P))
2801	continue;
2802      /* Dispatch on STAB type.  */
2803      switch (S_GET_RAW_TYPE (s1P))
2804	{
2805	default:
2806	  continue;
2807
2808	case N_LBRAC:
2809	  if (Level != 0)
2810	    {
2811	      char str[10];
2812	      sprintf (str, "$%d", rcount++);
2813	      VMS_TBT_Block_Begin (s1P, Text_Psect, str);
2814	    }
2815	  /* Side-effect: fully resolve symbol.  */
2816	  Offset = S_GET_VALUE (s1P);
2817	  Define_Local_Symbols (s0P, s1P, Current_Routine, Text_Psect);
2818	  s1P = Define_Routine (s1P, Level + 1, Current_Routine, Text_Psect);
2819	  if (Level != 0)
2820	    VMS_TBT_Block_End (S_GET_VALUE (s1P) - Offset);
2821	  s0P = s1P;
2822	  break;
2823
2824	case N_RBRAC:
2825	  return s1P;
2826	}
2827    }
2828
2829  /* We end up here if there were no brackets in this function.
2830     Define everything.  */
2831  Define_Local_Symbols (s0P, (symbolS *)0, Current_Routine, Text_Psect);
2832  return s1P;
2833}
2834
2835
2836#ifndef VMS
2837#include <sys/types.h>
2838#include <time.h>
2839static void get_VMS_time_on_unix (char *);
2840
2841/* Manufacture a VMS-like time string on a Unix based system.  */
2842static void
2843get_VMS_time_on_unix (char *Now)
2844{
2845  char *pnt;
2846  time_t timeb;
2847
2848  time (&timeb);
2849  pnt = ctime (&timeb);
2850  pnt[3] = 0;
2851  pnt[7] = 0;
2852  pnt[10] = 0;
2853  pnt[16] = 0;
2854  pnt[24] = 0;
2855  sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
2856}
2857#endif /* not VMS */
2858
2859/* Write the MHD (Module Header) records.  */
2860
2861static void
2862Write_VMS_MHD_Records (void)
2863{
2864  const char *cp;
2865  char *cp1;
2866  int i;
2867#ifdef VMS
2868  struct { unsigned short len, mbz; char *ptr; } Descriptor;
2869#endif
2870  char Now[17+1];
2871
2872  /* We are writing a module header record.  */
2873  Set_VMS_Object_File_Record (OBJ_S_C_HDR);
2874  /* MAIN MODULE HEADER RECORD.  */
2875  /* Store record type and header type.  */
2876  PUT_CHAR (OBJ_S_C_HDR);
2877  PUT_CHAR (MHD_S_C_MHD);
2878  /* Structure level is 0.  */
2879  PUT_CHAR (OBJ_S_C_STRLVL);
2880  /* Maximum record size is size of the object record buffer.  */
2881  PUT_SHORT (sizeof (Object_Record_Buffer));
2882
2883  /* FIXME:  module name and version should be user
2884	     specifiable via `.ident' and/or `#pragma ident'.  */
2885
2886  /* Get module name (the FILENAME part of the object file).  */
2887  cp = out_file_name;
2888  cp1 = Module_Name;
2889  while (*cp)
2890    {
2891      if (*cp == ']' || *cp == '>' || *cp == ':' || *cp == '/')
2892	{
2893	  cp1 = Module_Name;
2894	  cp++;
2895	  continue;
2896	}
2897      *cp1++ = TOUPPER (*cp++);
2898    }
2899  *cp1 = '\0';
2900
2901  /* Limit it to 31 characters and store in the object record.  */
2902  while (--cp1 >= Module_Name)
2903    if (*cp1 == '.')
2904      *cp1 = '\0';
2905  if (strlen (Module_Name) > 31)
2906    {
2907      if (flag_hash_long_names)
2908	as_tsktsk (_("Module name truncated: %s\n"), Module_Name);
2909      Module_Name[31] = '\0';
2910    }
2911  PUT_COUNTED_STRING (Module_Name);
2912  /* Module Version is "V1.0".  */
2913  PUT_COUNTED_STRING ("V1.0");
2914  /* Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm".  */
2915#ifndef VMS
2916  get_VMS_time_on_unix (Now);
2917#else /* VMS */
2918  Descriptor.len = sizeof Now - 1;
2919  Descriptor.mbz = 0;		/* type & class unspecified */
2920  Descriptor.ptr = Now;
2921  (void) sys$asctim ((unsigned short *)0, &Descriptor, (long *)0, 0);
2922#endif /* VMS */
2923  for (i = 0; i < 17; i++)
2924    PUT_CHAR (Now[i]);
2925  /* Patch time is "never" (17 zeros).  */
2926  for (i = 0; i < 17; i++)
2927    PUT_CHAR (0);
2928  /* Force this to be a separate output record.  */
2929  Flush_VMS_Object_Record_Buffer ();
2930
2931  /* LANGUAGE PROCESSOR NAME.  */
2932
2933  /* Store record type and header type.  */
2934  PUT_CHAR (OBJ_S_C_HDR);
2935  PUT_CHAR (MHD_S_C_LNM);
2936
2937  /* Store language processor name and version (not a counted string!).
2938     This is normally supplied by the gcc driver for the command line
2939     which invokes gas.  If absent, we fall back to gas's version.  */
2940
2941  cp = compiler_version_string;
2942  if (cp == 0)
2943    {
2944      cp = "GNU AS  V";
2945      while (*cp)
2946	PUT_CHAR (*cp++);
2947      cp = VERSION;
2948    }
2949  while (*cp >= ' ')
2950    PUT_CHAR (*cp++);
2951  /* Force this to be a separate output record.  */
2952  Flush_VMS_Object_Record_Buffer ();
2953}
2954
2955/* Write the EOM (End Of Module) record.  */
2956
2957static void
2958Write_VMS_EOM_Record (int Psect, valueT Offset)
2959{
2960  /* We are writing an end-of-module record
2961     (this assumes that the entry point will always be in a psect
2962     represented by a single byte, which is the case for code in
2963     Text_Psect==0).  */
2964
2965  Set_VMS_Object_File_Record (OBJ_S_C_EOM);
2966  PUT_CHAR (OBJ_S_C_EOM);	/* Record type.  */
2967  PUT_CHAR (0);			/* Error severity level (we ignore it).  */
2968  /* Store the entry point, if it exists.  */
2969  if (Psect >= 0)
2970    {
2971      PUT_CHAR (Psect);
2972      PUT_LONG (Offset);
2973    }
2974  /* Flush the record; this will be our final output.  */
2975  Flush_VMS_Object_Record_Buffer ();
2976}
2977
2978
2979/* This hash routine borrowed from GNU-EMACS, and strengthened slightly
2980   ERY.  */
2981
2982static int
2983hash_string (const char *ptr)
2984{
2985  const unsigned char *p = (unsigned char *) ptr;
2986  const unsigned char *end = p + strlen (ptr);
2987  unsigned char c;
2988  int hash = 0;
2989
2990  while (p != end)
2991    {
2992      c = *p++;
2993      hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
2994    }
2995  return hash;
2996}
2997
2998/* Generate a Case-Hacked VMS symbol name (limited to 31 chars).  */
2999
3000static void
3001VMS_Case_Hack_Symbol (const char *In, char *Out)
3002{
3003  long int init;
3004  long int result;
3005  char *pnt = 0;
3006  char *new_name;
3007  const char *old_name;
3008  int i;
3009  int destructor = 0;		/* Hack to allow for case sens in a destructor.  */
3010  int truncate = 0;
3011  int Case_Hack_Bits = 0;
3012  int Saw_Dollar = 0;
3013  static char Hex_Table[16] =
3014  {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3015
3016  /* Kill any leading "_".  */
3017  if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0')))
3018    In++;
3019
3020  new_name = Out;		/* Save this for later.  */
3021
3022#if 0
3023  if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_'))
3024    destructor = 1;
3025#endif
3026
3027  /* We may need to truncate the symbol, save the hash for later.  */
3028  result = (strlen (In) > 23) ? hash_string (In) : 0;
3029  /* Is there a Psect Attribute to skip?  */
3030  if (HAS_PSECT_ATTRIBUTES (In))
3031    {
3032      /* Yes: Skip it.  */
3033      In += PSECT_ATTRIBUTES_STRING_LENGTH;
3034      while (*In)
3035	{
3036	  if ((In[0] == '$') && (In[1] == '$'))
3037	    {
3038	      In += 2;
3039	      break;
3040	    }
3041	  In++;
3042	}
3043    }
3044
3045  old_name = In;
3046#if 0
3047  if (strlen (In) > 31 && flag_hash_long_names)
3048    as_tsktsk ("Symbol name truncated: %s\n", In);
3049#endif
3050  /* Do the case conversion.  */
3051  /* Maximum of 23 chars */
3052  i = 23;
3053  while (*In && (--i >= 0))
3054    {
3055      Case_Hack_Bits <<= 1;
3056      if (*In == '$')
3057	Saw_Dollar = 1;
3058      if ((destructor == 1) && (i == 21))
3059	Saw_Dollar = 0;
3060
3061      switch (vms_name_mapping)
3062	{
3063	case 0:
3064	  if (ISUPPER (*In))
3065	    {
3066	      *Out++ = *In++;
3067	      Case_Hack_Bits |= 1;
3068	    }
3069	  else
3070	    *Out++ = TOUPPER (*In++);
3071	  break;
3072
3073	case 3:
3074	  *Out++ = *In++;
3075	  break;
3076
3077	case 2:
3078	  if (ISLOWER (*In))
3079	    *Out++ = *In++;
3080	  else
3081	    *Out++ = TOLOWER (*In++);
3082	  break;
3083	}
3084    }
3085  /* If we saw a dollar sign, we don't do case hacking.  */
3086  if (flag_no_hash_mixed_case || Saw_Dollar)
3087    Case_Hack_Bits = 0;
3088
3089  /* If we have more than 23 characters and everything is lowercase
3090     we can insert the full 31 characters.  */
3091  if (*In)
3092    {
3093      /* We have more than 23 characters
3094         If we must add the case hack, then we have truncated the str.  */
3095      pnt = Out;
3096      truncate = 1;
3097      if (Case_Hack_Bits == 0)
3098	{
3099	  /* And so far they are all lower case:
3100	     Check up to 8 more characters
3101	     and ensure that they are lowercase.  */
3102	  for (i = 0; (In[i] != 0) && (i < 8); i++)
3103	    if (ISUPPER (In[i]) && !Saw_Dollar && !flag_no_hash_mixed_case)
3104	      break;
3105
3106	  if (In[i] == 0)
3107	    truncate = 0;
3108
3109	  if ((i == 8) || (In[i] == 0))
3110	    {
3111	      /* They are:  Copy up to 31 characters
3112	         to the output string.  */
3113	      i = 8;
3114	      while ((--i >= 0) && (*In))
3115		switch (vms_name_mapping){
3116		case 0: *Out++ = TOUPPER (*In++);
3117		  break;
3118		case 3: *Out++ = *In++;
3119		  break;
3120		case 2: *Out++ = TOLOWER (*In++);
3121		  break;
3122		}
3123	    }
3124	}
3125    }
3126  /* If there were any uppercase characters in the name we
3127     take on the case hacking string.  */
3128
3129  /* Old behavior for regular GNU-C compiler.  */
3130  if (!flag_hash_long_names)
3131    truncate = 0;
3132  if ((Case_Hack_Bits != 0) || (truncate == 1))
3133    {
3134      if (truncate == 0)
3135	{
3136	  *Out++ = '_';
3137	  for (i = 0; i < 6; i++)
3138	    {
3139	      *Out++ = Hex_Table[Case_Hack_Bits & 0xf];
3140	      Case_Hack_Bits >>= 4;
3141	    }
3142	  *Out++ = 'X';
3143	}
3144      else
3145	{
3146	  Out = pnt;		/* Cut back to 23 characters maximum.  */
3147	  *Out++ = '_';
3148	  for (i = 0; i < 7; i++)
3149	    {
3150	      init = result & 0x01f;
3151	      *Out++ = (init < 10) ? ('0' + init) : ('A' + init - 10);
3152	      result = result >> 5;
3153	    }
3154	}
3155    }
3156  /* Done.  */
3157  *Out = 0;
3158  if (truncate == 1 && flag_hash_long_names && flag_show_after_trunc)
3159    as_tsktsk (_("Symbol %s replaced by %s\n"), old_name, new_name);
3160}
3161
3162
3163/* Scan a symbol name for a psect attribute specification.  */
3164
3165#define GLOBALSYMBOL_BIT	0x10000
3166#define GLOBALVALUE_BIT		0x20000
3167
3168static void
3169VMS_Modify_Psect_Attributes (const char *Name, int *Attribute_Pointer)
3170{
3171  int i;
3172  const char *cp;
3173  int Negate;
3174  static const struct
3175  {
3176    const char *Name;
3177    int Value;
3178  } Attributes[] =
3179  {
3180    {"PIC", GPS_S_M_PIC},
3181    {"LIB", GPS_S_M_LIB},
3182    {"OVR", GPS_S_M_OVR},
3183    {"REL", GPS_S_M_REL},
3184    {"GBL", GPS_S_M_GBL},
3185    {"SHR", GPS_S_M_SHR},
3186    {"EXE", GPS_S_M_EXE},
3187    {"RD", GPS_S_M_RD},
3188    {"WRT", GPS_S_M_WRT},
3189    {"VEC", GPS_S_M_VEC},
3190    {"GLOBALSYMBOL", GLOBALSYMBOL_BIT},
3191    {"GLOBALVALUE", GLOBALVALUE_BIT},
3192    {0, 0}
3193  };
3194
3195  /* Kill leading "_".  */
3196  if (*Name == '_')
3197    Name++;
3198  /* Check for a PSECT attribute list.  */
3199  if (!HAS_PSECT_ATTRIBUTES (Name))
3200    return;
3201  /* Skip the attribute list indicator.  */
3202  Name += PSECT_ATTRIBUTES_STRING_LENGTH;
3203  /* Process the attributes ("_" separated, "$" terminated).  */
3204  while (*Name != '$')
3205    {
3206      /* Assume not negating.  */
3207      Negate = 0;
3208      /* Check for "NO".  */
3209      if ((Name[0] == 'N') && (Name[1] == 'O'))
3210	{
3211	  /* We are negating (and skip the NO).  */
3212	  Negate = 1;
3213	  Name += 2;
3214	}
3215      /* Find the token delimiter.  */
3216      cp = Name;
3217      while (*cp && (*cp != '_') && (*cp != '$'))
3218	cp++;
3219      /* Look for the token in the attribute list.  */
3220      for (i = 0; Attributes[i].Name; i++)
3221	{
3222	  /* If the strings match, set/clear the attr.  */
3223	  if (strncmp (Name, Attributes[i].Name, cp - Name) == 0)
3224	    {
3225	      /* Set or clear.  */
3226	      if (Negate)
3227		*Attribute_Pointer &=
3228		  ~Attributes[i].Value;
3229	      else
3230		*Attribute_Pointer |=
3231		  Attributes[i].Value;
3232	      /* Done.  */
3233	      break;
3234	    }
3235	}
3236      /* Now skip the attribute.  */
3237      Name = cp;
3238      if (*Name == '_')
3239	Name++;
3240    }
3241}
3242
3243
3244#define GBLSYM_REF 0
3245#define GBLSYM_DEF 1
3246#define GBLSYM_VAL 2
3247#define GBLSYM_LCL 4	/* not GBL after all...  */
3248#define GBLSYM_WEAK 8
3249
3250/* Define a global symbol (or possibly a local one).  */
3251
3252static void
3253VMS_Global_Symbol_Spec (const char *Name, int Psect_Number, int Psect_Offset, int Flags)
3254{
3255  char Local[32];
3256
3257  /* We are writing a GSD record.  */
3258  Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3259
3260  /* If the buffer is empty we must insert the GSD record type.  */
3261  if (Object_Record_Offset == 0)
3262    PUT_CHAR (OBJ_S_C_GSD);
3263
3264  /* We are writing a Global (or local) symbol definition subrecord.  */
3265  PUT_CHAR ((Flags & GBLSYM_LCL) != 0 ? GSD_S_C_LSY :
3266	    ((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW);
3267
3268  /* Data type is undefined.  */
3269  PUT_CHAR (0);
3270
3271  /* Switch on Definition/Reference.  */
3272  if ((Flags & GBLSYM_DEF) == 0)
3273    {
3274      /* Reference.  */
3275      PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ? GSY_S_M_REL : 0);
3276      if ((Flags & GBLSYM_LCL) != 0)	/* local symbols have extra field */
3277	PUT_SHORT (Current_Environment);
3278    }
3279  else
3280    {
3281      int sym_flags;
3282
3283      /* Definition
3284         [ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ].  */
3285      sym_flags = GSY_S_M_DEF;
3286      if (Flags & GBLSYM_WEAK)
3287	sym_flags |= GSY_S_M_WEAK;
3288      if ((Flags & GBLSYM_VAL) == 0)
3289	sym_flags |= GSY_S_M_REL;
3290      PUT_SHORT (sym_flags);
3291      if ((Flags & GBLSYM_LCL) != 0)	/* local symbols have extra field */
3292	PUT_SHORT (Current_Environment);
3293
3294      /* Psect Number.  */
3295      if ((Flags & GBLSYM_LCL) == 0 && (unsigned) Psect_Number <= 255)
3296	PUT_CHAR (Psect_Number);
3297      else
3298	PUT_SHORT (Psect_Number);
3299
3300      /* Offset.  */
3301      PUT_LONG (Psect_Offset);
3302    }
3303
3304  /* Finally, the global symbol name.  */
3305  VMS_Case_Hack_Symbol (Name, Local);
3306  PUT_COUNTED_STRING (Local);
3307
3308  /* Flush the buffer if it is more than 75% full.  */
3309  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3310    Flush_VMS_Object_Record_Buffer ();
3311}
3312
3313/* Define an environment to support local symbol references.
3314   This is just to mollify the linker; we don't actually do
3315   anything useful with it.  */
3316
3317static void
3318VMS_Local_Environment_Setup (const char *Env_Name)
3319{
3320  /* We are writing a GSD record.  */
3321  Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3322  /* If the buffer is empty we must insert the GSD record type.  */
3323  if (Object_Record_Offset == 0)
3324    PUT_CHAR (OBJ_S_C_GSD);
3325  /* We are writing an ENV subrecord.  */
3326  PUT_CHAR (GSD_S_C_ENV);
3327
3328  ++Current_Environment;	/* index of environment being defined */
3329
3330  /* ENV$W_FLAGS:  we are defining the next environment.  It's not nested.  */
3331  PUT_SHORT (ENV_S_M_DEF);
3332  /* ENV$W_ENVINDX:  index is always 0 for non-nested definitions.  */
3333  PUT_SHORT (0);
3334
3335  /* ENV$B_NAMLNG + ENV$T_NAME:  environment name in ASCIC format.  */
3336  if (!Env_Name) Env_Name = "";
3337  PUT_COUNTED_STRING ((char *)Env_Name);
3338
3339  /* Flush the buffer if it is more than 75% full.  */
3340  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3341    Flush_VMS_Object_Record_Buffer ();
3342}
3343
3344
3345/* Define a psect.  */
3346
3347static int
3348VMS_Psect_Spec (const char *Name, int Size, enum ps_type Type, struct VMS_Symbol *vsp)
3349{
3350  char Local[32];
3351  int Psect_Attributes;
3352
3353  /* Generate the appropriate PSECT flags given the PSECT type.  */
3354  switch (Type)
3355    {
3356    case ps_TEXT:
3357      /* Text psects are PIC,noOVR,REL,noGBL,SHR,EXE,RD,noWRT.  */
3358      Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE
3359			  |GPS_S_M_RD);
3360      break;
3361    case ps_DATA:
3362      /* Data psects are PIC,noOVR,REL,noGBL,noSHR,noEXE,RD,WRT.  */
3363      Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT);
3364      break;
3365    case ps_COMMON:
3366      /* Common block psects are:  PIC,OVR,REL,GBL,noSHR,noEXE,RD,WRT.  */
3367      Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL
3368			  |GPS_S_M_RD|GPS_S_M_WRT);
3369      break;
3370    case ps_CONST:
3371      /* Const data psects are:  PIC,OVR,REL,GBL,noSHR,noEXE,RD,noWRT.  */
3372      Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL
3373			  |GPS_S_M_RD);
3374      break;
3375    case ps_CTORS:
3376      /* Ctor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT.  */
3377      Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD);
3378      break;
3379    case ps_DTORS:
3380      /* Dtor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT.  */
3381      Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD);
3382      break;
3383    default:
3384      /* impossible */
3385      error (_("Unknown VMS psect type (%ld)"), (long) Type);
3386      break;
3387    }
3388  /* Modify the psect attributes according to any attribute string.  */
3389  if (vsp && S_GET_TYPE (vsp->Symbol) == N_ABS)
3390    Psect_Attributes |= GLOBALVALUE_BIT;
3391  else if (HAS_PSECT_ATTRIBUTES (Name))
3392    VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
3393  /* Check for globalref/def/val.  */
3394  if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3395    {
3396      /* globalvalue symbols were generated before. This code
3397         prevents unsightly psect buildup, and makes sure that
3398         fixup references are emitted correctly.  */
3399      vsp->Psect_Index = -1;	/* to catch errors */
3400      S_SET_TYPE (vsp->Symbol, N_UNDF);		/* make refs work */
3401      return 1;			/* decrement psect counter */
3402    }
3403
3404  if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0)
3405    {
3406      switch (S_GET_RAW_TYPE (vsp->Symbol))
3407	{
3408	case N_UNDF | N_EXT:
3409	  VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3410				  vsp->Psect_Offset, GBLSYM_REF);
3411	  vsp->Psect_Index = -1;
3412	  S_SET_TYPE (vsp->Symbol, N_UNDF);
3413	  /* Return and indicate no psect.  */
3414	  return 1;
3415
3416	case N_DATA | N_EXT:
3417	  VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3418				  vsp->Psect_Offset, GBLSYM_DEF);
3419	  /* In this case we still generate the psect. */
3420	  break;
3421
3422	default:
3423	  as_fatal (_("Globalsymbol attribute for symbol %s was unexpected."),
3424		    Name);
3425	  break;
3426	}
3427    }
3428
3429  /* Clear out the globalref/def stuff.  */
3430  Psect_Attributes &= 0xffff;
3431  /* We are writing a GSD record.  */
3432  Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3433  /* If the buffer is empty we must insert the GSD record type.  */
3434  if (Object_Record_Offset == 0)
3435    PUT_CHAR (OBJ_S_C_GSD);
3436  /* We are writing a PSECT definition subrecord.  */
3437  PUT_CHAR (GSD_S_C_PSC);
3438  /* Psects are always LONGWORD aligned.  */
3439  PUT_CHAR (2);
3440  /* Specify the psect attributes.  */
3441  PUT_SHORT (Psect_Attributes);
3442  /* Specify the allocation.  */
3443  PUT_LONG (Size);
3444  /* Finally, the psect name.  */
3445  VMS_Case_Hack_Symbol (Name, Local);
3446  PUT_COUNTED_STRING (Local);
3447  /* Flush the buffer if it is more than 75% full.  */
3448  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3449    Flush_VMS_Object_Record_Buffer ();
3450  return 0;
3451}
3452
3453
3454/* Given the pointer to a symbol we calculate how big the data at the
3455   symbol is.  We do this by looking for the next symbol (local or global)
3456   which will indicate the start of another datum.  */
3457
3458static offsetT
3459VMS_Initialized_Data_Size (symbolS *s0P, unsigned End_Of_Data)
3460{
3461  symbolS *s1P;
3462  valueT s0P_val = S_GET_VALUE (s0P), s1P_val,
3463	 nearest_val = (valueT) End_Of_Data;
3464
3465  /* Find the nearest symbol what follows this one.  */
3466  for (s1P = symbol_rootP; s1P; s1P = symbol_next (s1P))
3467    {
3468      /* The data type must match.  */
3469      if (S_GET_TYPE (s1P) != N_DATA)
3470	continue;
3471      s1P_val = S_GET_VALUE (s1P);
3472      if (s1P_val > s0P_val && s1P_val < nearest_val)
3473	nearest_val = s1P_val;
3474    }
3475  /* Calculate its size.  */
3476  return (offsetT) (nearest_val - s0P_val);
3477}
3478
3479/* Check symbol names for the Psect hack with a globalvalue, and then
3480   generate globalvalues for those that have it.  */
3481
3482static void
3483VMS_Emit_Globalvalues (unsigned text_siz, unsigned data_siz,
3484		       char *Data_Segment)
3485{
3486  symbolS *sp;
3487  char *stripped_name, *Name;
3488  int Size;
3489  int Psect_Attributes;
3490  int globalvalue;
3491  int typ, abstyp;
3492
3493  /* Scan the symbol table for globalvalues, and emit def/ref when
3494     required.  These will be caught again later and converted to
3495     N_UNDF.  */
3496  for (sp = symbol_rootP; sp; sp = sp->sy_next)
3497    {
3498      typ = S_GET_RAW_TYPE (sp);
3499      abstyp = ((typ & ~N_EXT) == N_ABS);
3500      /* See if this is something we want to look at.  */
3501      if (!abstyp &&
3502	  typ != (N_DATA | N_EXT) &&
3503	  typ != (N_UNDF | N_EXT))
3504	continue;
3505      /* See if this has globalvalue specification.  */
3506      Name = S_GET_NAME (sp);
3507
3508      if (abstyp)
3509	{
3510	  stripped_name = 0;
3511	  Psect_Attributes = GLOBALVALUE_BIT;
3512	}
3513      else if (HAS_PSECT_ATTRIBUTES (Name))
3514	{
3515	  stripped_name = xmalloc (strlen (Name) + 1);
3516	  strcpy (stripped_name, Name);
3517	  Psect_Attributes = 0;
3518	  VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
3519	}
3520      else
3521	continue;
3522
3523      if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3524	{
3525	  switch (typ)
3526	    {
3527	    case N_ABS:
3528	      /* Local symbol references will want
3529		 to have an environment defined.  */
3530	      if (Current_Environment < 0)
3531		VMS_Local_Environment_Setup (".N_ABS");
3532	      VMS_Global_Symbol_Spec (Name, 0,
3533				      S_GET_VALUE (sp),
3534				      GBLSYM_DEF|GBLSYM_VAL|GBLSYM_LCL);
3535	      break;
3536	    case N_ABS | N_EXT:
3537	      VMS_Global_Symbol_Spec (Name, 0,
3538				      S_GET_VALUE (sp),
3539				      GBLSYM_DEF|GBLSYM_VAL);
3540	      break;
3541	    case N_UNDF | N_EXT:
3542	      VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
3543	      break;
3544	    case N_DATA | N_EXT:
3545	      Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
3546	      if (Size > 4)
3547		error (_("Invalid data type for globalvalue"));
3548	      globalvalue = md_chars_to_number (Data_Segment +
3549		     S_GET_VALUE (sp) - text_siz , Size);
3550	      /* Three times for good luck.  The linker seems to get confused
3551	         if there are fewer than three */
3552	      VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
3553	      VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
3554				      GBLSYM_DEF|GBLSYM_VAL);
3555	      VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
3556				      GBLSYM_DEF|GBLSYM_VAL);
3557	      break;
3558	    default:
3559	      as_warn (_("Invalid globalvalue of %s"), stripped_name);
3560	      break;
3561	    }
3562	}
3563
3564      if (stripped_name)
3565	free (stripped_name);
3566    }
3567
3568}
3569
3570
3571/* Define a procedure entry pt/mask.  */
3572
3573static void
3574VMS_Procedure_Entry_Pt (char *Name, int Psect_Number, int Psect_Offset,
3575			int Entry_Mask)
3576{
3577  char Local[32];
3578
3579  /* We are writing a GSD record.  */
3580  Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3581  /* If the buffer is empty we must insert the GSD record type.  */
3582  if (Object_Record_Offset == 0)
3583    PUT_CHAR (OBJ_S_C_GSD);
3584  /* We are writing a Procedure Entry Pt/Mask subrecord.  */
3585  PUT_CHAR (((unsigned) Psect_Number <= 255) ? GSD_S_C_EPM : GSD_S_C_EPMW);
3586  /* Data type is undefined.  */
3587  PUT_CHAR (0);
3588  /* Flags = "RELOCATABLE" and "DEFINED".  */
3589  PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
3590  /* Psect Number.  */
3591  if ((unsigned) Psect_Number <= 255)
3592    PUT_CHAR (Psect_Number);
3593  else
3594    PUT_SHORT (Psect_Number);
3595  /* Offset.  */
3596  PUT_LONG (Psect_Offset);
3597  /* Entry mask.  */
3598  PUT_SHORT (Entry_Mask);
3599  /* Finally, the global symbol name.  */
3600  VMS_Case_Hack_Symbol (Name, Local);
3601  PUT_COUNTED_STRING (Local);
3602  /* Flush the buffer if it is more than 75% full.  */
3603  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3604    Flush_VMS_Object_Record_Buffer ();
3605}
3606
3607
3608/* Set the current location counter to a particular Psect and Offset.  */
3609
3610static void
3611VMS_Set_Psect (int Psect_Index, int Offset, int Record_Type)
3612{
3613  /* We are writing a "Record_Type" record.  */
3614  Set_VMS_Object_File_Record (Record_Type);
3615  /* If the buffer is empty we must insert the record type.  */
3616  if (Object_Record_Offset == 0)
3617    PUT_CHAR (Record_Type);
3618  /* Stack the Psect base + Offset.  */
3619  vms_tir_stack_psect (Psect_Index, Offset, 0);
3620  /* Set relocation base.  */
3621  PUT_CHAR (TIR_S_C_CTL_SETRB);
3622  /* Flush the buffer if it is more than 75% full.  */
3623  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3624    Flush_VMS_Object_Record_Buffer ();
3625}
3626
3627
3628/* Store repeated immediate data in current Psect.  */
3629
3630static void
3631VMS_Store_Repeated_Data (int Repeat_Count, char *Pointer, int Size,
3632			 int Record_Type)
3633{
3634  /* Ignore zero bytes/words/longwords.  */
3635  switch (Size)
3636    {
3637    case 4:
3638      if (Pointer[3] != 0 || Pointer[2] != 0) break;
3639      /* else FALLTHRU */
3640    case 2:
3641      if (Pointer[1] != 0) break;
3642      /* else FALLTHRU */
3643    case 1:
3644      if (Pointer[0] != 0) break;
3645      /* zero value */
3646      return;
3647    default:
3648      break;
3649    }
3650  /* If the data is too big for a TIR_S_C_STO_RIVB sub-record
3651     then we do it manually.  */
3652  if (Size > 255)
3653    {
3654      while (--Repeat_Count >= 0)
3655	VMS_Store_Immediate_Data (Pointer, Size, Record_Type);
3656      return;
3657    }
3658  /* We are writing a "Record_Type" record.  */
3659  Set_VMS_Object_File_Record (Record_Type);
3660  /* If the buffer is empty we must insert record type.  */
3661  if (Object_Record_Offset == 0)
3662    PUT_CHAR (Record_Type);
3663  /* Stack the repeat count.  */
3664  PUT_CHAR (TIR_S_C_STA_LW);
3665  PUT_LONG (Repeat_Count);
3666  /* And now the command and its data.  */
3667  PUT_CHAR (TIR_S_C_STO_RIVB);
3668  PUT_CHAR (Size);
3669  while (--Size >= 0)
3670    PUT_CHAR (*Pointer++);
3671  /* Flush the buffer if it is more than 75% full.  */
3672  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3673    Flush_VMS_Object_Record_Buffer ();
3674}
3675
3676
3677/* Store a Position Independent Reference.  */
3678
3679static void
3680VMS_Store_PIC_Symbol_Reference (symbolS *Symbol, int Offset, int PC_Relative,
3681				int Psect, int Psect_Offset, int Record_Type)
3682{
3683  struct VMS_Symbol *vsp = Symbol->sy_obj;
3684  char Local[32];
3685  int local_sym = 0;
3686
3687  /* We are writing a "Record_Type" record.  */
3688  Set_VMS_Object_File_Record (Record_Type);
3689  /* If the buffer is empty we must insert record type.  */
3690  if (Object_Record_Offset == 0)
3691    PUT_CHAR (Record_Type);
3692  /* Set to the appropriate offset in the Psect.
3693     For a Code reference we need to fix the operand
3694     specifier as well, so back up 1 byte;
3695     for a Data reference we just store HERE.  */
3696  VMS_Set_Psect (Psect,
3697		 PC_Relative ? Psect_Offset - 1 : Psect_Offset,
3698		 Record_Type);
3699  /* Make sure we are still generating a "Record Type" record.  */
3700  if (Object_Record_Offset == 0)
3701    PUT_CHAR (Record_Type);
3702  /* Dispatch on symbol type (so we can stack its value).  */
3703  switch (S_GET_RAW_TYPE (Symbol))
3704    {
3705      /* Global symbol.  */
3706    case N_ABS:
3707      local_sym = 1;
3708      /*FALLTHRU*/
3709    case N_ABS | N_EXT:
3710#ifdef	NOT_VAX_11_C_COMPATIBLE
3711    case N_UNDF | N_EXT:
3712    case N_DATA | N_EXT:
3713#endif	/* NOT_VAX_11_C_COMPATIBLE */
3714    case N_UNDF:
3715    case N_TEXT | N_EXT:
3716      /* Get the symbol name (case hacked).  */
3717      VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local);
3718      /* Stack the global symbol value.  */
3719      if (!local_sym)
3720	{
3721	  PUT_CHAR (TIR_S_C_STA_GBL);
3722	}
3723      else
3724	{
3725	  /* Local symbols have an extra field.  */
3726	  PUT_CHAR (TIR_S_C_STA_LSY);
3727	  PUT_SHORT (Current_Environment);
3728	}
3729      PUT_COUNTED_STRING (Local);
3730      if (Offset)
3731	{
3732	  /* Stack the longword offset.  */
3733	  PUT_CHAR (TIR_S_C_STA_LW);
3734	  PUT_LONG (Offset);
3735	  /* Add the two, leaving the result on the stack.  */
3736	  PUT_CHAR (TIR_S_C_OPR_ADD);
3737	}
3738      break;
3739      /* Uninitialized local data.  */
3740    case N_BSS:
3741      /* Stack the Psect (+offset).  */
3742      vms_tir_stack_psect (vsp->Psect_Index,
3743			   vsp->Psect_Offset + Offset,
3744			   0);
3745      break;
3746      /* Local text.  */
3747    case N_TEXT:
3748      /* Stack the Psect (+offset).  */
3749      vms_tir_stack_psect (vsp->Psect_Index,
3750			   S_GET_VALUE (Symbol) + Offset,
3751			   0);
3752      break;
3753      /* Initialized local or global data.  */
3754    case N_DATA:
3755#ifndef	NOT_VAX_11_C_COMPATIBLE
3756    case N_UNDF | N_EXT:
3757    case N_DATA | N_EXT:
3758#endif	/* NOT_VAX_11_C_COMPATIBLE */
3759      /* Stack the Psect (+offset).  */
3760      vms_tir_stack_psect (vsp->Psect_Index,
3761			   vsp->Psect_Offset + Offset,
3762			   0);
3763      break;
3764    }
3765  /* Store either a code or data reference.  */
3766  PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR);
3767  /* Flush the buffer if it is more than 75% full.  */
3768  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3769    Flush_VMS_Object_Record_Buffer ();
3770}
3771
3772
3773/* Check in the text area for an indirect pc-relative reference
3774   and fix it up with addressing mode 0xff [PC indirect]
3775
3776   THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
3777   PIC CODE GENERATING FIXUP ROUTINE.  */
3778
3779static void
3780VMS_Fix_Indirect_Reference (int Text_Psect, addressT Offset,
3781			    fragS *fragP, fragS *text_frag_root)
3782{
3783  /* The addressing mode byte is 1 byte before the address.  */
3784  Offset--;
3785  /* Is it in THIS frag?  */
3786  if ((Offset < fragP->fr_address) ||
3787      (Offset >= (fragP->fr_address + fragP->fr_fix)))
3788    {
3789      /* We need to search for the fragment containing this
3790         Offset.  */
3791      for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
3792	{
3793	  if ((Offset >= fragP->fr_address) &&
3794	      (Offset < (fragP->fr_address + fragP->fr_fix)))
3795	    break;
3796	}
3797      /* If we couldn't find the frag, things are BAD!  */
3798      if (fragP == 0)
3799	error (_("Couldn't find fixup fragment when checking for indirect reference"));
3800    }
3801  /* Check for indirect PC relative addressing mode.  */
3802  if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff)
3803    {
3804      static char Address_Mode = (char) 0xff;
3805
3806      /* Yes: Store the indirect mode back into the image
3807         to fix up the damage done by STO_PICR.  */
3808      VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR);
3809      VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR);
3810    }
3811}
3812
3813
3814/* If the procedure "main()" exists we have to add the instruction
3815   "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
3816
3817   FIXME:  the macro name `HACK_DEC_C_STARTUP' should be renamed
3818	   to `HACK_VAXCRTL_STARTUP' because Digital's compiler
3819 	   named "DEC C" uses run-time library "DECC$SHR", but this
3820 	   startup code is for "VAXCRTL", the library for Digital's
3821 	   older "VAX C".  Also, this extra code isn't needed for
3822 	   supporting gcc because it already generates the VAXCRTL
3823 	   startup call when compiling main().  The reference to
3824 	   `flag_hash_long_names' looks very suspicious too;
3825 	   probably an old-style command line option was inadvertently
3826 	   overloaded here, then blindly converted into the new one.  */
3827void
3828vms_check_for_main (void)
3829{
3830  symbolS *symbolP;
3831#ifdef	HACK_DEC_C_STARTUP	/* JF */
3832  struct frchain *frchainP;
3833  fragS *fragP;
3834  fragS **prev_fragPP;
3835  struct fix *fixP;
3836  fragS *New_Frag;
3837  int i;
3838#endif	/* HACK_DEC_C_STARTUP */
3839
3840  symbolP = (symbolS *) symbol_find ("_main");
3841  if (symbolP && !S_IS_DEBUG (symbolP) &&
3842      S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
3843    {
3844#ifdef	HACK_DEC_C_STARTUP
3845      if (!flag_hash_long_names)
3846	{
3847#endif
3848	  /* Remember the entry point symbol.  */
3849	  Entry_Point_Symbol = symbolP;
3850#ifdef HACK_DEC_C_STARTUP
3851	}
3852      else
3853	{
3854	  /* Scan all the fragment chains for the one with "_main"
3855	     (Actually we know the fragment from the symbol, but we need
3856	     the previous fragment so we can change its pointer).  */
3857	  frchainP = frchain_root;
3858	  while (frchainP)
3859	    {
3860	      /* Scan all the fragments in this chain, remembering
3861	         the "previous fragment".  */
3862	      prev_fragPP = &frchainP->frch_root;
3863	      fragP = frchainP->frch_root;
3864	      while (fragP && (fragP != frchainP->frch_last))
3865		{
3866		  /* Is this the fragment ?  */
3867		  if (fragP == symbolP->sy_frag)
3868		    {
3869		      /* Yes: Modify the fragment by replacing
3870		         it with a new fragment.  */
3871		      New_Frag =
3872			xmalloc (sizeof (*New_Frag) +
3873				 fragP->fr_fix +
3874				 fragP->fr_var +
3875				 5);
3876		      /* The fragments are the same except
3877		        	that the "fixed" area is larger.  */
3878		      *New_Frag = *fragP;
3879		      New_Frag->fr_fix += 6;
3880		      /* Copy the literal data opening a hole
3881		         2 bytes after "_main" (i.e. just after
3882		         the entry mask).  Into which we place
3883		         the JSB instruction.  */
3884		      New_Frag->fr_literal[0] = fragP->fr_literal[0];
3885		      New_Frag->fr_literal[1] = fragP->fr_literal[1];
3886		      New_Frag->fr_literal[2] = 0x16;	/* Jsb */
3887		      New_Frag->fr_literal[3] = 0xef;
3888		      New_Frag->fr_literal[4] = 0;
3889		      New_Frag->fr_literal[5] = 0;
3890		      New_Frag->fr_literal[6] = 0;
3891		      New_Frag->fr_literal[7] = 0;
3892		      for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++)
3893			New_Frag->fr_literal[i + 6] =
3894			  fragP->fr_literal[i];
3895		      /* Now replace the old fragment with the
3896		         newly generated one.  */
3897		      *prev_fragPP = New_Frag;
3898		      /* Remember the entry point symbol.  */
3899		      Entry_Point_Symbol = symbolP;
3900		      /* Scan the text area fixup structures
3901		         as offsets in the fragment may have changed.  */
3902		      for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
3903			{
3904			  /* Look for references to this fragment.  */
3905			  if (fixP->fx_frag == fragP)
3906			    {
3907			      /* Change the fragment pointer.  */
3908			      fixP->fx_frag = New_Frag;
3909			      /* If the offset is after	the entry mask we need
3910			         to account for the JSB	instruction we just
3911			         inserted.  */
3912			      if (fixP->fx_where >= 2)
3913				fixP->fx_where += 6;
3914			    }
3915			}
3916		      /* Scan the symbols as offsets in the
3917		        fragment may have changed.  */
3918		      for (symbolP = symbol_rootP;
3919			   symbolP;
3920			   symbolP = symbol_next (symbolP))
3921			{
3922			  /* Look for references to this fragment.  */
3923			  if (symbolP->sy_frag == fragP)
3924			    {
3925			      /* Change the fragment pointer.  */
3926			      symbolP->sy_frag = New_Frag;
3927			      /* If the offset is after	the entry mask we need
3928			         to account for the JSB	instruction we just
3929			         inserted.  */
3930			      if (S_GET_VALUE (symbolP) >= 2)
3931				S_SET_VALUE (symbolP,
3932					     S_GET_VALUE (symbolP) + 6);
3933			    }
3934			}
3935		      /*  Make a symbol reference to "_c$main_args" so we
3936			  can get its address inserted into the	JSB
3937			  instruction.  */
3938		      symbolP = xmalloc (sizeof (*symbolP));
3939		      S_SET_NAME (symbolP, "_C$MAIN_ARGS");
3940		      S_SET_TYPE (symbolP, N_UNDF);
3941		      S_SET_OTHER (symbolP, 0);
3942		      S_SET_DESC (symbolP, 0);
3943		      S_SET_VALUE (symbolP, 0);
3944		      symbolP->sy_name_offset = 0;
3945		      symbolP->sy_number = 0;
3946		      symbolP->sy_obj = 0;
3947		      symbolP->sy_frag = New_Frag;
3948		      symbolP->sy_resolved = 0;
3949		      symbolP->sy_resolving = 0;
3950		      /* This actually inserts at the beginning of the list.  */
3951		      symbol_append (symbol_rootP, symbolP,
3952				     &symbol_rootP, &symbol_lastP);
3953
3954		      symbol_rootP = symbolP;
3955		      /* Generate a text fixup structure
3956		         to get "_c$main_args" stored into the
3957		         JSB instruction.  */
3958		      fixP = xmalloc (sizeof (*fixP));
3959		      fixP->fx_frag = New_Frag;
3960		      fixP->fx_where = 4;
3961		      fixP->fx_addsy = symbolP;
3962		      fixP->fx_subsy = 0;
3963		      fixP->fx_offset = 0;
3964		      fixP->fx_size = 4;
3965		      fixP->fx_pcrel = 1;
3966		      fixP->fx_next = text_fix_root;
3967		      text_fix_root = fixP;
3968		      /* Now make sure we exit from the loop.  */
3969		      frchainP = 0;
3970		      break;
3971		    }
3972		  /* Try the next fragment.  */
3973		  prev_fragPP = &fragP->fr_next;
3974		  fragP = fragP->fr_next;
3975		}
3976	      /* Try the next fragment chain.  */
3977	      if (frchainP)
3978		frchainP = frchainP->frch_next;
3979	    }
3980	}
3981#endif /* HACK_DEC_C_STARTUP */
3982    }
3983}
3984
3985
3986/* Beginning of vms_write_object_file().  */
3987
3988static
3989struct vms_obj_state
3990{
3991  /* Next program section index to use.  */
3992  int	psect_number;
3993
3994  /* Psect index for code.  Always ends up #0.  */
3995  int	text_psect;
3996
3997  /* Psect index for initialized static variables.  */
3998  int	data_psect;
3999
4000  /* Psect index for uninitialized static variables.  */
4001  int	bss_psect;
4002
4003  /* Psect index for static constructors.  */
4004  int	ctors_psect;
4005
4006  /* Psect index for static destructors.  */
4007  int	dtors_psect;
4008
4009  /* Number of bytes used for local symbol data.  */
4010  int	local_initd_data_size;
4011
4012  /* Dynamic buffer for initialized data.  */
4013  char *data_segment;
4014
4015} vms_obj_state;
4016
4017#define Psect_Number		vms_obj_state.psect_number
4018#define Text_Psect		vms_obj_state.text_psect
4019#define Data_Psect		vms_obj_state.data_psect
4020#define Bss_Psect		vms_obj_state.bss_psect
4021#define Ctors_Psect		vms_obj_state.ctors_psect
4022#define Dtors_Psect		vms_obj_state.dtors_psect
4023#define Local_Initd_Data_Size	vms_obj_state.local_initd_data_size
4024#define Data_Segment		vms_obj_state.data_segment
4025
4026#define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
4027#define IS_GXX_XTOR(symP) (strncmp (S_GET_NAME (symP), "__GLOBAL_.", 10) == 0)
4028#define XTOR_SIZE 4
4029
4030
4031/* Perform text segment fixups.  */
4032
4033static void
4034vms_fixup_text_section (unsigned text_siz ATTRIBUTE_UNUSED,
4035			struct frag *text_frag_root,
4036			struct frag *data_frag_root)
4037{
4038  fragS *fragP;
4039  struct fix *fixP;
4040  offsetT dif;
4041
4042  /* Scan the text fragments.  */
4043  for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
4044    {
4045      /* Stop if we get to the data fragments.  */
4046      if (fragP == data_frag_root)
4047	break;
4048      /* Ignore fragments with no data.  */
4049      if ((fragP->fr_fix == 0) && (fragP->fr_var == 0))
4050	continue;
4051      /* Go to the appropriate offset in the Text Psect.  */
4052      VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR);
4053      /* Store the "fixed" part.  */
4054      if (fragP->fr_fix)
4055	VMS_Store_Immediate_Data (fragP->fr_literal,
4056				  fragP->fr_fix,
4057				  OBJ_S_C_TIR);
4058      /* Store the "variable" part.  */
4059      if (fragP->fr_var && fragP->fr_offset)
4060	VMS_Store_Repeated_Data (fragP->fr_offset,
4061				 fragP->fr_literal + fragP->fr_fix,
4062				 fragP->fr_var,
4063				 OBJ_S_C_TIR);
4064    }
4065
4066  /* Now we go through the text segment fixups and generate
4067     TIR records to fix up addresses within the Text Psect.  */
4068  for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
4069    {
4070      /* We DO handle the case of "Symbol - Symbol" as
4071	 long as it is in the same segment.  */
4072      if (fixP->fx_subsy && fixP->fx_addsy)
4073	{
4074	  /* They need to be in the same segment.  */
4075	  if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
4076	      S_GET_RAW_TYPE (fixP->fx_addsy))
4077	    error (_("Fixup data addsy and subsy don't have the same type"));
4078	  /* And they need to be in one that we can check the psect on.  */
4079	  if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
4080		    (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
4081	    error (_("Fixup data addsy and subsy don't have an appropriate type"));
4082	  /* This had better not be PC relative!  */
4083	  if (fixP->fx_pcrel)
4084	    error (_("Fixup data is erroneously \"pcrel\""));
4085	  /* Subtract their values to get the difference.  */
4086	  dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
4087	  md_number_to_chars (Local, (valueT)dif, fixP->fx_size);
4088	  /* Now generate the fixup object records;
4089	     set the psect and store the data.  */
4090	  VMS_Set_Psect (Text_Psect,
4091			 fixP->fx_where + fixP->fx_frag->fr_address,
4092			 OBJ_S_C_TIR);
4093	  VMS_Store_Immediate_Data (Local,
4094				    fixP->fx_size,
4095				    OBJ_S_C_TIR);
4096	  continue;
4097	}
4098      /* Size will HAVE to be "long".  */
4099      if (fixP->fx_size != 4)
4100	error (_("Fixup datum is not a longword"));
4101      /* Symbol must be "added" (if it is ever
4102	 subtracted we can fix this assumption).  */
4103      if (fixP->fx_addsy == 0)
4104	error (_("Fixup datum is not \"fixP->fx_addsy\""));
4105      /* Store the symbol value in a PIC fashion.  */
4106      VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
4107				      fixP->fx_offset,
4108				      fixP->fx_pcrel,
4109				      Text_Psect,
4110				    fixP->fx_where + fixP->fx_frag->fr_address,
4111				      OBJ_S_C_TIR);
4112	  /* Check for indirect address reference, which has to be fixed up
4113	     (as the linker will screw it up with TIR_S_C_STO_PICR).  */
4114      if (fixP->fx_pcrel)
4115	VMS_Fix_Indirect_Reference (Text_Psect,
4116				    fixP->fx_where + fixP->fx_frag->fr_address,
4117				    fixP->fx_frag,
4118				    text_frag_root);
4119    }
4120}
4121
4122
4123/* Create a buffer holding the data segment.  */
4124
4125static void
4126synthesize_data_segment (unsigned data_siz, unsigned text_siz,
4127			 struct frag *data_frag_root)
4128{
4129  fragS *fragP;
4130  char *fill_literal;
4131  long fill_size, count, i;
4132
4133  /* Allocate the data segment.  */
4134  Data_Segment = xmalloc (data_siz);
4135
4136  /* Run through the data fragments, filling in the segment.  */
4137  for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
4138    {
4139      i = fragP->fr_address - text_siz;
4140      if (fragP->fr_fix)
4141	memcpy (Data_Segment + i, fragP->fr_literal, fragP->fr_fix);
4142      i += fragP->fr_fix;
4143
4144      if ((fill_size = fragP->fr_var) != 0)
4145	{
4146	  fill_literal = fragP->fr_literal + fragP->fr_fix;
4147	  for (count = fragP->fr_offset; count; count--)
4148	    {
4149	      memcpy (Data_Segment + i, fill_literal, fill_size);
4150	      i += fill_size;
4151	    }
4152	}
4153    }
4154}
4155
4156/* Perform data segment fixups.  */
4157
4158static void
4159vms_fixup_data_section (unsigned int data_siz ATTRIBUTE_UNUSED,
4160			unsigned int text_siz)
4161{
4162  struct VMS_Symbol *vsp;
4163  struct fix *fixP;
4164  symbolS *sp;
4165  addressT fr_address;
4166  offsetT dif;
4167  valueT val;
4168
4169  /* Run through all the data symbols and store the data.  */
4170  for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4171    {
4172      /* Ignore anything other than data symbols.  */
4173      if (S_GET_TYPE (vsp->Symbol) != N_DATA)
4174	continue;
4175      /* Set the Psect + Offset.  */
4176      VMS_Set_Psect (vsp->Psect_Index,
4177		       vsp->Psect_Offset,
4178		       OBJ_S_C_TIR);
4179      /* Store the data.  */
4180      val = S_GET_VALUE (vsp->Symbol);
4181      VMS_Store_Immediate_Data (Data_Segment + val - text_siz,
4182				vsp->Size,
4183				OBJ_S_C_TIR);
4184    }			/* N_DATA symbol loop */
4185
4186  /* Now we go through the data segment fixups and generate
4187     TIR records to fix up addresses within the Data Psects.  */
4188  for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
4189    {
4190      /* Find the symbol for the containing datum.  */
4191      for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4192	{
4193	  /* Only bother with Data symbols.  */
4194	  sp = vsp->Symbol;
4195	  if (S_GET_TYPE (sp) != N_DATA)
4196	    continue;
4197	  /* Ignore symbol if After fixup.  */
4198	  val = S_GET_VALUE (sp);
4199	  fr_address = fixP->fx_frag->fr_address;
4200	  if (val > fixP->fx_where + fr_address)
4201	    continue;
4202	  /* See if the datum is here.  */
4203	  if (val + vsp->Size <= fixP->fx_where + fr_address)
4204	    continue;
4205	  /* We DO handle the case of "Symbol - Symbol" as
4206	     long as it is in the same segment.  */
4207	  if (fixP->fx_subsy && fixP->fx_addsy)
4208	    {
4209	      /* They need to be in the same segment.  */
4210	      if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
4211		  S_GET_RAW_TYPE (fixP->fx_addsy))
4212		error (_("Fixup data addsy and subsy don't have the same type"));
4213	      /* And they need to be in one that we can check the psect on.  */
4214	      if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
4215		  (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
4216		error (_("Fixup data addsy and subsy don't have an appropriate type"));
4217	      /* This had better not be PC relative!  */
4218	      if (fixP->fx_pcrel)
4219		error (_("Fixup data is erroneously \"pcrel\""));
4220	      /* Subtract their values to get the difference.  */
4221	      dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
4222	      md_number_to_chars (Local, (valueT)dif, fixP->fx_size);
4223	      /* Now generate the fixup object records;
4224	         set the psect and store the data.  */
4225	      VMS_Set_Psect (vsp->Psect_Index,
4226			     fr_address + fixP->fx_where
4227				 - val + vsp->Psect_Offset,
4228			     OBJ_S_C_TIR);
4229	      VMS_Store_Immediate_Data (Local,
4230					fixP->fx_size,
4231					OBJ_S_C_TIR);
4232		  break;	/* done with this fixup */
4233		}
4234	  /* Size will HAVE to be "long".  */
4235	  if (fixP->fx_size != 4)
4236	    error (_("Fixup datum is not a longword"));
4237	  /* Symbol must be "added" (if it is ever
4238	     subtracted we can fix this assumption).  */
4239	  if (fixP->fx_addsy == 0)
4240	    error (_("Fixup datum is not \"fixP->fx_addsy\""));
4241	  /* Store the symbol value in a PIC fashion.  */
4242	  VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
4243					  fixP->fx_offset,
4244					  fixP->fx_pcrel,
4245					  vsp->Psect_Index,
4246					  fr_address + fixP->fx_where
4247					      - val + vsp->Psect_Offset,
4248					  OBJ_S_C_TIR);
4249	  /* Done with this fixup.  */
4250	  break;
4251	}
4252    }
4253}
4254
4255/* Perform ctors/dtors segment fixups.  */
4256
4257static void
4258vms_fixup_xtors_section (struct VMS_Symbol *symbols,
4259			 int sect_no ATTRIBUTE_UNUSED)
4260{
4261  struct VMS_Symbol *vsp;
4262
4263  /* Run through all the symbols and store the data.  */
4264  for (vsp = symbols; vsp; vsp = vsp->Next)
4265    {
4266      symbolS *sp;
4267
4268      /* Set relocation base.  */
4269      VMS_Set_Psect (vsp->Psect_Index, vsp->Psect_Offset, OBJ_S_C_TIR);
4270
4271      sp = vsp->Symbol;
4272      /* Stack the Psect base with its offset.  */
4273      VMS_Set_Data (Text_Psect, S_GET_VALUE (sp), OBJ_S_C_TIR, 0);
4274    }
4275  /* Flush the buffer if it is more than 75% full.  */
4276  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4277    Flush_VMS_Object_Record_Buffer ();
4278}
4279
4280
4281/* Define symbols for the linker.  */
4282
4283static void
4284global_symbol_directory (unsigned text_siz, unsigned data_siz)
4285{
4286  fragS *fragP;
4287  symbolS *sp;
4288  struct VMS_Symbol *vsp;
4289  int Globalref, define_as_global_symbol;
4290
4291#if 0
4292  /* The g++ compiler does not write out external references to
4293     vtables correctly.  Check for this and holler if we see it
4294     happening.  If that compiler bug is ever fixed we can remove
4295     this.
4296
4297     (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
4298
4299     This was reportedly fixed as of June 2, 1998.   */
4300
4301  for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4302    if (S_GET_RAW_TYPE (sp) == N_UNDF && IS_GXX_VTABLE (sp))
4303      {
4304	S_SET_TYPE (sp, N_UNDF | N_EXT);
4305	S_SET_OTHER (sp, 1);
4306	as_warn (_("g++ wrote an extern reference to `%s' as a routine.\nI will fix it, but I hope that it was note really a routine."),
4307		 S_GET_NAME (sp));
4308      }
4309#endif
4310
4311  /* Now scan the symbols and emit the appropriate GSD records.  */
4312  for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4313    {
4314      define_as_global_symbol = 0;
4315      vsp = 0;
4316      /* Dispatch on symbol type.  */
4317      switch (S_GET_RAW_TYPE (sp))
4318	{
4319
4320	/* Global uninitialized data.  */
4321	case N_UNDF | N_EXT:
4322	  /* Make a VMS data symbol entry.  */
4323	  vsp = xmalloc (sizeof *vsp);
4324	  vsp->Symbol = sp;
4325	  vsp->Size = S_GET_VALUE (sp);
4326	  vsp->Psect_Index = Psect_Number++;
4327	  vsp->Psect_Offset = 0;
4328	  vsp->Next = VMS_Symbols;
4329	  VMS_Symbols = vsp;
4330	  sp->sy_obj = vsp;
4331	  /* Make the psect for this data.  */
4332	  Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
4333				      vsp->Size,
4334				      S_GET_OTHER (sp) ? ps_CONST : ps_COMMON,
4335				      vsp);
4336	  if (Globalref)
4337	    Psect_Number--;
4338#ifdef	NOT_VAX_11_C_COMPATIBLE
4339	  define_as_global_symbol = 1;
4340#else
4341	  /* See if this is an external vtable.  We want to help the
4342	     linker find these things in libraries, so we make a symbol
4343	     reference.  This is not compatible with VAX-C usage for
4344	     variables, but since vtables are only used internally by
4345	     g++, we can get away with this hack.  */
4346	  define_as_global_symbol = IS_GXX_VTABLE (sp);
4347#endif
4348	  break;
4349
4350	/* Local uninitialized data.  */
4351	case N_BSS:
4352	  /* Make a VMS data symbol entry.  */
4353	  vsp = xmalloc (sizeof *vsp);
4354	  vsp->Symbol = sp;
4355	  vsp->Size = 0;
4356	  vsp->Psect_Index = Bss_Psect;
4357	  vsp->Psect_Offset = S_GET_VALUE (sp) - bss_address_frag.fr_address;
4358	  vsp->Next = VMS_Symbols;
4359	  VMS_Symbols = vsp;
4360	  sp->sy_obj = vsp;
4361	  break;
4362
4363	/* Global initialized data.  */
4364	case N_DATA | N_EXT:
4365	  /* Make a VMS data symbol entry.  */
4366	  vsp = xmalloc (sizeof *vsp);
4367	  vsp->Symbol = sp;
4368	  vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
4369	  vsp->Psect_Index = Psect_Number++;
4370	  vsp->Psect_Offset = 0;
4371	  vsp->Next = VMS_Symbols;
4372	  VMS_Symbols = vsp;
4373	  sp->sy_obj = vsp;
4374	  /* Make its psect.  */
4375	  Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
4376				      vsp->Size,
4377				      S_GET_OTHER (sp) ? ps_CONST : ps_COMMON,
4378				      vsp);
4379	  if (Globalref)
4380	    Psect_Number--;
4381#ifdef	NOT_VAX_11_C_COMPATIBLE
4382	  define_as_global_symbol = 1;
4383#else
4384	  /* See N_UNDF|N_EXT above for explanation.  */
4385	  define_as_global_symbol = IS_GXX_VTABLE (sp);
4386#endif
4387	  break;
4388
4389	/* Local initialized data.  */
4390	case N_DATA:
4391	  {
4392	    char *sym_name = S_GET_NAME (sp);
4393
4394	    /* Always suppress local numeric labels.  */
4395	    if (sym_name && strcmp (sym_name, FAKE_LABEL_NAME) == 0)
4396	      break;
4397
4398	    /* Make a VMS data symbol entry.  */
4399	    vsp = xmalloc (sizeof *vsp);
4400	    vsp->Symbol = sp;
4401	    vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
4402	    vsp->Psect_Index = Data_Psect;
4403	    vsp->Psect_Offset = Local_Initd_Data_Size;
4404	    Local_Initd_Data_Size += vsp->Size;
4405	    vsp->Next = VMS_Symbols;
4406	    VMS_Symbols = vsp;
4407	    sp->sy_obj = vsp;
4408	  }
4409	  break;
4410
4411	/* Global Text definition.  */
4412	case N_TEXT | N_EXT:
4413	  {
4414
4415	    if (IS_GXX_XTOR (sp))
4416	      {
4417		vsp = xmalloc (sizeof *vsp);
4418		vsp->Symbol = sp;
4419		vsp->Size = XTOR_SIZE;
4420		sp->sy_obj = vsp;
4421		switch ((S_GET_NAME (sp))[10])
4422		  {
4423		    case 'I':
4424		      vsp->Psect_Index = Ctors_Psect;
4425		      vsp->Psect_Offset = (Ctors_Symbols==0)?0:(Ctors_Symbols->Psect_Offset+XTOR_SIZE);
4426		      vsp->Next = Ctors_Symbols;
4427		      Ctors_Symbols = vsp;
4428		      break;
4429		    case 'D':
4430		      vsp->Psect_Index = Dtors_Psect;
4431		      vsp->Psect_Offset = (Dtors_Symbols==0)?0:(Dtors_Symbols->Psect_Offset+XTOR_SIZE);
4432		      vsp->Next = Dtors_Symbols;
4433		      Dtors_Symbols = vsp;
4434		      break;
4435		    case 'G':
4436		      as_warn (_("Can't handle global xtors symbols yet."));
4437		      break;
4438		    default:
4439		      as_warn (_("Unknown %s"), S_GET_NAME (sp));
4440		      break;
4441		  }
4442	      }
4443	    else
4444	      {
4445		unsigned short Entry_Mask;
4446
4447		/* Get the entry mask.  */
4448		fragP = sp->sy_frag;
4449		/* First frag might be empty if we're generating listings.
4450		   So skip empty rs_fill frags.  */
4451		while (fragP && fragP->fr_type == rs_fill && fragP->fr_fix == 0)
4452		  fragP = fragP->fr_next;
4453
4454		/* If first frag doesn't contain the data, what do we do?
4455		   If it's possibly smaller than two bytes, that would
4456		   imply that the entry mask is not stored where we're
4457		   expecting it.
4458
4459		   If you can find a test case that triggers this, report
4460		   it (and tell me what the entry mask field ought to be),
4461		   and I'll try to fix it.  KR */
4462		if (fragP->fr_fix < 2)
4463		  abort ();
4464
4465		Entry_Mask = (fragP->fr_literal[0] & 0x00ff) |
4466			     ((fragP->fr_literal[1] & 0x00ff) << 8);
4467		/* Define the procedure entry point.  */
4468		VMS_Procedure_Entry_Pt (S_GET_NAME (sp),
4469				    Text_Psect,
4470				    S_GET_VALUE (sp),
4471				    Entry_Mask);
4472	      }
4473	    break;
4474	  }
4475
4476	/* Local Text definition.  */
4477	case N_TEXT:
4478	  /* Make a VMS data symbol entry.  */
4479	  if (Text_Psect != -1)
4480	    {
4481	      vsp = xmalloc (sizeof *vsp);
4482	      vsp->Symbol = sp;
4483	      vsp->Size = 0;
4484	      vsp->Psect_Index = Text_Psect;
4485	      vsp->Psect_Offset = S_GET_VALUE (sp);
4486	      vsp->Next = VMS_Symbols;
4487	      VMS_Symbols = vsp;
4488	      sp->sy_obj = vsp;
4489	    }
4490	  break;
4491
4492	/* Global Reference.  */
4493	case N_UNDF:
4494	  /* Make a GSD global symbol reference record.  */
4495	  VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4496				  0,
4497				  0,
4498				  GBLSYM_REF);
4499	  break;
4500
4501	/* Absolute symbol.  */
4502	case N_ABS:
4503	case N_ABS | N_EXT:
4504	  /* gcc doesn't generate these;
4505	     VMS_Emit_Globalvalue handles them though.	*/
4506	  vsp = xmalloc (sizeof *vsp);
4507	  vsp->Symbol = sp;
4508	  vsp->Size = 4;		/* always assume 32 bits */
4509	  vsp->Psect_Index = 0;
4510	  vsp->Psect_Offset = S_GET_VALUE (sp);
4511	  vsp->Next = VMS_Symbols;
4512	  VMS_Symbols = vsp;
4513	  sp->sy_obj = vsp;
4514	  break;
4515
4516	/* Anything else.  */
4517	default:
4518	  /* Ignore STAB symbols, including .stabs emitted by g++.  */
4519	  if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22))
4520	    break;
4521	  /*
4522	   *	Error otherwise.
4523	   */
4524	  as_tsktsk (_("unhandled stab type %d"), S_GET_TYPE (sp));
4525	  break;
4526	}
4527
4528      /* Global symbols have different linkage than external variables.  */
4529      if (define_as_global_symbol)
4530	VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4531				vsp->Psect_Index,
4532				0,
4533				GBLSYM_DEF);
4534    }
4535}
4536
4537
4538/* Output debugger symbol table information for symbols which
4539   are local to a specific routine.  */
4540
4541static void
4542local_symbols_DST (symbolS *s0P, symbolS *Current_Routine)
4543{
4544  symbolS *s1P;
4545  char *s0P_name, *pnt0, *pnt1;
4546
4547  s0P_name = S_GET_NAME (s0P);
4548  if (*s0P_name++ != '_')
4549    return;
4550
4551  for (s1P = Current_Routine; s1P; s1P = symbol_next (s1P))
4552    {
4553#if 0		/* redundant; RAW_TYPE != N_FUN suffices */
4554      if (!S_IS_DEBUG (s1P))
4555	continue;
4556#endif
4557      if (S_GET_RAW_TYPE (s1P) != N_FUN)
4558	continue;
4559      pnt0 = s0P_name;
4560      pnt1 = S_GET_NAME (s1P);
4561      /* We assume the two strings are never exactly equal...  */
4562      while (*pnt0++ == *pnt1++)
4563	{
4564	}
4565      /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next.
4566	 Note:  both pointers have advanced one past the non-matching char.  */
4567      if ((*pnt1 == 'F' || *pnt1 == 'f') && *--pnt1 == ':' && *--pnt0 == '\0')
4568	{
4569	  Define_Routine (s1P, 0, Current_Routine, Text_Psect);
4570	  return;
4571	}
4572    }
4573}
4574
4575/* Construct and output the debug symbol table.  */
4576
4577static void
4578vms_build_DST (unsigned text_siz)
4579{
4580  symbolS *symbolP;
4581  symbolS *Current_Routine = 0;
4582  struct input_file *Cur_File = 0;
4583  offsetT Cur_Offset = -1;
4584  int Cur_Line_Number = 0;
4585  int File_Number = 0;
4586  int Debugger_Offset = 0;
4587  int file_available;
4588  int dsc;
4589  offsetT val;
4590
4591  /* Write the Traceback Begin Module record.  */
4592  VMS_TBT_Module_Begin ();
4593
4594  /* Output debugging info for global variables and static variables
4595     that are not specific to one routine.  We also need to examine
4596     all stabs directives, to find the definitions to all of the
4597     advanced data types, and this is done by VMS_LSYM_Parse.  This
4598     needs to be done before any definitions are output to the object
4599     file, since there can be forward references in the stabs
4600     directives.  When through with parsing, the text of the stabs
4601     directive is altered, with the definitions removed, so that later
4602     passes will see directives as they would be written if the type
4603     were already defined.
4604
4605     We also look for files and include files, and make a list of
4606     them.  We examine the source file numbers to establish the actual
4607     lines that code was generated from, and then generate offsets.  */
4608  VMS_LSYM_Parse ();
4609  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
4610    {
4611      /* Only deal with STAB symbols here.  */
4612      if (!S_IS_DEBUG (symbolP))
4613	continue;
4614      /* Dispatch on STAB type.  */
4615      switch (S_GET_RAW_TYPE (symbolP))
4616	{
4617	case N_SLINE:
4618	  dsc = S_GET_DESC (symbolP);
4619	  if (dsc > Cur_File->max_line)
4620	    Cur_File->max_line = dsc;
4621	  if (dsc < Cur_File->min_line)
4622	    Cur_File->min_line = dsc;
4623	  break;
4624	case N_SO:
4625	  Cur_File = find_file (symbolP);
4626	  Cur_File->flag = 1;
4627	  Cur_File->min_line = 1;
4628	  break;
4629	case N_SOL:
4630	  Cur_File = find_file (symbolP);
4631	  break;
4632	case N_GSYM:
4633	  VMS_GSYM_Parse (symbolP, Text_Psect);
4634	  break;
4635	case N_LCSYM:
4636	  VMS_LCSYM_Parse (symbolP, Text_Psect);
4637	  break;
4638	case N_FUN:		/* For static constant symbols */
4639	case N_STSYM:
4640	  VMS_STSYM_Parse (symbolP, Text_Psect);
4641	  break;
4642	default:
4643	  break;
4644	}
4645    }
4646
4647  /* Now we take a quick sweep through the files and assign offsets
4648     to each one.  This will essentially be the starting line number to
4649     the debugger for each file.  Output the info for the debugger to
4650     specify the files, and then tell it how many lines to use.  */
4651  for (Cur_File = file_root; Cur_File; Cur_File = Cur_File->next)
4652    {
4653      if (Cur_File->max_line == 0)
4654	continue;
4655      if ((strncmp (Cur_File->name, "GNU_GXX_INCLUDE:", 16) == 0) &&
4656	  !flag_debug)
4657	continue;
4658      if ((strncmp (Cur_File->name, "GNU_CC_INCLUDE:", 15) == 0) &&
4659	  !flag_debug)
4660	continue;
4661      /* show a few extra lines at the start of the region selected */
4662      if (Cur_File->min_line > 2)
4663	Cur_File->min_line -= 2;
4664      Cur_File->offset = Debugger_Offset - Cur_File->min_line + 1;
4665      Debugger_Offset += Cur_File->max_line - Cur_File->min_line + 1;
4666      if (Cur_File->same_file_fpnt)
4667	{
4668	  Cur_File->file_number = Cur_File->same_file_fpnt->file_number;
4669	}
4670      else
4671	{
4672	  Cur_File->file_number = ++File_Number;
4673	  file_available = VMS_TBT_Source_File (Cur_File->name,
4674						Cur_File->file_number);
4675	  if (!file_available)
4676	    {
4677	      Cur_File->file_number = 0;
4678	      File_Number--;
4679	      continue;
4680	    }
4681	}
4682      VMS_TBT_Source_Lines (Cur_File->file_number,
4683			    Cur_File->min_line,
4684			    Cur_File->max_line - Cur_File->min_line + 1);
4685  }			/* for */
4686  Cur_File = (struct input_file *) NULL;
4687
4688  /* Scan the symbols and write out the routines
4689     (this makes the assumption that symbols are in
4690     order of ascending text segment offset).  */
4691  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
4692    {
4693      /* Deal with text symbols.  */
4694      if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
4695	{
4696	  /* Ignore symbols starting with "L", as they are local symbols.  */
4697	  if (*S_GET_NAME (symbolP) == 'L')
4698	    continue;
4699	  /* If there is a routine start defined, terminate it.  */
4700	  if (Current_Routine)
4701	    VMS_TBT_Routine_End (text_siz, Current_Routine);
4702
4703	  /* Check for & skip dummy labels like "gcc_compiled.".
4704	   * They're identified by the IN_DEFAULT_SECTION flag.  */
4705	  if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 &&
4706	      S_GET_VALUE (symbolP) == 0)
4707	    continue;
4708	  /* Store the routine begin traceback info.  */
4709	  VMS_TBT_Routine_Begin (symbolP, Text_Psect);
4710	  Current_Routine = symbolP;
4711	  /* Define symbols local to this routine.  */
4712	  local_symbols_DST (symbolP, Current_Routine);
4713	  /* Done.  */
4714	  continue;
4715
4716	}
4717      /* Deal with STAB symbols.  */
4718      else if (S_IS_DEBUG (symbolP))
4719	{
4720	  /* Dispatch on STAB type.  */
4721	  switch (S_GET_RAW_TYPE (symbolP))
4722	    {
4723	      /* Line number.  */
4724	    case N_SLINE:
4725	      /* Offset the line into the correct portion of the file.  */
4726	      if (Cur_File->file_number == 0)
4727		break;
4728	      val = S_GET_VALUE (symbolP);
4729	      /* Sometimes the same offset gets several source lines
4730		 assigned to it.  We should be selective about which
4731		 lines we allow, we should prefer lines that are in
4732		 the main source file when debugging inline functions.  */
4733	      if (val == Cur_Offset && Cur_File->file_number != 1)
4734		break;
4735
4736	      /* Calculate actual debugger source line.  */
4737	      dsc = S_GET_DESC (symbolP) + Cur_File->offset;
4738	      S_SET_DESC (symbolP, dsc);
4739	      /* Define PC/Line correlation.  */
4740	      if (Cur_Offset == -1)
4741		{
4742		  /* First N_SLINE; set up initial correlation.  */
4743		  VMS_TBT_Line_PC_Correlation (dsc,
4744					       val,
4745					       Text_Psect,
4746					       0);
4747		}
4748	      else if ((dsc - Cur_Line_Number) <= 0)
4749		{
4750		  /* Line delta is not +ve, we need to close the line and
4751		     start a new PC/Line correlation.  */
4752		  VMS_TBT_Line_PC_Correlation (0,
4753					       val - Cur_Offset,
4754					       0,
4755					       -1);
4756		  VMS_TBT_Line_PC_Correlation (dsc,
4757					       val,
4758					       Text_Psect,
4759					       0);
4760		}
4761	      else
4762		{
4763		  /* Line delta is +ve, all is well.  */
4764		  VMS_TBT_Line_PC_Correlation (dsc - Cur_Line_Number,
4765					       val - Cur_Offset,
4766					       0,
4767					       1);
4768		}
4769	      /* Update the current line/PC info.  */
4770	      Cur_Line_Number = dsc;
4771	      Cur_Offset = val;
4772	      break;
4773
4774		/* Source file.  */
4775	    case N_SO:
4776	      /* Remember that we had a source file and emit
4777		 the source file debugger record.  */
4778	      Cur_File = find_file (symbolP);
4779	      break;
4780
4781	    case N_SOL:
4782	      /* We need to make sure that we are really in the actual
4783		 source file when we compute the maximum line number.
4784		 Otherwise the debugger gets really confused.  */
4785	      Cur_File = find_file (symbolP);
4786	      break;
4787
4788	    default:
4789	      break;
4790	    }
4791	}
4792    }
4793
4794    /* If there is a routine start defined, terminate it
4795       (and the line numbers).  */
4796    if (Current_Routine)
4797      {
4798	/* Terminate the line numbers.  */
4799	VMS_TBT_Line_PC_Correlation (0,
4800				     text_siz - S_GET_VALUE (Current_Routine),
4801				     0,
4802				     -1);
4803	/* Terminate the routine.  */
4804	VMS_TBT_Routine_End (text_siz, Current_Routine);
4805      }
4806
4807  /* Write the Traceback End Module TBT record.  */
4808  VMS_TBT_Module_End ();
4809}
4810
4811
4812/* Write a VAX/VMS object file (everything else has been done!).  */
4813
4814void
4815vms_write_object_file (unsigned text_siz, unsigned data_siz, unsigned bss_siz,
4816		       fragS *text_frag_root, fragS *data_frag_root)
4817{
4818  struct VMS_Symbol *vsp;
4819
4820  /* Initialize program section indices; values get updated later.  */
4821  Psect_Number = 0;		/* next Psect Index to use */
4822  Text_Psect = -1;		/* Text Psect Index   */
4823  Data_Psect = -2;		/* Data Psect Index   JF: Was -1 */
4824  Bss_Psect = -3;		/* Bss Psect Index    JF: Was -1 */
4825  Ctors_Psect = -4;		/* Ctors Psect Index  */
4826  Dtors_Psect = -5;		/* Dtors Psect Index  */
4827  /* Initialize other state variables.  */
4828  Data_Segment = 0;
4829  Local_Initd_Data_Size = 0;
4830
4831  /* Create the actual output file and populate it with required
4832     "module header" information.  */
4833  Create_VMS_Object_File ();
4834  Write_VMS_MHD_Records ();
4835
4836  /* Create the Data segment:
4837
4838     Since this is REALLY hard to do any other way,
4839     we actually manufacture the data segment and
4840     then store the appropriate values out of it.
4841     We need to generate this early, so that globalvalues
4842     can be properly emitted.  */
4843  if (data_siz > 0)
4844    synthesize_data_segment (data_siz, text_siz, data_frag_root);
4845
4846  /* Global Symbol Directory.  */
4847
4848  /* Emit globalvalues now.  We must do this before the text psect is
4849     defined, or we will get linker warnings about multiply defined
4850     symbols.  All of the globalvalues "reference" psect 0, although
4851     it really does not have anything to do with it.  */
4852  VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment);
4853  /* Define the Text Psect.  */
4854  Text_Psect = Psect_Number++;
4855  VMS_Psect_Spec ("$code", text_siz, ps_TEXT, 0);
4856  /* Define the BSS Psect.  */
4857  if (bss_siz > 0)
4858    {
4859      Bss_Psect = Psect_Number++;
4860      VMS_Psect_Spec ("$uninitialized_data", bss_siz, ps_DATA, 0);
4861    }
4862  /* Define symbols to the linker.  */
4863  global_symbol_directory (text_siz, data_siz);
4864  /* Define the Data Psect.  */
4865  if (data_siz > 0 && Local_Initd_Data_Size > 0)
4866    {
4867      Data_Psect = Psect_Number++;
4868      VMS_Psect_Spec ("$data", Local_Initd_Data_Size, ps_DATA, 0);
4869      /* Local initialized data (N_DATA) symbols need to be updated to the
4870         proper value of Data_Psect now that it's actually been defined.
4871         (A dummy value was used in global_symbol_directory() above.)  */
4872      for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4873	if (vsp->Psect_Index < 0 && S_GET_RAW_TYPE (vsp->Symbol) == N_DATA)
4874	  vsp->Psect_Index = Data_Psect;
4875    }
4876
4877  if (Ctors_Symbols != 0)
4878    {
4879      char *ps_name = "$ctors";
4880      Ctors_Psect = Psect_Number++;
4881      VMS_Psect_Spec (ps_name, Ctors_Symbols->Psect_Offset + XTOR_SIZE,
4882		      ps_CTORS, 0);
4883      VMS_Global_Symbol_Spec (ps_name, Ctors_Psect,
4884				  0, GBLSYM_DEF|GBLSYM_WEAK);
4885      for (vsp = Ctors_Symbols; vsp; vsp = vsp->Next)
4886	vsp->Psect_Index = Ctors_Psect;
4887    }
4888
4889  if (Dtors_Symbols != 0)
4890    {
4891      char *ps_name = "$dtors";
4892      Dtors_Psect = Psect_Number++;
4893      VMS_Psect_Spec (ps_name, Dtors_Symbols->Psect_Offset + XTOR_SIZE,
4894		      ps_DTORS, 0);
4895      VMS_Global_Symbol_Spec (ps_name, Dtors_Psect,
4896				  0, GBLSYM_DEF|GBLSYM_WEAK);
4897      for (vsp = Dtors_Symbols; vsp; vsp = vsp->Next)
4898	vsp->Psect_Index = Dtors_Psect;
4899    }
4900
4901  /* Text Information and Relocation Records.  */
4902
4903  /* Write the text segment data.  */
4904  if (text_siz > 0)
4905    vms_fixup_text_section (text_siz, text_frag_root, data_frag_root);
4906  /* Write the data segment data, then discard it.  */
4907  if (data_siz > 0)
4908    {
4909      vms_fixup_data_section (data_siz, text_siz);
4910      free (Data_Segment),  Data_Segment = 0;
4911    }
4912
4913  if (Ctors_Symbols != 0)
4914    vms_fixup_xtors_section (Ctors_Symbols, Ctors_Psect);
4915
4916  if (Dtors_Symbols != 0)
4917    vms_fixup_xtors_section (Dtors_Symbols, Dtors_Psect);
4918
4919  /* Debugger Symbol Table Records.  */
4920
4921  vms_build_DST (text_siz);
4922
4923  /* Wrap things up.  */
4924
4925  /* Write the End Of Module record.  */
4926  if (Entry_Point_Symbol)
4927    Write_VMS_EOM_Record (Text_Psect, S_GET_VALUE (Entry_Point_Symbol));
4928  else
4929    Write_VMS_EOM_Record (-1, (valueT) 0);
4930
4931  /* All done, close the object file.  */
4932  Close_VMS_Object_File ();
4933}
4934