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