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