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.  */
44 extern 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).  */
49 char *compiler_version_string;
50 
51 extern int flag_hash_long_names;	/* -+ */
52 extern int flag_one;			/* -1; compatibility with gcc 1.x */
53 extern int flag_show_after_trunc;	/* -H */
54 extern 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 
67 char vms_name_mapping = 0;
68 
69 static symbolS *Entry_Point_Symbol = 0;	/* Pointer to "_main" */
70 
71 /* We augment the "gas" symbol structure with this.  */
72 
73 struct VMS_Symbol
74 {
75   struct VMS_Symbol *Next;
76   symbolS *Symbol;
77   int Size;
78   int Psect_Index;
79   int Psect_Offset;
80 };
81 
82 struct VMS_Symbol *VMS_Symbols = 0;
83 struct VMS_Symbol *Ctors_Symbols = 0;
84 struct 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 
89 struct 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 
102 static 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().  */
106 enum 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 
114 enum 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 
125 struct 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 
152 struct 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 
159 struct forward_ref
160 {
161   struct forward_ref *next;
162   int dbx_type;
163   int struc_numb;
164   char resolved;
165 };
166 
167 struct 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 
177 static 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 
184 static 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 
190 static 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 
198 static 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 
204 static 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 
212 static 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 
217 static 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
234 static char Local[MAX_DEBUG_RECORD];	/* Buffer for variable descriptor.  */
235 static char Asuffix[MAX_DEBUG_RECORD];	/* Buffer for array descriptor.  */
236 static int Lpnt;		/* Index into Local.  */
237 static int Apoint;		/* Index into Asuffix.  */
238 static char overflow;		/* Flag to indicate we have written too much.  */
239 static 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.  */
245 static int gave_compiler_message = 0;
246 
247 /* Global data (Object records limited to 512 bytes by VAX-11 "C" runtime).  */
248 
249 static int VMS_Object_File_FD;		/* File Descriptor for object file.  */
250 static char Object_Record_Buffer[512];	/* Buffer for object file records.  */
251 static size_t Object_Record_Offset;	/* Offset to end of data.  */
252 static 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 */
300 const 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 
315 const 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 
338 unsigned char const_flag = IN_DEFAULT_SECTION;
339 
340 static void
s_const(int arg)341 s_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 
351 const 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 
359 int
vms_resolve_symbol_redef(symbolS * sym)360 vms_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 
393 void
vms_check_for_special_label(symbolS * symbolP)394 vms_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 
419 void
obj_read_begin_hook(void)420 obj_read_begin_hook (void)
421 {
422 }
423 
424 void
obj_crawl_symbol_chain(object_headers * headers)425 obj_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 
476 static void
Create_VMS_Object_File(void)477 Create_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 
500 static void
Flush_VMS_Object_Record_Buffer(void)501 Flush_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 
539 static void
Set_VMS_Object_File_Record(int Type)540 Set_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 
553 static void
Close_VMS_Object_File(void)554 Close_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 
585 static void
vms_tir_stack_psect(int Psect_Index,int Offset,int Force)586 vms_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 
627 static void
VMS_Store_Immediate_Data(const char * Pointer,int Size,int Record_Type)628 VMS_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 
660 static void
VMS_Set_Data(int Psect_Index,int Offset,int Record_Type,int Force)661 VMS_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 
678 static void
VMS_Store_Struct(int Struct_Index)679 VMS_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 
697 static void
VMS_Def_Struct(int Struct_Index)698 VMS_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 
713 static void
VMS_Set_Struct(int Struct_Index)714 VMS_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 
730 static void
VMS_TBT_Module_Begin(void)731 VMS_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 
760 static void
VMS_TBT_Module_End(void)761 VMS_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 
774 static void
VMS_TBT_Routine_Begin(symbolS * symbolP,int Psect)775 VMS_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 
823 static void
VMS_TBT_Routine_End(int Max_Size,symbolS * sp)824 VMS_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 
869 static void
VMS_TBT_Block_Begin(symbolS * symbolP,int Psect,char * Name)870 VMS_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 
909 static void
VMS_TBT_Block_End(valueT Size)910 VMS_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 
925 static void
VMS_TBT_Line_PC_Correlation(int Line_Number,int Offset,int Psect,int Do_Delta)926 VMS_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 
1032 static int
VMS_TBT_Source_File(char * Filename,int ID_Number)1033 VMS_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 
1132 static void
VMS_TBT_Source_Lines(int ID_Number,int Starting_Line_Number,int Number_Of_Lines)1133 VMS_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 
1187 static struct input_file *
find_file(symbolS * sp)1188 find_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 
1232 static char *
cvt_integer(char * str,int * rtn)1233 cvt_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 
1262 static char *
fix_name(char * pnt)1263 fix_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 
1301 static char *
get_struct_name(char * str)1302 get_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 
1325 static struct VMS_DBG_Symbol *
find_symbol(int dbx_type)1326 find_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 
1348 static void
1349 push (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 
1377 static void
fpush(int value,int size)1378 fpush (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 
1395 static void
rpush(int value,int size)1396 rpush (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 
1415 static void
array_suffix(struct VMS_DBG_Symbol * spnt2)1416 array_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 
1473 static void
new_forward_ref(int dbx_type)1474 new_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 
1496 static int
gen1(struct VMS_DBG_Symbol * spnt,int array_suffix_len)1497 gen1 (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 
1599 static void
generate_suffix(struct VMS_DBG_Symbol * spnt,int dbx_type)1600 generate_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 
1677 static void
bitfield_suffix(struct VMS_DBG_Symbol * spnt,int width)1678 bitfield_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 
1700 static void
setup_basic_type(struct VMS_DBG_Symbol * spnt ATTRIBUTE_UNUSED)1701 setup_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 
1752 static void
VMS_DBG_record(struct VMS_DBG_Symbol * spnt,int Psect,int Offset,char * Name)1753 VMS_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 
1793 static void
VMS_local_stab_Parse(symbolS * sp)1794 VMS_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 
1884 static void
VMS_stab_parse(symbolS * sp,int expected_type,int type1,int type2,int Text_Psect)1885 VMS_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 
1980 static void
VMS_GSYM_Parse(symbolS * sp,int Text_Psect)1981 VMS_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 
1986 static void
VMS_LCSYM_Parse(symbolS * sp,int Text_Psect)1987 VMS_LCSYM_Parse (symbolS *sp, int Text_Psect)
1988 {
1989   VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
1990 }
1991 
1992 static void
VMS_STSYM_Parse(symbolS * sp,int Text_Psect)1993 VMS_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 
2005 static void
VMS_RSYM_Parse(symbolS * sp,symbolS * Current_Routine ATTRIBUTE_UNUSED,int Text_Psect)2006 VMS_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 
2121 static int
forward_reference(char * pnt)2122 forward_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 
2150 static int
final_forward_reference(struct VMS_DBG_Symbol * spnt)2151 final_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 
2182 static int
VMS_typedef_parse(char * str)2183 VMS_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 
2606 static void
VMS_LSYM_Parse(void)2607 VMS_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 
2744 static void
Define_Local_Symbols(symbolS * s0P,symbolS * s2P,symbolS * Current_Routine,int Text_Psect)2745 Define_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 
2785 static symbolS *
Define_Routine(symbolS * s0P,int Level,symbolS * Current_Routine,int Text_Psect)2786 Define_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>
2839 static void get_VMS_time_on_unix (char *);
2840 
2841 /* Manufacture a VMS-like time string on a Unix based system.  */
2842 static void
get_VMS_time_on_unix(char * Now)2843 get_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 
2861 static void
Write_VMS_MHD_Records(void)2862 Write_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 
2957 static void
Write_VMS_EOM_Record(int Psect,valueT Offset)2958 Write_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 
2982 static int
hash_string(const char * ptr)2983 hash_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 
3000 static void
VMS_Case_Hack_Symbol(const char * In,char * Out)3001 VMS_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 
3168 static void
VMS_Modify_Psect_Attributes(const char * Name,int * Attribute_Pointer)3169 VMS_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 
3252 static void
VMS_Global_Symbol_Spec(const char * Name,int Psect_Number,int Psect_Offset,int Flags)3253 VMS_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 
3317 static void
VMS_Local_Environment_Setup(const char * Env_Name)3318 VMS_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 
3347 static int
VMS_Psect_Spec(const char * Name,int Size,enum ps_type Type,struct VMS_Symbol * vsp)3348 VMS_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 
3458 static offsetT
VMS_Initialized_Data_Size(symbolS * s0P,unsigned End_Of_Data)3459 VMS_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 
3482 static void
VMS_Emit_Globalvalues(unsigned text_siz,unsigned data_siz,char * Data_Segment)3483 VMS_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 
3573 static void
VMS_Procedure_Entry_Pt(char * Name,int Psect_Number,int Psect_Offset,int Entry_Mask)3574 VMS_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 
3610 static void
VMS_Set_Psect(int Psect_Index,int Offset,int Record_Type)3611 VMS_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 
3630 static void
VMS_Store_Repeated_Data(int Repeat_Count,char * Pointer,int Size,int Record_Type)3631 VMS_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 
3679 static void
VMS_Store_PIC_Symbol_Reference(symbolS * Symbol,int Offset,int PC_Relative,int Psect,int Psect_Offset,int Record_Type)3680 VMS_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 
3779 static void
VMS_Fix_Indirect_Reference(int Text_Psect,addressT Offset,fragS * fragP,fragS * text_frag_root)3780 VMS_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.  */
3827 void
vms_check_for_main(void)3828 vms_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 
3988 static
3989 struct 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 
4033 static void
vms_fixup_text_section(unsigned text_siz ATTRIBUTE_UNUSED,struct frag * text_frag_root,struct frag * data_frag_root)4034 vms_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 
4125 static void
synthesize_data_segment(unsigned data_siz,unsigned text_siz,struct frag * data_frag_root)4126 synthesize_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 
4158 static void
vms_fixup_data_section(unsigned int data_siz ATTRIBUTE_UNUSED,unsigned int text_siz)4159 vms_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 
4257 static void
vms_fixup_xtors_section(struct VMS_Symbol * symbols,int sect_no ATTRIBUTE_UNUSED)4258 vms_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 
4283 static void
global_symbol_directory(unsigned text_siz,unsigned data_siz)4284 global_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 
4541 static void
local_symbols_DST(symbolS * s0P,symbolS * Current_Routine)4542 local_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 
4577 static void
vms_build_DST(unsigned text_siz)4578 vms_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 
4814 void
vms_write_object_file(unsigned text_siz,unsigned data_siz,unsigned bss_siz,fragS * text_frag_root,fragS * data_frag_root)4815 vms_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