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