1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
27 /* What we do if there is a goof. */
28 #define error as_fatal
30 #ifdef HO_VMS /* These are of no use if we are cross assembling. */
31 #include <fab.h> /* Define File Access Block */
32 #include <nam.h> /* Define NAM Block */
33 #include <xab.h> /* Define XAB - all different types*/
36 * Version string of the compiler that produced the code we are
37 * assembling. (And this assembler, if we do not have compiler info.)
39 extern const char version_string
[];
40 char *compiler_version_string
;
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. */
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.
54 char vms_name_mapping
= 0;
57 extern char *strchr ();
59 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
62 * We augment the "gas" symbol structure with this
66 struct VMS_Symbol
*Next
;
67 struct symbol
*Symbol
;
72 struct VMS_Symbol
*VMS_Symbols
= 0;
74 /* We need this to keep track of the various input files, so that we can
75 * give the debugger the correct source line.
80 struct input_file
*next
;
81 struct input_file
*same_file_fpnt
;
91 static struct input_file
*file_root
= (struct input_file
*) NULL
;
94 static struct input_file
*find_file
PARAMS ((symbolS
*));
97 * This enum is used to keep track of the various types of variables that
103 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
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.
113 struct VMS_DBG_Symbol
115 struct VMS_DBG_Symbol
*next
;
116 enum advanced_type advanced
; /* description of what this is */
117 int dbx_type
; /* this record is for this type */
118 int type2
; /* For advanced types this is the type referred to.
119 i.e. the type a pointer points to, or the type
120 of object that makes up an array */
121 int VMS_type
; /* Use this type when generating a variable def */
122 int index_min
; /* used for arrays - this will be present for all */
123 int index_max
; /* entries, but will be meaningless for non-arrays */
124 int data_size
; /* size in bytes of the data type. For an array, this
125 is the size of one element in the array */
126 int struc_numb
; /* Number of the structure/union/enum - used for ref */
129 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
=
130 {(struct VMS_DBG_Symbol
*) NULL
};
133 * We need this structure to keep track of forward references to
134 * struct/union/enum that have not been defined yet. When they are ultimately
135 * defined, then we can go back and generate the TIR commands to make a back
141 struct forward_ref
*next
;
147 struct forward_ref
*f_ref_root
=
148 {(struct forward_ref
*) NULL
};
151 * This routine is used to compare the names of certain types to various
152 * fixed types that are known by the debugger.
154 #define type_check(x) !strcmp( symbol_name , x )
157 * This variable is used to keep track of the name of the symbol we are
158 * working on while we are parsing the stabs directives.
160 static char *symbol_name
;
162 /* We use this counter to assign numbers to all of the structures, unions
163 * and enums that we define. When we actually declare a variable to the
164 * debugger, we can simply do it by number, rather than describing the
165 * whole thing each time.
168 static structure_count
= 0;
170 /* This variable is used to indicate that we are making the last attempt to
171 parse the stabs, and that we should define as much as we can, and ignore
174 static int final_pass
;
176 /* This variable is used to keep track of the current structure number
177 * for a given variable. If this is < 0, that means that the structure
178 * has not yet been defined to the debugger. This is still cool, since
179 * the VMS object language has ways of fixing things up after the fact,
180 * so we just make a note of this, and generate fixups at the end.
182 static int struct_number
;
186 * Variable descriptors are used tell the debugger the data types of certain
187 * more complicated variables (basically anything involving a structure,
188 * union, enum, array or pointer). Some non-pointer variables of the
189 * basic types that the debugger knows about do not require a variable
192 * Since it is impossible to have a variable descriptor longer than 128
193 * bytes by virtue of the way that the VMS object language is set up,
194 * it makes not sense to make the arrays any longer than this, or worrying
195 * about dynamic sizing of the array.
197 * These are the arrays and counters that we use to build a variable
201 #define MAX_DEBUG_RECORD 128
202 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
203 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
204 static int Lpnt
; /* index into Local */
205 static int Apoint
; /* index into Asuffix */
206 static char overflow
; /* flag to indicate we have written too much*/
207 static int total_len
; /* used to calculate the total length of variable
208 descriptor plus array descriptor - used for len byte*/
210 /* Flag if we have told user about finding global constants in the text
212 static gave_compiler_message
= 0;
214 /* A pointer to the current routine that we are working on. */
216 static symbolS
*Current_Routine
;
218 /* The psect number for $code a.k.a. the text section. */
220 static int Text_Psect
;
224 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
226 static int VMS_Object_File_FD
; /* File Descriptor for object file */
227 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
228 static int Object_Record_Offset
;/* Offset to end of data */
229 static int Current_Object_Record_Type
; /* Type of record in above */
232 * Macros for moving data around. Must work on big-endian systems.
234 #ifdef HO_VMS /* These are more efficient for VMS->VMS systems */
235 #define COPY_LONG(dest,val) {*(long *) dest = val; }
236 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
238 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
239 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
242 * Macros for placing data into the object record buffer
245 #define PUT_LONG(val) \
246 { md_number_to_chars(Object_Record_Buffer + \
247 Object_Record_Offset, val, 4); \
248 Object_Record_Offset += 4; }
250 #define PUT_SHORT(val) \
251 { md_number_to_chars(Object_Record_Buffer + \
252 Object_Record_Offset, val, 2); \
253 Object_Record_Offset += 2; }
255 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
257 #define PUT_COUNTED_STRING(cp) {\
258 register char *p = cp; \
259 PUT_CHAR(strlen(p)); \
260 while (*p) PUT_CHAR(*p++);}
263 * Macro for determining if a Name has psect attributes attached
266 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
267 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
269 #define HAS_PSECT_ATTRIBUTES(Name) \
270 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
271 PSECT_ATTRIBUTES_STRING, \
272 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
275 /* in: segT out: N_TYPE bits */
276 const short seg_N_TYPE
[] =
282 N_UNDF
, /* unknown */
286 N_UNDF
, /* bignum/flonum */
287 N_UNDF
, /* difference */
291 N_REGISTER
, /* register */
294 const segT N_TYPE_seg
[N_TYPE
+ 2] =
295 { /* N_TYPE == 0x1E = 32-2 */
296 SEG_UNKNOWN
, /* N_UNDF == 0 */
298 SEG_ABSOLUTE
, /* N_ABS == 2 */
300 SEG_TEXT
, /* N_TEXT == 4 */
302 SEG_DATA
, /* N_DATA == 6 */
304 SEG_BSS
, /* N_BSS == 8 */
306 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
307 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
308 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
309 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
314 /* The following code defines the special types of pseudo-ops that we
325 temp
= get_absolute_expression ();
326 subseg_new (SEG_DATA
, (subsegT
) temp
);
328 demand_empty_rest_of_line ();
334 * Handle .stabX directives, which used to be open-coded.
335 * So much creeping featurism overloaded the semantics that we decided
336 * to put all .stabX thinking in one place. Here.
338 * We try to make any .stabX directive legal. Other people's AS will often
339 * do assembly-time consistency checks: eg assigning meaning to n_type bits
340 * and "protecting" you from setting them to certain values. (They also zero
341 * certain bits before emitting symbols. Tut tut.)
343 * If an expression is not absolute we either gripe or use the relocation
344 * information. Other people's assemblers silently forget information they
345 * don't need and invent information they need that you didn't supply.
347 * .stabX directives always make a symbol table entry. It may be junk if
348 * the rest of your .stabX directive is malformed.
356 #endif /* NO_LISTING */
358 register symbolS
*symbolP
= 0;
359 register char *string
;
362 int goof
; /* TRUE if we have aborted. */
366 * Enter with input_line_pointer pointing past .stabX and any following
369 goof
= 0; /* JF who forgot this?? */
372 string
= demand_copy_C_string (&length
);
374 if (*input_line_pointer
== ',')
375 input_line_pointer
++;
378 as_bad ("I need a comma after symbol's name");
386 * Input_line_pointer->after ','. String->symbol name.
390 symbolP
= symbol_new (string
,
397 S_SET_NAME (symbolP
, NULL
); /* .stabd feature. */
398 S_SET_VALUE (symbolP
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
399 symbolP
->sy_frag
= frag_now
;
403 symbolP
->sy_frag
= &zero_address_frag
;
407 symbolP
->sy_frag
= &zero_address_frag
;
415 if (get_absolute_expression_and_terminator (&longint
) == ',')
416 symbolP
->sy_symbol
.n_type
= saved_type
= longint
;
419 as_bad ("I want a comma after the n_type expression");
421 input_line_pointer
--; /* Backup over a non-',' char. */
427 if (get_absolute_expression_and_terminator (&longint
) == ',')
428 S_SET_OTHER (symbolP
, longint
);
431 as_bad ("I want a comma after the n_other expression");
433 input_line_pointer
--; /* Backup over a non-',' char. */
439 S_SET_DESC (symbolP
, get_absolute_expression ());
440 if (what
== 's' || what
== 'n')
442 if (*input_line_pointer
!= ',')
444 as_bad ("I want a comma after the n_desc expression");
449 input_line_pointer
++;
454 if ((!goof
) && (what
== 's' || what
== 'n'))
456 pseudo_set (symbolP
);
457 symbolP
->sy_symbol
.n_type
= saved_type
;
461 if (listing
&& !goof
)
463 if (symbolP
->sy_symbol
.n_type
== N_SLINE
)
466 listing_source_line(symbolP
->sy_symbol
.n_desc
);
468 else if (symbolP
->sy_symbol
.n_type
== N_SO
469 || symbolP
->sy_symbol
.n_type
== N_SOL
)
471 listing_source_file(string
);
477 ignore_rest_of_line ();
479 demand_empty_rest_of_line ();
480 } /* obj_aout_stab() */
482 const pseudo_typeS obj_pseudo_table
[] =
484 {"stabd", obj_aout_stab
, 'd'},/* stabs */
485 {"stabn", obj_aout_stab
, 'n'},/* stabs */
486 {"stabs", obj_aout_stab
, 's'},/* stabs */
487 {"const", s_const
, 0},
490 }; /* obj_pseudo_table */
493 obj_read_begin_hook ()
496 } /* obj_read_begin_hook() */
499 obj_crawl_symbol_chain (headers
)
500 object_headers
*headers
;
504 int symbol_number
= 0;
506 /* JF deal with forward references first... */
507 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
509 if (symbolP
->sy_forward
)
511 S_SET_VALUE (symbolP
, S_GET_VALUE (symbolP
)
512 + S_GET_VALUE (symbolP
->sy_forward
)
513 + symbolP
->sy_forward
->sy_frag
->fr_address
);
514 symbolP
->sy_forward
= 0;
515 } /* if it has a forward reference */
516 } /* walk the symbol chain */
518 { /* crawl symbol table */
519 register int symbol_number
= 0;
522 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
523 while ((symbolP
= *symbolPP
) != NULL
)
525 S_GET_VALUE (symbolP
) += symbolP
->sy_frag
->fr_address
;
527 /* OK, here is how we decide which symbols go out into the
528 brave new symtab. Symbols that do are:
530 * symbols with no name (stabd's?)
531 * symbols with debug info in their N_TYPE
533 Symbols that don't are:
534 * symbols that are registers
535 * symbols with \1 as their 3rd character (numeric labels)
536 * "local labels" as defined by S_LOCAL_NAME(name)
537 if the -L switch was passed to gas.
539 All other symbols are output. We complain if a deleted
540 symbol was marked external. */
543 if (!S_IS_REGISTER (symbolP
))
545 symbolP
->sy_name_offset
= 0;
546 symbolPP
= &(symbol_next (symbolP
));
550 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
552 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
555 } /* if this symbol should be in the output */
556 } /* for each symbol */
558 H_SET_STRING_SIZE (headers
, string_byte_count
);
559 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
560 } /* crawl symbol table */
562 } /* obj_crawl_symbol_chain() */
565 /****** VMS OBJECT FILE HACKING ROUTINES *******/
569 * Create the VMS object file
572 Create_VMS_Object_File ()
574 #if defined(eunice) || !defined(HO_VMS)
575 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
577 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
578 "mbc=16", "deq=64", "fop=tef", "shr=nil");
583 if (VMS_Object_File_FD
< 0)
585 char Error_Line
[256];
587 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
592 * Initialize object file hacking variables
594 Object_Record_Offset
= 0;
595 Current_Object_Record_Type
= -1;
600 * Flush the object record buffer to the object file
603 Flush_VMS_Object_Record_Buffer ()
609 * If the buffer is empty, we are done
611 if (Object_Record_Offset
== 0)
614 * Write the data to the file
616 #ifndef HO_VMS /* For cross-assembly purposes. */
617 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
618 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
619 #endif /* not HO_VMS */
620 i
= write (VMS_Object_File_FD
,
621 Object_Record_Buffer
,
622 Object_Record_Offset
);
623 if (i
!= Object_Record_Offset
)
624 error ("I/O error writing VMS object file");
625 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
627 /* pad it if needed */
629 if (Object_Record_Offset
& 1 != 0)
630 write (VMS_Object_File_FD
, &zero
, 1);
631 #endif /* not HO_VMS */
633 * The buffer is now empty
635 Object_Record_Offset
= 0;
640 * Declare a particular type of object file record
643 Set_VMS_Object_File_Record (Type
)
647 * If the type matches, we are done
649 if (Type
== Current_Object_Record_Type
)
652 * Otherwise: flush the buffer
654 Flush_VMS_Object_Record_Buffer ();
658 Current_Object_Record_Type
= Type
;
664 * Close the VMS Object file
667 Close_VMS_Object_File ()
669 short int m_one
= -1;
670 #ifndef HO_VMS /* For cross-assembly purposes. */
671 /* Write a 0xffff into the file, which means "End of File" */
672 write (VMS_Object_File_FD
, &m_one
, 2);
673 #endif /* not HO_VMS */
674 close (VMS_Object_File_FD
);
679 * Store immediate data in current Psect
682 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
690 * We are writing a "Record_Type" record
692 Set_VMS_Object_File_Record (Record_Type
);
694 * We can only store 128 bytes at a time
699 * Store a maximum of 128 bytes
701 i
= (Size
> 128) ? 128 : Size
;
704 * If we cannot accommodate this record, flush the
707 if ((Object_Record_Offset
+ i
+ 1) >=
708 sizeof (Object_Record_Buffer
))
709 Flush_VMS_Object_Record_Buffer ();
711 * If the buffer is empty we must insert record type
713 if (Object_Record_Offset
== 0)
714 PUT_CHAR (Record_Type
);
718 PUT_CHAR (-i
& 0xff);
723 PUT_CHAR (*Pointer
++);
725 * Flush the buffer if it is more than 75% full
727 if (Object_Record_Offset
>
728 (sizeof (Object_Record_Buffer
) * 3 / 4))
729 Flush_VMS_Object_Record_Buffer ();
734 * Make a data reference
737 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
744 * We are writing a "Record_Type" record
746 Set_VMS_Object_File_Record (Record_Type
);
748 * If the buffer is empty we must insert the record type
750 if (Object_Record_Offset
== 0)
751 PUT_CHAR (Record_Type
);
753 * Stack the Psect base + Longword Offset
757 if (Psect_Index
> 127)
759 PUT_CHAR (TIR_S_C_STA_WPL
);
760 PUT_SHORT (Psect_Index
);
765 PUT_CHAR (TIR_S_C_STA_PL
);
766 PUT_CHAR (Psect_Index
);
774 PUT_CHAR (TIR_S_C_STA_WPL
);
775 PUT_SHORT (Psect_Index
);
778 else if (Offset
> 127)
780 PUT_CHAR (TIR_S_C_STA_WPW
);
781 PUT_SHORT (Psect_Index
);
786 PUT_CHAR (TIR_S_C_STA_WPB
);
787 PUT_SHORT (Psect_Index
);
792 * Set relocation base
794 PUT_CHAR (TIR_S_C_STO_PIDR
);
796 * Flush the buffer if it is more than 75% full
798 if (Object_Record_Offset
>
799 (sizeof (Object_Record_Buffer
) * 3 / 4))
800 Flush_VMS_Object_Record_Buffer ();
804 * Make a debugger reference to a struct, union or enum.
807 VMS_Store_Struct (int Struct_Index
)
810 * We are writing a "OBJ_S_C_DBG" record
812 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
814 * If the buffer is empty we must insert the record type
816 if (Object_Record_Offset
== 0)
817 PUT_CHAR (OBJ_S_C_DBG
);
818 PUT_CHAR (TIR_S_C_STA_UW
);
819 PUT_SHORT (Struct_Index
);
820 PUT_CHAR (TIR_S_C_CTL_STKDL
);
821 PUT_CHAR (TIR_S_C_STO_L
);
823 * Flush the buffer if it is more than 75% full
825 if (Object_Record_Offset
>
826 (sizeof (Object_Record_Buffer
) * 3 / 4))
827 Flush_VMS_Object_Record_Buffer ();
831 * Make a debugger reference to partially define a struct, union or enum.
834 VMS_Def_Struct (int Struct_Index
)
837 * We are writing a "OBJ_S_C_DBG" record
839 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
841 * If the buffer is empty we must insert the record type
843 if (Object_Record_Offset
== 0)
844 PUT_CHAR (OBJ_S_C_DBG
);
845 PUT_CHAR (TIR_S_C_STA_UW
);
846 PUT_SHORT (Struct_Index
);
847 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
849 * Flush the buffer if it is more than 75% full
851 if (Object_Record_Offset
>
852 (sizeof (Object_Record_Buffer
) * 3 / 4))
853 Flush_VMS_Object_Record_Buffer ();
857 VMS_Set_Struct (int Struct_Index
)
858 { /* see previous functions for comments */
859 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
860 if (Object_Record_Offset
== 0)
861 PUT_CHAR (OBJ_S_C_DBG
);
862 PUT_CHAR (TIR_S_C_STA_UW
);
863 PUT_SHORT (Struct_Index
);
864 PUT_CHAR (TIR_S_C_CTL_STLOC
);
865 if (Object_Record_Offset
>
866 (sizeof (Object_Record_Buffer
) * 3 / 4))
867 Flush_VMS_Object_Record_Buffer ();
871 * Write the Traceback Module Begin record
874 VMS_TBT_Module_Begin ()
876 register char *cp
, *cp1
;
878 char Module_Name
[256];
882 * Get module name (the FILENAME part of the object file)
888 if ((*cp
== ']') || (*cp
== '>') ||
889 (*cp
== ':') || (*cp
== '/'))
895 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
899 * Limit it to 31 characters
901 while (--cp1
>= Module_Name
)
904 if (strlen (Module_Name
) > 31)
907 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
911 * Arrange to store the data locally (leave room for size byte)
917 *cp
++ = DST_S_C_MODBEG
;
923 * Language type == "C"
925 COPY_LONG (cp
, DST_S_C_C
);
928 * Store the module name
930 *cp
++ = strlen (Module_Name
);
935 * Now we can store the record size
940 * Put it into the object record
942 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
947 * Write the Traceback Module End record
950 VMS_TBT_Module_End ()
958 Local
[1] = DST_S_C_MODEND
;
960 * Put it into the object record
962 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
967 * Write the Traceback Routine Begin record
970 VMS_TBT_Routine_Begin (symbolP
, Psect
)
971 struct symbol
*symbolP
;
974 register char *cp
, *cp1
;
981 * Strip the leading "_" from the name
983 Name
= S_GET_NAME (symbolP
);
987 * Get the text psect offset
989 Offset
= S_GET_VALUE (symbolP
);
991 * Calculate the record size
993 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1001 Local
[1] = DST_S_C_RTNBEG
;
1007 * Store the data so far
1009 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1011 * Make sure we are still generating a OBJ_S_C_TBT record
1013 if (Object_Record_Offset
== 0)
1014 PUT_CHAR (OBJ_S_C_TBT
);
1016 * Now get the symbol address
1018 PUT_CHAR (TIR_S_C_STA_WPL
);
1022 * Store the data reference
1024 PUT_CHAR (TIR_S_C_STO_PIDR
);
1026 * Store the counted string as data
1030 Size
= strlen (cp1
) + 1;
1034 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1039 * Write the Traceback Routine End record
1040 * We *must* search the symbol table to find the next routine, since
1041 * the assember has a way of reassembling the symbol table OUT OF ORDER
1042 * Thus the next routine in the symbol list is not necessarily the
1043 * next one in memory. For debugging to work correctly we must know the
1044 * size of the routine.
1047 VMS_TBT_Routine_End (Max_Size
, sp
)
1052 int Size
= 0x7fffffff;
1056 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1058 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1060 if (*S_GET_NAME (symbolP
) == 'L')
1062 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
1063 (S_GET_VALUE (symbolP
) < Size
))
1064 Size
= S_GET_VALUE (symbolP
);
1065 /* check if gcc_compiled. has size of zero */
1066 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
1068 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1069 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1070 Size
= S_GET_VALUE (symbolP
);
1074 if (Size
== 0x7fffffff)
1076 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
1084 Local
[1] = DST_S_C_RTNEND
;
1092 COPY_LONG (&Local
[3], Size
);
1096 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1100 * Write the Traceback Block End record
1103 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1104 struct symbol
*symbolP
;
1108 register char *cp
, *cp1
;
1115 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1121 * Begin Block - We simulate with a phony routine
1123 Local
[1] = DST_S_C_BLKBEG
;
1129 * Store the data so far
1131 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1133 * Make sure we are still generating a OBJ_S_C_DBG record
1135 if (Object_Record_Offset
== 0)
1136 PUT_CHAR (OBJ_S_C_DBG
);
1138 * Now get the symbol address
1140 PUT_CHAR (TIR_S_C_STA_WPL
);
1143 * Get the text psect offset
1145 Offset
= S_GET_VALUE (symbolP
);
1148 * Store the data reference
1150 PUT_CHAR (TIR_S_C_STO_PIDR
);
1152 * Store the counted string as data
1156 Size
= strlen (cp1
) + 1;
1160 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1165 * Write the Traceback Block End record
1168 VMS_TBT_Block_End (int Size
)
1173 * End block - simulate with a phony end routine
1176 Local
[1] = DST_S_C_BLKEND
;
1177 COPY_LONG (&Local
[3], Size
);
1182 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1188 * Write a Line number / PC correlation record
1191 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1201 * If not delta, set our PC/Line number correlation
1208 Local
[0] = 1 + 1 + 2 + 1 + 4;
1210 * Line Number/PC correlation
1212 Local
[1] = DST_S_C_LINE_NUM
;
1216 Local
[2] = DST_S_C_SET_LINE_NUM
;
1217 COPY_SHORT (&Local
[3], Line_Number
- 1);
1221 Local
[5] = DST_S_C_SET_ABS_PC
;
1222 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1224 * Make sure we are still generating a OBJ_S_C_TBT record
1226 if (Object_Record_Offset
== 0)
1227 PUT_CHAR (OBJ_S_C_TBT
);
1230 PUT_CHAR (TIR_S_C_STA_PL
);
1235 PUT_CHAR (TIR_S_C_STA_WPL
);
1239 PUT_CHAR (TIR_S_C_STO_PIDR
);
1241 * Do a PC offset of 0 to register the line number
1244 Local
[1] = DST_S_C_LINE_NUM
;
1245 Local
[2] = 0; /* Increment PC by 0 and register line # */
1246 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1251 * If Delta is negative, terminate the line numbers
1255 Local
[0] = 1 + 1 + 4;
1256 Local
[1] = DST_S_C_LINE_NUM
;
1257 Local
[2] = DST_S_C_TERM_L
;
1258 COPY_LONG (&Local
[3], Offset
);
1259 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1266 * Do a PC/Line delta
1269 *cp
++ = DST_S_C_LINE_NUM
;
1270 if (Line_Number
> 1)
1273 * We need to increment the line number
1275 if (Line_Number
- 1 <= 255)
1277 *cp
++ = DST_S_C_INCR_LINUM
;
1278 *cp
++ = Line_Number
- 1;
1282 *cp
++ = DST_S_C_INCR_LINUM_W
;
1283 COPY_SHORT (cp
, Line_Number
- 1);
1284 cp
+= sizeof (short);
1296 if (Offset
< 0x10000)
1298 *cp
++ = DST_S_C_DELTA_PC_W
;
1299 COPY_SHORT (cp
, Offset
);
1300 cp
+= sizeof (short);
1304 *cp
++ = DST_S_C_DELTA_PC_L
;
1305 COPY_LONG (cp
, Offset
);
1306 cp
+= sizeof (long);
1309 Local
[0] = cp
- (Local
+ 1);
1310 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1316 * Describe a source file to the debugger
1319 VMS_TBT_Source_File (Filename
, ID_Number
)
1323 register char *cp
, *cp1
;
1326 #ifndef HO_VMS /* Used for cross-assembly */
1327 i
= strlen (Filename
);
1329 static struct FAB Fab
;
1330 static struct NAM Nam
;
1331 static struct XABDAT Date_Xab
;
1332 static struct XABFHC File_Header_Xab
;
1333 char Es_String
[255], Rs_String
[255];
1338 Fab
.fab$b_bid
= FAB$C_BID
;
1339 Fab
.fab$b_bln
= sizeof (Fab
);
1340 Fab
.fab$l_nam
= (&Nam
);
1341 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1343 * Setup the Nam block so we can find out the FULL name
1344 * of the source file.
1346 Nam
.nam$b_bid
= NAM$C_BID
;
1347 Nam
.nam$b_bln
= sizeof (Nam
);
1348 Nam
.nam$l_rsa
= Rs_String
;
1349 Nam
.nam$b_rss
= sizeof (Rs_String
);
1350 Nam
.nam$l_esa
= Es_String
;
1351 Nam
.nam$b_ess
= sizeof (Es_String
);
1353 * Setup the Date and File Header Xabs
1355 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1356 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1357 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1358 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1359 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1361 * Get the file information
1363 Fab
.fab$l_fna
= Filename
;
1364 Fab
.fab$b_fns
= strlen (Filename
);
1365 Status
= sys$
open (&Fab
);
1368 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1374 * Calculate the size of the resultant string
1381 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1383 * Source declaration
1385 Local
[1] = DST_S_C_SOURCE
;
1387 * Make formfeeds count as source records
1389 Local
[2] = DST_S_C_SRC_FORMFEED
;
1391 * Declare source file
1393 Local
[3] = DST_S_C_SRC_DECLFILE
;
1394 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1403 COPY_SHORT (cp
, ID_Number
);
1404 cp
+= sizeof (short);
1407 * Creation Date. Unknown, so we fill with zeroes.
1410 cp
+= sizeof (long);
1412 cp
+= sizeof (long);
1417 cp
+= sizeof (long);
1422 cp
+= sizeof (short);
1432 #else /* Use this code when assembling for VMS on a VMS system */
1436 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1437 cp
+= sizeof (long);
1438 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1439 cp
+= sizeof (long);
1443 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1444 cp
+= sizeof (long);
1448 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1449 cp
+= sizeof (short);
1453 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1463 * Library module name (none)
1469 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1475 * Give the number of source lines to the debugger
1478 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1480 int Starting_Line_Number
;
1481 int Number_Of_Lines
;
1489 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1491 * Source declaration
1493 Local
[1] = DST_S_C_SOURCE
;
1498 *cp
++ = DST_S_C_SRC_SETFILE
;
1502 COPY_SHORT (cp
, ID_Number
);
1503 cp
+= sizeof (short);
1507 *cp
++ = DST_S_C_SRC_SETREC_L
;
1508 COPY_LONG (cp
, Starting_Line_Number
);
1509 cp
+= sizeof (long);
1513 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1514 COPY_SHORT (cp
, Number_Of_Lines
);
1515 cp
+= sizeof (short);
1519 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1525 /* This routine locates a file in the list of files. If an entry does not
1526 * exist, one is created. For include files, a new entry is always created
1527 * such that inline functions can be properly debugged. */
1528 static struct input_file
*
1532 struct input_file
*same_file
;
1533 struct input_file
*fpnt
;
1534 same_file
= (struct input_file
*) NULL
;
1535 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1537 if (fpnt
== (struct input_file
*) NULL
)
1539 if (fpnt
->spnt
== sp
)
1542 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1544 if (fpnt
== (struct input_file
*) NULL
)
1546 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1548 if (fpnt
->flag
== 1)
1554 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1555 if (file_root
== (struct input_file
*) NULL
)
1559 struct input_file
*fpnt1
;
1560 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1563 fpnt
->next
= (struct input_file
*) NULL
;
1564 fpnt
->name
= S_GET_NAME (sp
);
1565 fpnt
->min_line
= 0x7fffffff;
1569 fpnt
->file_number
= 0;
1571 fpnt
->same_file_fpnt
= same_file
;
1576 * The following functions and definitions are used to generate object records
1577 * that will describe program variables to the VMS debugger.
1579 * This file contains many of the routines needed to output debugging info into
1580 * the object file that the VMS debugger needs to understand symbols. These
1581 * routines are called very late in the assembly process, and thus we can be
1582 * fairly lax about changing things, since the GSD and the TIR sections have
1583 * already been output.
1587 /* This routine converts a number string into an integer, and stops when it
1588 * sees an invalid character the return value is the address of the character
1589 * just past the last character read. No error is generated.
1592 cvt_integer (str
, rtn
)
1597 neg
= *str
== '-' ? ++str
, -1 : 1;
1598 ival
= 0; /* first get the number of the type for dbx */
1599 while ((*str
<= '9') && (*str
>= '0'))
1600 ival
= 10 * ival
+ *str
++ - '0';
1605 /* this routine fixes the names that are generated by C++, ".this" is a good
1606 * example. The period does not work for the debugger, since it looks like
1607 * the syntax for a structure element, and thus it gets mightily confused
1609 * We also use this to strip the PsectAttribute hack from the name before we
1610 * write a debugger record */
1618 * Kill any leading "_"
1623 * Is there a Psect Attribute to skip??
1625 if (HAS_PSECT_ATTRIBUTES (pnt
))
1630 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1633 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1641 /* Here we fix the .this -> $this conversion */
1642 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1650 /* When defining a structure, this routine is called to find the name of
1651 * the actual structure. It is assumed that str points to the equal sign
1652 * in the definition, and it moves backward until it finds the start of the
1653 * name. If it finds a 0, then it knows that this structure def is in the
1654 * outermost level, and thus symbol_name points to the symbol name.
1657 get_struct_name (str
)
1662 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1667 while ((*pnt
!= ';') && (*pnt
!= '='))
1671 while ((*pnt
< '0') || (*pnt
> '9'))
1673 while ((*pnt
>= '0') && (*pnt
<= '9'))
1678 /* search symbol list for type number dbx_type. Return a pointer to struct */
1679 static struct VMS_DBG_Symbol
*
1680 find_symbol (dbx_type
)
1683 struct VMS_DBG_Symbol
*spnt
;
1684 spnt
= VMS_Symbol_type_list
;
1685 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1687 if (spnt
->dbx_type
== dbx_type
)
1691 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1692 return 0; /*Dunno what this is*/
1693 if(spnt
->advanced
== ALIAS
)
1694 return find_symbol(spnt
->type2
);
1699 /* this routine puts info into either Local or Asuffix, depending on the sign
1700 * of size. The reason is that it is easier to build the variable descriptor
1701 * backwards, while the array descriptor is best built forwards. In the end
1702 * they get put together, if there is not a struct/union/enum along the way
1721 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1725 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1728 Apoint
= MAX_DEBUG_RECORD
- 1;
1731 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1736 /* this routine generates the array descriptor for a given array */
1738 array_suffix (spnt2
)
1739 struct VMS_DBG_Symbol
*spnt2
;
1741 struct VMS_DBG_Symbol
*spnt
;
1742 struct VMS_DBG_Symbol
*spnt1
;
1748 while (spnt
->advanced
!= ARRAY
)
1750 spnt
= find_symbol (spnt
->type2
);
1751 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1757 while (spnt1
->advanced
== ARRAY
)
1760 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1761 spnt1
= find_symbol (spnt1
->type2
);
1763 total_size
= total_size
* spnt1
->data_size
;
1764 push (spnt1
->data_size
, 2);
1765 if (spnt1
->VMS_type
== 0xa3)
1768 push (spnt1
->VMS_type
, 1);
1770 for (i
= 0; i
< 6; i
++)
1774 push (total_size
, 4);
1777 while (spnt1
->advanced
== ARRAY
)
1779 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1780 spnt1
= find_symbol (spnt1
->type2
);
1783 while (spnt1
->advanced
== ARRAY
)
1785 push (spnt1
->index_min
, 4);
1786 push (spnt1
->index_max
, 4);
1787 spnt1
= find_symbol (spnt1
->type2
);
1791 /* this routine generates the start of a variable descriptor based upon
1792 * a struct/union/enum that has yet to be defined. We define this spot as
1793 * a new location, and save four bytes for the address. When the struct is
1794 * finally defined, then we can go back and plug in the correct address
1797 new_forward_ref (dbx_type
)
1800 struct forward_ref
*fpnt
;
1801 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1802 fpnt
->next
= f_ref_root
;
1804 fpnt
->dbx_type
= dbx_type
;
1805 fpnt
->struc_numb
= ++structure_count
;
1806 fpnt
->resolved
= 'N';
1809 push (total_len
, -2);
1810 struct_number
= -fpnt
->struc_numb
;
1813 /* this routine generates the variable descriptor used to describe non-basic
1814 * variables. It calls itself recursively until it gets to the bottom of it
1815 * all, and then builds the descriptor backwards. It is easiest to do it this
1816 *way since we must periodically write length bytes, and it is easiest if we know
1817 *the value when it is time to write it.
1820 gen1 (spnt
, array_suffix_len
)
1821 struct VMS_DBG_Symbol
*spnt
;
1822 int array_suffix_len
;
1824 struct VMS_DBG_Symbol
*spnt1
;
1826 switch (spnt
->advanced
)
1829 push (DBG_S_C_VOID
, -1);
1831 push (total_len
, -2);
1835 if (array_suffix_len
== 0)
1837 push (spnt
->VMS_type
, -1);
1838 push (DBG_S_C_BASIC
, -1);
1840 push (total_len
, -2);
1850 struct_number
= spnt
->struc_numb
;
1851 if (struct_number
< 0)
1853 new_forward_ref (spnt
->dbx_type
);
1856 push (DBG_S_C_STRUCT
, -1);
1858 push (total_len
, -2);
1861 spnt1
= find_symbol (spnt
->type2
);
1863 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1864 new_forward_ref (spnt
->type2
);
1866 i
= gen1 (spnt1
, 0);
1868 { /* (*void) is a special case, do not put pointer suffix*/
1869 push (DBG_S_C_POINTER
, -1);
1871 push (total_len
, -2);
1876 while (spnt1
->advanced
== ARRAY
)
1878 spnt1
= find_symbol (spnt1
->type2
);
1879 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1881 printf ("gcc-as warning(debugger output):");
1882 printf ("Forward reference error, dbx type %d\n",
1887 /* It is too late to generate forward references, so the user gets a message.
1888 * This should only happen on a compiler error */
1889 i
= gen1 (spnt1
, 1);
1891 array_suffix (spnt
);
1892 array_suffix_len
= Apoint
- i
;
1893 switch (spnt1
->advanced
)
1901 push (total_len
, -2);
1904 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1906 total_len
+= array_suffix_len
+ 8;
1907 push (total_len
, -2);
1911 /* This generates a suffix for a variable. If it is not a defined type yet,
1912 * then dbx_type contains the type we are expecting so we can generate a
1913 * forward reference. This calls gen1 to build most of the descriptor, and
1914 * then it puts the icing on at the end. It then dumps whatever is needed
1915 * to get a complete descriptor (i.e. struct reference, array suffix ).
1918 generate_suffix (spnt
, dbx_type
)
1919 struct VMS_DBG_Symbol
*spnt
;
1924 CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1925 struct VMS_DBG_Symbol
*spnt1
;
1927 Lpnt
= MAX_DEBUG_RECORD
- 1;
1931 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1932 new_forward_ref (dbx_type
);
1935 if (spnt
->VMS_type
!= 0xa3)
1936 return 0; /* no suffix needed */
1941 push (total_len
, -1);
1942 /* if the variable descriptor overflows the record, output a descriptor for
1943 * a pointer to void.
1945 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1947 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1948 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1952 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1953 Local
[i
++] = Local
[++Lpnt
];
1955 /* we use this for a reference to a structure that has already been defined */
1956 if (struct_number
> 0)
1958 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1960 VMS_Store_Struct (struct_number
);
1962 /* we use this for a forward reference to a structure that has yet to be
1963 *defined. We store four bytes of zero to make room for the actual address once
1966 if (struct_number
< 0)
1968 struct_number
= -struct_number
;
1969 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1971 VMS_Def_Struct (struct_number
);
1972 for (i
= 0; i
< 4; i
++)
1974 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1979 Local
[Lpnt
++] = Asuffix
[i
++];
1981 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1985 /* This routine generates a symbol definition for a C sybmol for the debugger.
1986 * It takes a psect and offset for global symbols - if psect < 0, then this is
1987 * a local variable and the offset is relative to FP. In this case it can
1988 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1991 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1992 struct VMS_DBG_Symbol
*spnt
;
2002 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
2004 { /* this is a local variable, referenced to SP */
2005 maxlen
= 7 + strlen (Name_pnt
);
2006 Local
[i
++] = maxlen
;
2007 Local
[i
++] = spnt
->VMS_type
;
2009 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
2011 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
2012 COPY_LONG (&Local
[i
], Offset
);
2017 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
2018 Local
[i
++] = 7 + strlen (Name_pnt
);
2019 Local
[i
++] = spnt
->VMS_type
;
2021 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2023 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2025 Local
[i
++] = strlen (Name_pnt
);
2026 while (*Name_pnt
!= '\0')
2027 Local
[i
++] = *Name_pnt
++;
2028 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2029 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2030 generate_suffix (spnt
, 0);
2034 /* This routine parses the stabs entries in order to make the definition
2035 * for the debugger of local symbols and function parameters
2038 VMS_local_stab_Parse (sp
)
2044 struct VMS_DBG_Symbol
*spnt
;
2045 struct VMS_Symbol
*vsp
;
2049 str
= S_GET_NAME (sp
);
2050 pnt
= (char *) strchr (str
, ':');
2051 if (pnt
== (char *) NULL
)
2052 return; /* no colon present */
2053 pnt1
= pnt
++; /* save this for later, and skip colon */
2055 return 0; /* ignore static constants */
2056 /* there is one little catch that we must be aware of. Sometimes function
2057 * parameters are optimized into registers, and the compiler, in its infiite
2058 * wisdom outputs stabs records for *both*. In general we want to use the
2059 * register if it is present, so we must search the rest of the symbols for
2060 * this function to see if this parameter is assigned to a register.
2068 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2070 if (!S_IS_DEBUG (sp1
))
2072 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2074 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2075 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2077 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2079 str1
= S_GET_NAME (sp1
); /* and get the name */
2081 while (*pnt2
!= ':')
2088 if ((*str1
!= ':') || (*pnt2
!= ':'))
2090 return; /* they are the same! lets skip this one */
2092 /* first find the dbx symbol type from list, and then find VMS type */
2093 pnt
++; /* skip p in case no register */
2096 pnt
= cvt_integer (pnt
, &dbx_type
);
2097 spnt
= find_symbol (dbx_type
);
2098 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2099 return 0; /*Dunno what this is*/
2101 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2102 *pnt1
= ':'; /* and restore the string */
2106 /* This routine parses a stabs entry to find the information required to define
2107 * a variable. It is used for global and static variables.
2108 * Basically we need to know the address of the symbol. With older versions
2109 * of the compiler, const symbols are
2110 * treated differently, in that if they are global they are written into the
2111 * text psect. The global symbol entry for such a const is actually written
2112 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2113 * of psects, we must search the entry points as well. static consts are even
2114 * harder, since they are never assigned a memory address. The compiler passes
2115 * a stab to tell us the value, but I am not sure what to do with it.
2119 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2122 int type1
, type2
, Text_Psect
;
2128 struct VMS_DBG_Symbol
*spnt
;
2129 struct VMS_Symbol
*vsp
;
2133 str
= S_GET_NAME (sp
);
2134 pnt
= (char *) strchr (str
, ':');
2135 if (pnt
== (char *) NULL
)
2136 return; /* no colon present */
2137 pnt1
= pnt
; /* save this for later*/
2139 if (*pnt
== expected_type
)
2141 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2142 spnt
= find_symbol (dbx_type
);
2143 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2144 return 0; /*Dunno what this is*/
2145 /* now we need to search the symbol table to find the psect and offset for
2150 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2152 pnt
= S_GET_NAME (vsp
->Symbol
);
2153 if (pnt
!= (char *) NULL
)
2155 /* make sure name is the same, and make sure correct symbol type */
2156 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2157 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2158 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2162 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2164 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2165 *pnt1
= ':'; /* and restore the string */
2168 /* the symbol was not in the symbol list, but it may be an "entry point"
2169 if it was a constant */
2170 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2173 * Dispatch on STAB type
2175 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2177 pnt
= S_GET_NAME (sp1
);
2180 if (strcmp (pnt
, str
) == 0)
2182 if (!gave_compiler_message
&& expected_type
== 'G')
2184 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2185 printf ("global constant(s) in the text psect. These will not be available to\n");
2186 printf ("other modules, since this is not the correct way to handle this. You\n");
2187 printf ("have two options: 1) get a patched compiler that does not put global\n");
2188 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2189 printf ("definitions of global variables in your source module(s). Don't say\n");
2190 printf ("I didn't warn you!");
2191 gave_compiler_message
= 1;
2193 VMS_DBG_record (spnt
,
2198 *S_GET_NAME (sp1
) = 'L';
2199 /* fool assembler to not output this
2200 * as a routine in the TBT */
2205 *pnt1
= ':'; /* and restore the string */
2210 VMS_GSYM_Parse (sp
, Text_Psect
)
2213 { /* Global variables */
2214 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2219 VMS_LCSYM_Parse (sp
, Text_Psect
)
2222 { /* Static symbols - uninitialized */
2223 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2227 VMS_STSYM_Parse (sp
, Text_Psect
)
2230 { /* Static symbols - initialized */
2231 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2235 /* for register symbols, we must figure out what range of addresses within the
2236 * psect are valid. We will use the brackets in the stab directives to give us
2237 * guidance as to the PC range that this variable is in scope. I am still not
2238 * completely comfortable with this but as I learn more, I seem to get a better
2239 * handle on what is going on.
2243 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2244 symbolS
*sp
, *Current_Routine
;
2251 struct VMS_DBG_Symbol
*spnt
;
2256 int Min_Offset
= -1; /* min PC of validity */
2257 int Max_Offset
= 0; /* max PC of validity */
2259 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2262 * Dispatch on STAB type
2264 switch (S_GET_RAW_TYPE (symbolP
))
2268 Min_Offset
= S_GET_VALUE (symbolP
);
2273 S_GET_VALUE (symbolP
) - 1;
2276 if ((Min_Offset
!= -1) && (bcnt
== 0))
2278 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2280 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2281 if (*pnt
== 'F' || *pnt
== 'f') break;
2284 /* check to see that the addresses were defined. If not, then there were no
2285 * brackets in the function, and we must try to search for the next function
2286 * Since functions can be in any order, we should search all of the symbol list
2287 * to find the correct ending address. */
2288 if (Min_Offset
== -1)
2290 int Max_Source_Offset
;
2292 Min_Offset
= S_GET_VALUE (sp
);
2293 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2296 * Dispatch on STAB type
2298 This_Offset
= S_GET_VALUE (symbolP
);
2299 switch (S_GET_RAW_TYPE (symbolP
))
2301 case N_TEXT
| N_EXT
:
2302 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2303 Max_Offset
= This_Offset
;
2306 if (This_Offset
> Max_Source_Offset
)
2307 Max_Source_Offset
= This_Offset
;
2310 /* if this is the last routine, then we use the PC of the last source line
2311 * as a marker of the max PC for which this reg is valid */
2312 if (Max_Offset
== 0x7fffffff)
2313 Max_Offset
= Max_Source_Offset
;
2316 str
= S_GET_NAME (sp
);
2317 pnt
= (char *) strchr (str
, ':');
2318 if (pnt
== (char *) NULL
)
2319 return; /* no colon present */
2320 pnt1
= pnt
; /* save this for later*/
2324 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2325 spnt
= find_symbol (dbx_type
);
2326 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2327 return 0; /*Dunno what this is yet*/
2329 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2330 maxlen
= 25 + strlen (pnt
);
2331 Local
[i
++] = maxlen
;
2332 Local
[i
++] = spnt
->VMS_type
;
2334 Local
[i
++] = strlen (pnt
) + 1;
2338 Local
[i
++] = strlen (pnt
);
2339 while (*pnt
!= '\0')
2340 Local
[i
++] = *pnt
++;
2346 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2348 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2349 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2351 Local
[i
++] = S_GET_VALUE (sp
);
2355 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2357 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2358 generate_suffix (spnt
, 0);
2361 /* this function examines a structure definition, checking all of the elements
2362 * to make sure that all of them are fully defined. The only thing that we
2363 * kick out are arrays of undefined structs, since we do not know how big
2364 * they are. All others we can handle with a normal forward reference.
2367 forward_reference (pnt
)
2371 struct VMS_DBG_Symbol
*spnt
;
2372 struct VMS_DBG_Symbol
*spnt1
;
2373 pnt
= cvt_integer (pnt
+ 1, &i
);
2375 return 0; /* no forward references */
2378 pnt
= (char *) strchr (pnt
, ':');
2379 pnt
= cvt_integer (pnt
+ 1, &i
);
2380 spnt
= find_symbol (i
);
2381 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2382 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2385 spnt1
= find_symbol (spnt
->type2
);
2386 if ((spnt
->advanced
== ARRAY
) &&
2387 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2389 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2394 pnt
= cvt_integer (pnt
+ 1, &i
);
2395 pnt
= cvt_integer (pnt
+ 1, &i
);
2396 } while (*++pnt
!= ';');
2397 return 0; /* no forward refences found */
2400 /* Used to check a single element of a structure on the final pass*/
2403 final_forward_reference (spnt
)
2404 struct VMS_DBG_Symbol
* spnt
;
2406 struct VMS_DBG_Symbol
* spnt1
;
2407 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2408 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2409 spnt1
= find_symbol(spnt
->type2
);
2410 if((spnt
->advanced
== ARRAY
) &&
2411 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2412 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2416 return 0; /* no forward refences found */
2419 /* This routine parses the stabs directives to find any definitions of dbx type
2420 * numbers. It makes a note of all of them, creating a structure element
2421 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2422 * debugger that describes the struct/union/enum, so that further references
2423 * to these data types will be by number
2424 * We have to process pointers right away, since there can be references
2425 * to them later in the same stabs directive. We cannot have forward
2426 * references to pointers, (but we can have a forward reference to a pointer to
2427 * a structure/enum/union) and this is why we process them immediately.
2428 * After we process the pointer, then we search for defs that are nested even
2430 * 8/15/92: We have to process arrays right away too, because there can
2431 * be multiple references to identical array types in one structure
2432 * definition, and only the first one has the definition. (We tend to
2433 * parse from the back going forward.
2436 VMS_typedef_parse (str
)
2444 struct forward_ref
*fpnt
;
2446 int convert_integer
;
2447 struct VMS_DBG_Symbol
*spnt
;
2448 struct VMS_DBG_Symbol
*spnt1
;
2449 /* check for any nested def's */
2450 pnt
= (char *) strchr (str
+ 1, '=');
2451 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2452 && (str
[1] != 'a' || str
[2] != 'r'))
2453 if (VMS_typedef_parse (pnt
) == 1)
2455 /* now find dbx_type of entry */
2458 { /* check for static constants */
2459 *str
= '\0'; /* for now we ignore them */
2462 while ((*pnt
<= '9') && (*pnt
>= '0'))
2464 pnt
++; /* and get back to the number */
2465 cvt_integer (pnt
, &i1
);
2466 spnt
= find_symbol (i1
);
2467 /* first we see if this has been defined already, due to a forward reference*/
2468 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2470 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2472 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2473 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2474 VMS_Symbol_type_list
= spnt
;
2478 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2479 spnt
->next
= VMS_Symbol_type_list
;
2480 VMS_Symbol_type_list
= spnt
;
2482 spnt
->dbx_type
= i1
; /* and save the type */
2484 /* for structs and unions, do a partial parse, otherwise we sometimes get
2485 * circular definitions that are impossible to resolve. We read enough info
2486 * so that any reference to this type has enough info to be resolved
2488 pnt
= str
+ 1; /* point to character past equal sign */
2489 if ((*pnt
== 'u') || (*pnt
== 's'))
2492 if ((*pnt
<= '9') && (*pnt
>= '0'))
2494 if (type_check ("void"))
2495 { /* this is the void symbol */
2497 spnt
->advanced
= VOID
;
2500 if (type_check ("unknown type"))
2501 { /* this is the void symbol */
2503 spnt
->advanced
= UNKNOWN
;
2506 pnt1
= cvt_integer(pnt
,&i1
);
2507 if(i1
!= spnt
->dbx_type
)
2509 spnt
->advanced
= ALIAS
;
2514 printf ("gcc-as warning(debugger output):");
2515 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2516 return 1; /* do not know what this is */
2518 /* now define this module*/
2519 pnt
= str
+ 1; /* point to character past equal sign */
2523 spnt
->advanced
= BASIC
;
2524 if (type_check ("int"))
2526 spnt
->VMS_type
= DBG_S_C_SLINT
;
2527 spnt
->data_size
= 4;
2529 else if (type_check ("long int"))
2531 spnt
->VMS_type
= DBG_S_C_SLINT
;
2532 spnt
->data_size
= 4;
2534 else if (type_check ("unsigned int"))
2536 spnt
->VMS_type
= DBG_S_C_ULINT
;
2537 spnt
->data_size
= 4;
2539 else if (type_check ("long unsigned int"))
2541 spnt
->VMS_type
= DBG_S_C_ULINT
;
2542 spnt
->data_size
= 4;
2544 else if (type_check ("short int"))
2546 spnt
->VMS_type
= DBG_S_C_SSINT
;
2547 spnt
->data_size
= 2;
2549 else if (type_check ("short unsigned int"))
2551 spnt
->VMS_type
= DBG_S_C_USINT
;
2552 spnt
->data_size
= 2;
2554 else if (type_check ("char"))
2556 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2557 spnt
->data_size
= 1;
2559 else if (type_check ("signed char"))
2561 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2562 spnt
->data_size
= 1;
2564 else if (type_check ("unsigned char"))
2566 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2567 spnt
->data_size
= 1;
2569 else if (type_check ("float"))
2571 spnt
->VMS_type
= DBG_S_C_REAL4
;
2572 spnt
->data_size
= 4;
2574 else if (type_check ("double"))
2576 spnt
->VMS_type
= DBG_S_C_REAL8
;
2577 spnt
->data_size
= 8;
2579 pnt1
= (char *) strchr (str
, ';') + 1;
2584 spnt
->advanced
= STRUCT
;
2586 spnt
->advanced
= UNION
;
2587 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2588 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2589 if (!final_pass
&& forward_reference(pnt
))
2591 spnt
->struc_numb
= -1;
2594 spnt
->struc_numb
= ++structure_count
;
2596 pnt
= get_struct_name (str
);
2597 VMS_Def_Struct (spnt
->struc_numb
);
2599 while (fpnt
!= (struct forward_ref
*) NULL
)
2601 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2603 fpnt
->resolved
= 'Y';
2604 VMS_Set_Struct (fpnt
->struc_numb
);
2605 VMS_Store_Struct (spnt
->struc_numb
);
2609 VMS_Set_Struct (spnt
->struc_numb
);
2611 Local
[i
++] = 11 + strlen (pnt
);
2612 Local
[i
++] = DBG_S_C_STRUCT_START
;
2614 for (i1
= 0; i1
< 4; i1
++)
2616 Local
[i
++] = strlen (pnt
);
2618 while (*pnt2
!= '\0')
2619 Local
[i
++] = *pnt2
++;
2620 i2
= spnt
->data_size
* 8; /* number of bits */
2621 COPY_LONG(&Local
[i
], i2
);
2623 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2625 if (pnt
!= symbol_name
)
2627 pnt
+= strlen (pnt
);
2629 }; /* replace colon for later */
2630 while (*++pnt1
!= ';')
2632 pnt
= (char *) strchr (pnt1
, ':');
2635 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2636 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2637 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2638 if ((dtype
== 1) && (i3
!= 32))
2641 push (19 + strlen (pnt2
), 1);
2643 push (1 + strlen (pnt2
), 4);
2644 push (strlen (pnt2
), 1);
2645 while (*pnt2
!= '\0')
2647 push (i3
, 2); /* size of bitfield */
2650 push (i2
, 4); /* start position */
2651 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2656 Local
[i
++] = 7 + strlen (pnt2
);
2657 spnt1
= find_symbol (dtype
);
2658 /* check if this is a forward reference */
2659 if(final_pass
&& final_forward_reference(spnt1
))
2661 printf("gcc-as warning(debugger output):");
2662 printf("structure element %s has undefined type\n",pnt2
);
2666 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2667 Local
[i
++] = spnt1
->VMS_type
;
2669 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2670 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2671 COPY_LONG (&Local
[i
], i2
);
2673 Local
[i
++] = strlen (pnt2
);
2674 while (*pnt2
!= '\0')
2675 Local
[i
++] = *pnt2
++;
2676 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2678 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2679 generate_suffix (spnt1
, dtype
);
2680 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2681 generate_suffix (spnt1
, 0);
2685 Local
[i
++] = 0x01; /* length byte */
2686 Local
[i
++] = DBG_S_C_STRUCT_END
;
2687 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2691 spnt
->advanced
= ENUM
;
2692 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2693 spnt
->struc_numb
= ++structure_count
;
2694 spnt
->data_size
= 4;
2695 VMS_Def_Struct (spnt
->struc_numb
);
2697 while (fpnt
!= (struct forward_ref
*) NULL
)
2699 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2701 fpnt
->resolved
= 'Y';
2702 VMS_Set_Struct (fpnt
->struc_numb
);
2703 VMS_Store_Struct (spnt
->struc_numb
);
2707 VMS_Set_Struct (spnt
->struc_numb
);
2709 Local
[i
++] = 3 + strlen (symbol_name
);
2710 Local
[i
++] = DBG_S_C_ENUM_START
;
2712 Local
[i
++] = strlen (symbol_name
);
2714 while (*pnt2
!= '\0')
2715 Local
[i
++] = *pnt2
++;
2716 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2718 while (*++pnt
!= ';')
2720 pnt1
= (char *) strchr (pnt
, ':');
2722 pnt1
= cvt_integer (pnt1
, &i1
);
2723 Local
[i
++] = 7 + strlen (pnt
);
2724 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2726 COPY_LONG (&Local
[i
], i1
);
2728 Local
[i
++] = strlen (pnt
);
2730 while (*pnt
!= '\0')
2731 Local
[i
++] = *pnt
++;
2732 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2734 pnt
= pnt1
; /* Skip final semicolon */
2736 Local
[i
++] = 0x01; /* len byte */
2737 Local
[i
++] = DBG_S_C_ENUM_END
;
2738 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2743 spnt
->advanced
= ARRAY
;
2744 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2745 pnt
= (char *) strchr (pnt
, ';');
2746 if (pnt
== (char *) NULL
)
2748 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2749 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2750 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2751 pnt
=(char*)strchr(str
+1,'=');
2752 if((pnt
!= (char*) NULL
))
2753 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2756 spnt
->advanced
= FUNCTION
;
2757 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2758 /* this masquerades as a basic type*/
2759 spnt
->data_size
= 4;
2760 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2763 spnt
->advanced
= POINTER
;
2764 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2765 spnt
->data_size
= 4;
2766 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2767 pnt
= (char *) strchr (str
+ 1, '=');
2768 if ((pnt
!= (char *) NULL
))
2769 if (VMS_typedef_parse (pnt
) == 1)
2773 spnt
->advanced
= UNKNOWN
;
2775 printf ("gcc-as warning(debugger output):");
2776 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2777 return 1; /* unable to decipher */
2779 /* this removes the evidence of the definition so that the outer levels of
2780 parsing do not have to worry about it */
2782 while (*pnt1
!= '\0')
2790 * This is the root routine that parses the stabs entries for definitions.
2791 * it calls VMS_typedef_parse, which can in turn call itself.
2792 * We need to be careful, since sometimes there are forward references to
2793 * other symbol types, and these cannot be resolved until we have completed
2796 * Also check and see if we are using continuation stabs, if we are, then
2797 * paste together the entire contents of the stab before we pass it to
2798 * VMS_typedef_parse.
2807 char *parse_buffer
= 0;
2809 int incomplete
, i
, pass
, incom1
;
2810 struct VMS_DBG_Symbol
*spnt
;
2811 struct VMS_Symbol
*vsp
;
2812 struct forward_ref
*fpnt
;
2819 incom1
= incomplete
;
2821 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2824 * Deal with STAB symbols
2826 if (S_IS_DEBUG (sp
))
2829 * Dispatch on STAB type
2831 switch (S_GET_RAW_TYPE (sp
))
2839 case N_FUN
: /*sometimes these contain typedefs*/
2840 str
= S_GET_NAME (sp
);
2842 pnt
= str
+ strlen(str
) -1;
2843 if (*pnt
== '?') /* Continuation stab. */
2849 tlen
+= strlen(str
) - 1;
2850 spnext
= symbol_next (spnext
);
2851 str
= S_GET_NAME (spnext
);
2852 pnt
= str
+ strlen(str
) - 1;
2853 } while (*pnt
== '?');
2854 tlen
+= strlen(str
);
2855 parse_buffer
= (char *) malloc (tlen
+ 1);
2856 strcpy(parse_buffer
, S_GET_NAME (sp
));
2857 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2861 spnext
= symbol_next (spnext
);
2862 str
= S_GET_NAME (spnext
);
2863 strcat (pnt2
, S_GET_NAME (spnext
));
2864 pnt2
+= strlen(str
) - 1;
2865 *str
= '\0'; /* Erase this string */
2866 if (*pnt2
!= '?') break;
2872 pnt
= (char *) strchr (str
, ':');
2873 if (pnt
!= (char *) NULL
)
2877 pnt2
= (char *) strchr (pnt1
, '=');
2878 if (pnt2
!= (char *) NULL
)
2879 incomplete
+= VMS_typedef_parse (pnt2
);
2881 /* At this point the parse buffer should just contain name:nn.
2882 If it does not, then we are in real trouble. Anyway,
2883 this is always shorter than the original line. */
2884 strcpy(S_GET_NAME (sp
), parse_buffer
);
2885 free (parse_buffer
);
2888 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2895 /* Make one last pass, if needed, and define whatever we can that is left */
2896 if(final_pass
== 0 && incomplete
== incom1
)
2899 incom1
++; /* Force one last pass through */
2901 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2902 /* repeat until all refs resolved if possible */
2903 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2904 if (incomplete
!= 0)
2906 printf ("gcc-as warning(debugger output):");
2907 printf ("Unable to resolve %d circular references.\n", incomplete
);
2911 while (fpnt
!= (struct forward_ref
*) NULL
)
2913 if (fpnt
->resolved
!= 'Y')
2915 if (find_symbol (fpnt
->dbx_type
) !=
2916 (struct VMS_DBG_Symbol
*) NULL
)
2918 printf ("gcc-as warning(debugger output):");
2919 printf ("Forward reference error, dbx type %d\n",
2924 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2925 pnt2
= (char *) strchr (&fixit
[1], '=');
2926 VMS_typedef_parse (pnt2
);
2933 Define_Local_Symbols (s1
, s2
)
2937 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2939 if (symbolP1
== (symbolS
*) NULL
)
2941 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2943 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2944 if (*pnt
== 'F' || *pnt
== 'f') break;
2947 * Deal with STAB symbols
2949 if (S_IS_DEBUG (symbolP1
))
2952 * Dispatch on STAB type
2954 switch (S_GET_RAW_TYPE (symbolP1
))
2958 VMS_local_stab_Parse (symbolP1
);
2961 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
2969 /* This function crawls the symbol chain searching for local symbols that need
2970 * to be described to the debugger. When we enter a new scope with a "{", it
2971 * creates a new "block", which helps the debugger keep track of which scope
2972 * we are currently in.
2976 Define_Routine (symbolP
, Level
)
2986 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
2988 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2990 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2991 if (*pnt
== 'F' || *pnt
== 'f') break;
2994 * Deal with STAB symbols
2996 if (S_IS_DEBUG (symbolP1
))
2999 * Dispatch on STAB type
3001 switch (S_GET_RAW_TYPE (symbolP1
))
3006 sprintf (str
, "$%d", rcount
++);
3007 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3009 Offset
= S_GET_VALUE (symbolP1
);
3010 Define_Local_Symbols (sstart
, symbolP1
);
3012 Define_Routine (symbolP1
, Level
+ 1);
3014 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3023 /* we end up here if there were no brackets in this function. Define
3025 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3031 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3033 symbolS
*Curr_Routine
;
3036 Current_Routine
= Curr_Routine
;
3037 Text_Psect
= Txt_Psect
;
3038 Define_Routine (symbolP
, 0);
3045 #include <sys/types.h>
3048 /* Manufacure a VMS like time on a unix based system. */
3049 get_VMS_time_on_unix (char *Now
)
3054 pnt
= ctime (&timeb
);
3060 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3063 #endif /* not HO_VMS */
3065 * Write the MHD (Module Header) records
3068 Write_VMS_MHD_Records ()
3070 register char *cp
, *cp1
;
3077 char Module_Name
[256];
3081 * We are writing a module header record
3083 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3085 * ***************************
3086 * *MAIN MODULE HEADER RECORD*
3087 * ***************************
3089 * Store record type and header type
3091 PUT_CHAR (OBJ_S_C_HDR
);
3092 PUT_CHAR (MHD_S_C_MHD
);
3094 * Structure level is 0
3096 PUT_CHAR (OBJ_S_C_STRLVL
);
3098 * Maximum record size is size of the object record buffer
3100 PUT_SHORT (sizeof (Object_Record_Buffer
));
3102 * Get module name (the FILENAME part of the object file)
3108 if ((*cp
== ']') || (*cp
== '>') ||
3109 (*cp
== ':') || (*cp
== '/'))
3115 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3119 * Limit it to 31 characters and store in the object record
3121 while (--cp1
>= Module_Name
)
3124 if (strlen (Module_Name
) > 31)
3127 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3128 Module_Name
[31] = 0;
3130 PUT_COUNTED_STRING (Module_Name
);
3132 * Module Version is "V1.0"
3134 PUT_COUNTED_STRING ("V1.0");
3136 * Creation time is "now" (17 chars of time string)
3139 get_VMS_time_on_unix (&Now
[0]);
3141 Descriptor
.Size
= 17;
3142 Descriptor
.Ptr
= Now
;
3143 sys$
asctim (0, &Descriptor
, 0, 0);
3145 for (i
= 0; i
< 17; i
++)
3148 * Patch time is "never" (17 zeros)
3150 for (i
= 0; i
< 17; i
++)
3155 Flush_VMS_Object_Record_Buffer ();
3157 * *************************
3158 * *LANGUAGE PROCESSOR NAME*
3159 * *************************
3161 * Store record type and header type
3163 PUT_CHAR (OBJ_S_C_HDR
);
3164 PUT_CHAR (MHD_S_C_LNM
);
3166 * Store language processor name and version
3167 * (not a counted string!)
3169 cp
= compiler_version_string
;
3175 cp
= strchr (&version_string
, '.');
3185 Flush_VMS_Object_Record_Buffer ();
3190 * Write the EOM (End Of Module) record
3193 Write_VMS_EOM_Record (Psect
, Offset
)
3198 * We are writing an end-of-module record
3200 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3204 PUT_CHAR (OBJ_S_C_EOM
);
3206 * Store the error severity (0)
3210 * Store the entry point, if it exists
3215 * Store the entry point Psect
3219 * Store the entry point Psect offset
3226 Flush_VMS_Object_Record_Buffer ();
3230 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3236 register unsigned char *p
= ptr
;
3237 register unsigned char *end
= p
+ strlen (ptr
);
3238 register unsigned char c
;
3239 register int hash
= 0;
3244 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3250 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3253 VMS_Case_Hack_Symbol (In
, Out
)
3263 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3265 int Case_Hack_Bits
= 0;
3267 static char Hex_Table
[16] =
3268 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3271 * Kill any leading "_"
3273 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3276 new_name
= Out
; /* save this for later*/
3278 #if barfoo /* Dead code */
3279 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3283 /* We may need to truncate the symbol, save the hash for later*/
3284 if (strlen (In
) > 23)
3285 result
= hash_string (In
);
3287 * Is there a Psect Attribute to skip??
3289 if (HAS_PSECT_ATTRIBUTES (In
))
3294 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3297 if ((In
[0] == '$') && (In
[1] == '$'))
3307 /* if (strlen(In) > 31 && flagseen['+'])
3308 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3310 * Do the case conversion
3312 i
= 23; /* Maximum of 23 chars */
3313 while (*In
&& (--i
>= 0))
3315 Case_Hack_Bits
<<= 1;
3318 if ((destructor
== 1) && (i
== 21))
3320 switch (vms_name_mapping
)
3325 Case_Hack_Bits
|= 1;
3327 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3330 case 3: *Out
++ = *In
++;
3336 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3342 * If we saw a dollar sign, we don't do case hacking
3344 if (flagseen
['h'] || Saw_Dollar
)
3348 * If we have more than 23 characters and everything is lowercase
3349 * we can insert the full 31 characters
3354 * We have more than 23 characters
3355 * If we must add the case hack, then we have truncated the str
3359 if (Case_Hack_Bits
== 0)
3362 * And so far they are all lower case:
3363 * Check up to 8 more characters
3364 * and ensure that they are lowercase
3366 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3367 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3373 if ((i
== 8) || (In
[i
] == 0))
3376 * They are: Copy up to 31 characters
3377 * to the output string
3380 while ((--i
>= 0) && (*In
))
3381 switch (vms_name_mapping
){
3382 case 0: *Out
++ = islower(*In
) ?
3386 case 3: *Out
++ = *In
++;
3388 case 2: *Out
++ = isupper(*In
) ?
3397 * If there were any uppercase characters in the name we
3398 * take on the case hacking string
3401 /* Old behavior for regular GNU-C compiler */
3404 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3409 for (i
= 0; i
< 6; i
++)
3411 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3412 Case_Hack_Bits
>>= 4;
3418 Out
= pnt
; /*Cut back to 23 characters maximum */
3420 for (i
= 0; i
< 7; i
++)
3422 init
= result
& 0x01f;
3424 *Out
++ = '0' + init
;
3426 *Out
++ = 'A' + init
- 10;
3427 result
= result
>> 5;
3435 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3436 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3441 * Scan a symbol name for a psect attribute specification
3443 #define GLOBALSYMBOL_BIT 0x10000
3444 #define GLOBALVALUE_BIT 0x20000
3448 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3450 int *Attribute_Pointer
;
3461 {"PIC", GPS_S_M_PIC
},
3462 {"LIB", GPS_S_M_LIB
},
3463 {"OVR", GPS_S_M_OVR
},
3464 {"REL", GPS_S_M_REL
},
3465 {"GBL", GPS_S_M_GBL
},
3466 {"SHR", GPS_S_M_SHR
},
3467 {"EXE", GPS_S_M_EXE
},
3469 {"WRT", GPS_S_M_WRT
},
3470 {"VEC", GPS_S_M_VEC
},
3471 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3472 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3482 * Check for a PSECT attribute list
3484 if (!HAS_PSECT_ATTRIBUTES (Name
))
3485 return; /* If not, return */
3487 * Skip the attribute list indicator
3489 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3491 * Process the attributes ("_" separated, "$" terminated)
3493 while (*Name
!= '$')
3496 * Assume not negating
3502 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3505 * We are negating (and skip the NO)
3511 * Find the token delimiter
3514 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3517 * Look for the token in the attribute list
3519 for (i
= 0; Attributes
[i
].Name
; i
++)
3522 * If the strings match, set/clear the attr.
3524 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3530 *Attribute_Pointer
&=
3531 ~Attributes
[i
].Value
;
3533 *Attribute_Pointer
|=
3534 Attributes
[i
].Value
;
3542 * Now skip the attribute
3556 * Define a global symbol
3559 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3567 * We are writing a GSD record
3569 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3571 * If the buffer is empty we must insert the GSD record type
3573 if (Object_Record_Offset
== 0)
3574 PUT_CHAR (OBJ_S_C_GSD
);
3576 * We are writing a Global symbol definition subrecord
3578 if (Psect_Number
<= 255)
3580 PUT_CHAR (GSD_S_C_SYM
);
3584 PUT_CHAR (GSD_S_C_SYMW
);
3587 * Data type is undefined
3591 * Switch on Definition/Reference
3593 if ((Defined
& 1) != 0)
3597 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3598 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3600 if ((Defined
& 2) == 0)
3602 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3606 PUT_SHORT (GSY_S_M_DEF
);
3611 if (Psect_Number
<= 255)
3613 PUT_CHAR (Psect_Number
);
3617 PUT_SHORT (Psect_Number
);
3622 PUT_LONG (Psect_Offset
);
3628 * Flags = "RELOCATABLE" for regular symbol,
3629 * = "" for globalvalue (Defined & 2 == 1)
3631 if ((Defined
& 2) == 0)
3633 PUT_SHORT (GSY_S_M_REL
);
3641 * Finally, the global symbol name
3643 VMS_Case_Hack_Symbol (Name
, Local
);
3644 PUT_COUNTED_STRING (Local
);
3646 * Flush the buffer if it is more than 75% full
3648 if (Object_Record_Offset
>
3649 (sizeof (Object_Record_Buffer
) * 3 / 4))
3650 Flush_VMS_Object_Record_Buffer ();
3658 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3662 struct VMS_Symbol
*vsp
;
3665 int Psect_Attributes
;
3668 * Generate the appropriate PSECT flags given the PSECT type
3670 if (strcmp (Type
, "COMMON") == 0)
3673 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3675 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3676 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3678 else if (strcmp (Type
, "CONST") == 0)
3681 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3683 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3684 GPS_S_M_SHR
| GPS_S_M_RD
);
3686 else if (strcmp (Type
, "DATA") == 0)
3689 * The Data psects are PIC,REL,RD,WRT
3692 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3694 else if (strcmp (Type
, "TEXT") == 0)
3697 * The Text psects are PIC,REL,SHR,EXE,RD
3700 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3701 GPS_S_M_EXE
| GPS_S_M_RD
);
3706 * Error: Unknown psect type
3708 error ("Unknown VMS psect type");
3711 * Modify the psect attributes according to any attribute string
3713 if (HAS_PSECT_ATTRIBUTES (Name
))
3714 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3716 * Check for globalref/def/val.
3718 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3721 * globalvalue symbols were generated before. This code
3722 * prevents unsightly psect buildup, and makes sure that
3723 * fixup references are emitted correctly.
3725 vsp
->Psect_Index
= -1; /* to catch errors */
3726 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3727 return 1; /* decrement psect counter */
3730 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3732 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3734 case N_UNDF
| N_EXT
:
3735 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3736 vsp
->Psect_Offset
, 0);
3737 vsp
->Psect_Index
= -1;
3738 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3739 return 1; /* return and indicate no psect */
3740 case N_DATA
| N_EXT
:
3741 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3742 vsp
->Psect_Offset
, 1);
3743 /* In this case we still generate the psect */
3747 char Error_Line
[256];
3748 sprintf (Error_Line
, "Globalsymbol attribute for"
3749 " symbol %s was unexpected.\n", Name
);
3756 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3758 * We are writing a GSD record
3760 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3762 * If the buffer is empty we must insert the GSD record type
3764 if (Object_Record_Offset
== 0)
3765 PUT_CHAR (OBJ_S_C_GSD
);
3767 * We are writing a PSECT definition subrecord
3769 PUT_CHAR (GSD_S_C_PSC
);
3771 * Psects are always LONGWORD aligned
3775 * Specify the psect attributes
3777 PUT_SHORT (Psect_Attributes
);
3779 * Specify the allocation
3783 * Finally, the psect name
3785 VMS_Case_Hack_Symbol (Name
, Local
);
3786 PUT_COUNTED_STRING (Local
);
3788 * Flush the buffer if it is more than 75% full
3790 if (Object_Record_Offset
>
3791 (sizeof (Object_Record_Buffer
) * 3 / 4))
3792 Flush_VMS_Object_Record_Buffer ();
3798 * Given the pointer to a symbol we calculate how big the data at the
3799 * symbol is. We do this by looking for the next symbol (local or
3800 * global) which will indicate the start of another datum.
3803 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3804 register struct symbol
*sp
;
3807 register struct symbol
*sp1
, *Next_Symbol
;
3810 * Find the next symbol
3811 * it delimits this datum
3814 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3817 * The data type must match
3819 if (S_GET_TYPE (sp1
) != N_DATA
)
3822 * The symbol must be AFTER this symbol
3824 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3827 * We ignore THIS symbol
3832 * If there is already a candidate selected for the
3833 * next symbol, see if we are a better candidate
3838 * We are a better candidate if we are "closer"
3841 if (S_GET_VALUE (sp1
) >
3842 S_GET_VALUE (Next_Symbol
))
3845 * Win: Make this the candidate
3852 * This is the 1st candidate
3858 * Calculate its size
3860 return (Next_Symbol
?
3861 (S_GET_VALUE (Next_Symbol
) -
3863 (End_Of_Data
- S_GET_VALUE (sp
)));
3867 * Check symbol names for the Psect hack with a globalvalue, and then
3868 * generate globalvalues for those that have it.
3871 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3876 register symbolS
*sp
;
3877 char *stripped_name
, *Name
;
3879 int Psect_Attributes
;
3883 * Scan the symbol table for globalvalues, and emit def/ref when
3884 * required. These will be caught again later and converted to
3887 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3890 * See if this is something we want to look at.
3892 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3893 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3896 * See if this has globalvalue specification.
3898 Name
= S_GET_NAME (sp
);
3900 if (!HAS_PSECT_ATTRIBUTES (Name
))
3903 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3904 strcpy (stripped_name
, Name
);
3905 Psect_Attributes
= 0;
3906 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3908 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3910 switch (S_GET_RAW_TYPE (sp
))
3912 case N_UNDF
| N_EXT
:
3913 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3915 case N_DATA
| N_EXT
:
3916 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3918 error ("Invalid data type for globalvalue");
3919 globalvalue
= md_chars_to_number (Data_Segment
+
3920 S_GET_VALUE (sp
) - text_siz
, Size
);
3921 /* Three times for good luck. The linker seems to get confused
3922 if there are fewer than three */
3923 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3924 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3925 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3928 printf (" Invalid globalvalue of %s\n", stripped_name
);
3932 free (stripped_name
); /* clean up */
3939 * Define a procedure entry pt/mask
3942 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3951 * We are writing a GSD record
3953 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3955 * If the buffer is empty we must insert the GSD record type
3957 if (Object_Record_Offset
== 0)
3958 PUT_CHAR (OBJ_S_C_GSD
);
3960 * We are writing a Procedure Entry Pt/Mask subrecord
3962 if (Psect_Number
<= 255)
3964 PUT_CHAR (GSD_S_C_EPM
);
3968 PUT_CHAR (GSD_S_C_EPMW
);
3971 * Data type is undefined
3975 * Flags = "RELOCATABLE" and "DEFINED"
3977 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3981 if (Psect_Number
<= 255)
3983 PUT_CHAR (Psect_Number
);
3987 PUT_SHORT (Psect_Number
);
3992 PUT_LONG (Psect_Offset
);
3996 PUT_SHORT (Entry_Mask
);
3998 * Finally, the global symbol name
4000 VMS_Case_Hack_Symbol (Name
, Local
);
4001 PUT_COUNTED_STRING (Local
);
4003 * Flush the buffer if it is more than 75% full
4005 if (Object_Record_Offset
>
4006 (sizeof (Object_Record_Buffer
) * 3 / 4))
4007 Flush_VMS_Object_Record_Buffer ();
4012 * Set the current location counter to a particular Psect and Offset
4015 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4021 * We are writing a "Record_Type" record
4023 Set_VMS_Object_File_Record (Record_Type
);
4025 * If the buffer is empty we must insert the record type
4027 if (Object_Record_Offset
== 0)
4028 PUT_CHAR (Record_Type
);
4030 * Stack the Psect base + Longword Offset
4032 if (Psect_Index
< 255)
4034 PUT_CHAR (TIR_S_C_STA_PL
);
4035 PUT_CHAR (Psect_Index
);
4039 PUT_CHAR (TIR_S_C_STA_WPL
);
4040 PUT_SHORT (Psect_Index
);
4044 * Set relocation base
4046 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4048 * Flush the buffer if it is more than 75% full
4050 if (Object_Record_Offset
>
4051 (sizeof (Object_Record_Buffer
) * 3 / 4))
4052 Flush_VMS_Object_Record_Buffer ();
4057 * Store repeated immediate data in current Psect
4060 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4062 register char *Pointer
;
4068 * Ignore zero bytes/words/longwords
4070 if ((Size
== sizeof (char)) && (*Pointer
== 0))
4072 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
4074 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
4077 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4078 * then we do it manually
4082 while (--Repeat_Count
>= 0)
4083 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4087 * We are writing a "Record_Type" record
4089 Set_VMS_Object_File_Record (Record_Type
);
4091 * If the buffer is empty we must insert record type
4093 if (Object_Record_Offset
== 0)
4094 PUT_CHAR (Record_Type
);
4096 * Stack the repeat count
4098 PUT_CHAR (TIR_S_C_STA_LW
);
4099 PUT_LONG (Repeat_Count
);
4101 * And now the command and its data
4103 PUT_CHAR (TIR_S_C_STO_RIVB
);
4106 PUT_CHAR (*Pointer
++);
4108 * Flush the buffer if it is more than 75% full
4110 if (Object_Record_Offset
>
4111 (sizeof (Object_Record_Buffer
) * 3 / 4))
4112 Flush_VMS_Object_Record_Buffer ();
4117 * Store a Position Independent Reference
4120 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4121 Psect
, Psect_Offset
, Record_Type
)
4122 struct symbol
*Symbol
;
4129 register struct VMS_Symbol
*vsp
=
4130 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4134 * We are writing a "Record_Type" record
4136 Set_VMS_Object_File_Record (Record_Type
);
4138 * If the buffer is empty we must insert record type
4140 if (Object_Record_Offset
== 0)
4141 PUT_CHAR (Record_Type
);
4143 * Set to the appropriate offset in the Psect
4148 * For a Code reference we need to fix the operand
4149 * specifier as well (so back up 1 byte)
4151 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4156 * For a Data reference we just store HERE
4158 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4161 * Make sure we are still generating a "Record Type" record
4163 if (Object_Record_Offset
== 0)
4164 PUT_CHAR (Record_Type
);
4166 * Dispatch on symbol type (so we can stack its value)
4168 switch (S_GET_RAW_TYPE (Symbol
))
4173 #ifdef NOT_VAX_11_C_COMPATIBLE
4174 case N_UNDF
| N_EXT
:
4175 case N_DATA
| N_EXT
:
4176 #endif /* NOT_VAX_11_C_COMPATIBLE */
4178 case N_TEXT
| N_EXT
:
4180 * Get the symbol name (case hacked)
4182 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4184 * Stack the global symbol value
4186 PUT_CHAR (TIR_S_C_STA_GBL
);
4187 PUT_COUNTED_STRING (Local
);
4191 * Stack the longword offset
4193 PUT_CHAR (TIR_S_C_STA_LW
);
4196 * Add the two, leaving the result on the stack
4198 PUT_CHAR (TIR_S_C_OPR_ADD
);
4202 * Uninitialized local data
4206 * Stack the Psect (+offset)
4208 if (vsp
->Psect_Index
< 255)
4210 PUT_CHAR (TIR_S_C_STA_PL
);
4211 PUT_CHAR (vsp
->Psect_Index
);
4215 PUT_CHAR (TIR_S_C_STA_WPL
);
4216 PUT_SHORT (vsp
->Psect_Index
);
4218 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4225 * Stack the Psect (+offset)
4227 if (vsp
->Psect_Index
< 255)
4229 PUT_CHAR (TIR_S_C_STA_PL
);
4230 PUT_CHAR (vsp
->Psect_Index
);
4234 PUT_CHAR (TIR_S_C_STA_WPL
);
4235 PUT_SHORT (vsp
->Psect_Index
);
4237 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4240 * Initialized local or global data
4243 #ifndef NOT_VAX_11_C_COMPATIBLE
4244 case N_UNDF
| N_EXT
:
4245 case N_DATA
| N_EXT
:
4246 #endif /* NOT_VAX_11_C_COMPATIBLE */
4248 * Stack the Psect (+offset)
4250 if (vsp
->Psect_Index
< 255)
4252 PUT_CHAR (TIR_S_C_STA_PL
);
4253 PUT_CHAR (vsp
->Psect_Index
);
4257 PUT_CHAR (TIR_S_C_STA_WPL
);
4258 PUT_SHORT (vsp
->Psect_Index
);
4260 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4264 * Store either a code or data reference
4266 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4268 * Flush the buffer if it is more than 75% full
4270 if (Object_Record_Offset
>
4271 (sizeof (Object_Record_Buffer
) * 3 / 4))
4272 Flush_VMS_Object_Record_Buffer ();
4277 * Check in the text area for an indirect pc-relative reference
4278 * and fix it up with addressing mode 0xff [PC indirect]
4280 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4281 * PIC CODE GENERATING FIXUP ROUTINE.
4284 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4287 register fragS
*fragP
;
4288 struct frag
*text_frag_root
;
4291 * The addressing mode byte is 1 byte before the address
4295 * Is it in THIS frag??
4297 if ((Offset
< fragP
->fr_address
) ||
4298 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4301 * We need to search for the fragment containing this
4304 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4306 if ((Offset
>= fragP
->fr_address
) &&
4307 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4311 * If we couldn't find the frag, things are BAD!!
4314 error ("Couldn't find fixup fragment when checking for indirect reference");
4317 * Check for indirect PC relative addressing mode
4319 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4321 static char Address_Mode
= 0xff;
4324 * Yes: Store the indirect mode back into the image
4325 * to fix up the damage done by STO_PICR
4327 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4328 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4335 * This is a hacked _doprnt() for VAX-11 "C". It understands that
4336 * it is ONLY called by as_fatal(Format, Args) with a pointer to the
4337 * "Args" argument. From this we can make it all work right!
4339 #if !defined(eunice) && defined(HO_VMS)
4340 _doprnt (Format
, a
, f
)
4345 int Nargs
= ((int *) a
)[-2]; /* This understands as_fatal() */
4350 fprintf (f
, "_doprnt error on \"%s\"!!", Format
);
4353 fprintf (f
, Format
);
4356 fprintf (f
, Format
, a
[0]);
4359 fprintf (f
, Format
, a
[0], a
[1]);
4362 fprintf (f
, Format
, a
[0], a
[1], a
[2]);
4365 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3]);
4368 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4]);
4371 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
4374 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6]);
4377 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]);
4380 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8]);
4389 * If the procedure "main()" exists we have to add the instruction
4390 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4392 VMS_Check_For_Main ()
4394 register symbolS
*symbolP
;
4395 #ifdef HACK_DEC_C_STARTUP /* JF */
4396 register struct frchain
*frchainP
;
4397 register fragS
*fragP
;
4398 register fragS
**prev_fragPP
;
4399 register struct fix
*fixP
;
4400 register fragS
*New_Frag
;
4402 #endif /* HACK_DEC_C_STARTUP */
4404 symbolP
= (struct symbol
*) symbol_find ("_main");
4405 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4406 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4408 #ifdef HACK_DEC_C_STARTUP
4413 * Remember the entry point symbol
4415 Entry_Point_Symbol
= symbolP
;
4416 #ifdef HACK_DEC_C_STARTUP
4421 * Scan all the fragment chains for the one with "_main"
4422 * (Actually we know the fragment from the symbol, but we need
4423 * the previous fragment so we can change its pointer)
4425 frchainP
= frchain_root
;
4429 * Scan all the fragments in this chain, remembering
4430 * the "previous fragment"
4432 prev_fragPP
= &frchainP
->frch_root
;
4433 fragP
= frchainP
->frch_root
;
4434 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4437 * Is this the fragment?
4439 if (fragP
== symbolP
->sy_frag
)
4442 * Yes: Modify the fragment by replacing
4443 * it with a new fragment.
4445 New_Frag
= (fragS
*)
4446 xmalloc (sizeof (*New_Frag
) +
4451 * The fragments are the same except
4452 * that the "fixed" area is larger
4455 New_Frag
->fr_fix
+= 6;
4457 * Copy the literal data opening a hole
4458 * 2 bytes after "_main" (i.e. just after
4459 * the entry mask). Into which we place
4460 * the JSB instruction.
4462 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4463 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4464 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4465 New_Frag
->fr_literal
[3] = 0xef;
4466 New_Frag
->fr_literal
[4] = 0;
4467 New_Frag
->fr_literal
[5] = 0;
4468 New_Frag
->fr_literal
[6] = 0;
4469 New_Frag
->fr_literal
[7] = 0;
4470 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4471 New_Frag
->fr_literal
[i
+ 6] =
4472 fragP
->fr_literal
[i
];
4474 * Now replace the old fragment with the
4475 * newly generated one.
4477 *prev_fragPP
= New_Frag
;
4479 * Remember the entry point symbol
4481 Entry_Point_Symbol
= symbolP
;
4483 * Scan the text area fixup structures
4484 * as offsets in the fragment may have
4487 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4490 * Look for references to this
4493 if (fixP
->fx_frag
== fragP
)
4496 * Change the fragment
4499 fixP
->fx_frag
= New_Frag
;
4501 * If the offset is after
4502 * the entry mask we need
4503 * to account for the JSB
4504 * instruction we just
4507 if (fixP
->fx_where
>= 2)
4508 fixP
->fx_where
+= 6;
4512 * Scan the symbols as offsets in the
4513 * fragment may have changed
4515 for (symbolP
= symbol_rootP
;
4517 symbolP
= symbol_next (symbolP
))
4520 * Look for references to this
4523 if (symbolP
->sy_frag
== fragP
)
4526 * Change the fragment
4529 symbolP
->sy_frag
= New_Frag
;
4531 * If the offset is after
4532 * the entry mask we need
4533 * to account for the JSB
4534 * instruction we just
4537 if (S_GET_VALUE (symbolP
) >= 2)
4538 S_GET_VALUE (symbolP
) += 6;
4542 * Make a symbol reference to
4543 * "_c$main_args" so we can get
4544 * its address inserted into the
4547 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4548 S_GET_NAME (symbolP
) = "_c$main_args";
4549 S_SET_TYPE (symbolP
, N_UNDF
);
4550 S_GET_OTHER (symbolP
) = 0;
4551 S_GET_DESC (symbolP
) = 0;
4552 S_GET_VALUE (symbolP
) = 0;
4553 symbolP
->sy_name_offset
= 0;
4554 symbolP
->sy_number
= 0;
4555 symbolP
->sy_frag
= New_Frag
;
4556 symbolP
->sy_forward
= 0;
4557 /* this actually inserts at the beginning of the list */
4558 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4560 symbol_rootP
= symbolP
;
4562 * Generate a text fixup structure
4563 * to get "_c$main_args" stored into the
4566 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4567 fixP
->fx_frag
= New_Frag
;
4569 fixP
->fx_addsy
= symbolP
;
4571 fixP
->fx_offset
= 0;
4572 fixP
->fx_size
= sizeof (long);
4574 fixP
->fx_next
= text_fix_root
;
4575 text_fix_root
= fixP
;
4577 * Now make sure we exit from the loop
4583 * Try the next fragment
4585 prev_fragPP
= &fragP
->fr_next
;
4586 fragP
= fragP
->fr_next
;
4589 * Try the next fragment chain
4592 frchainP
= frchainP
->frch_next
;
4595 #endif /* HACK_DEC_C_STARTUP */
4600 * Write a VAX/VMS object file (everything else has been done!)
4602 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4607 struct frag
*text_frag_root
;
4608 struct frag
*data_frag_root
;
4610 register fragS
*fragP
;
4611 register symbolS
*symbolP
;
4612 register symbolS
*sp
;
4613 register struct fix
*fixP
;
4614 register struct VMS_Symbol
*vsp
;
4616 int Local_Initialized_Data_Size
= 0;
4618 int Psect_Number
= 0; /* Psect Index Number */
4619 int Text_Psect
= -1; /* Text Psect Index */
4620 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4621 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4624 * Create the VMS object file
4626 Create_VMS_Object_File ();
4628 * Write the module header records
4630 Write_VMS_MHD_Records ();
4633 * Store the Data segment:
4635 * Since this is REALLY hard to do any other way,
4636 * we actually manufacture the data segment and
4637 * the store the appropriate values out of it.
4638 * We need to generate this early, so that globalvalues
4639 * can be properly emitted.
4644 * Allocate the data segment
4646 Data_Segment
= (char *) xmalloc (data_siz
);
4648 * Run through the data fragments, filling in the segment
4650 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4652 register long int count
;
4653 register char *fill_literal
;
4654 register long int fill_size
;
4657 i
= fragP
->fr_address
- text_siz
;
4659 memcpy (Data_Segment
+ i
,
4664 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4665 fill_size
= fragP
->fr_var
;
4666 for (count
= fragP
->fr_offset
; count
; count
--)
4669 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4677 * Generate the VMS object file records
4678 * 1st GSD then TIR records
4681 /******* Global Symbol Dictionary *******/
4683 * Emit globalvalues now. We must do this before the text psect
4684 * is defined, or we will get linker warnings about multiply defined
4685 * symbols. All of the globalvalues "reference" psect 0, although
4686 * it really does not have anything to do with it.
4688 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4690 * Define the Text Psect
4692 Text_Psect
= Psect_Number
++;
4693 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4695 * Define the BSS Psect
4699 Bss_Psect
= Psect_Number
++;
4700 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4702 #ifndef gxx_bug_fixed
4704 * The g++ compiler does not write out external references to vtables
4705 * correctly. Check for this and holler if we see it happening.
4706 * If that compiler bug is ever fixed we can remove this.
4708 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4711 * Dispatch on symbol type
4713 switch (S_GET_RAW_TYPE (sp
)) {
4719 * Make a GSD global symbol reference
4722 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4724 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4725 as_warn("g++ wrote an extern reference to %s as a routine.",
4727 as_warn("I will fix it, but I hope that it was not really a routine");
4734 #endif /* gxx_bug_fixed */
4736 * Now scan the symbols and emit the appropriate GSD records
4738 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4741 * Dispatch on symbol type
4743 switch (S_GET_RAW_TYPE (sp
))
4746 * Global uninitialized data
4748 case N_UNDF
| N_EXT
:
4750 * Make a VMS data symbol entry
4752 vsp
= (struct VMS_Symbol
*)
4753 xmalloc (sizeof (*vsp
));
4755 vsp
->Size
= S_GET_VALUE (sp
);
4756 vsp
->Psect_Index
= Psect_Number
++;
4757 vsp
->Psect_Offset
= 0;
4758 vsp
->Next
= VMS_Symbols
;
4760 sp
->sy_number
= (int) vsp
;
4762 * Make the psect for this data
4764 if (S_GET_OTHER (sp
))
4765 Globalref
= VMS_Psect_Spec (
4771 Globalref
= VMS_Psect_Spec (
4779 /* See if this is an external vtable. We want to help the linker find
4780 these things in libraries, so we make a symbol reference. This
4781 is not compatible with VAX-C usage for variables, but since vtables are
4782 only used internally by g++, we can get away with this hack. */
4784 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4785 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4790 #ifdef NOT_VAX_11_C_COMPATIBLE
4792 * Place a global symbol at the
4793 * beginning of the Psect
4795 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4799 #endif /* NOT_VAX_11_C_COMPATIBLE */
4802 * Local uninitialized data
4806 * Make a VMS data symbol entry
4808 vsp
= (struct VMS_Symbol
*)
4809 xmalloc (sizeof (*vsp
));
4812 vsp
->Psect_Index
= Bss_Psect
;
4815 bss_address_frag
.fr_address
;
4816 vsp
->Next
= VMS_Symbols
;
4818 sp
->sy_number
= (int) vsp
;
4821 * Global initialized data
4823 case N_DATA
| N_EXT
:
4825 * Make a VMS data symbol entry
4827 vsp
= (struct VMS_Symbol
*)
4828 xmalloc (sizeof (*vsp
));
4830 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4831 text_siz
+ data_siz
);
4832 vsp
->Psect_Index
= Psect_Number
++;
4833 vsp
->Psect_Offset
= 0;
4834 vsp
->Next
= VMS_Symbols
;
4836 sp
->sy_number
= (int) vsp
;
4840 if (S_GET_OTHER (sp
))
4841 Globalref
= VMS_Psect_Spec (
4847 Globalref
= VMS_Psect_Spec (
4855 /* See if this is an external vtable. We want to help the linker find
4856 these things in libraries, so we make a symbol definition. This
4857 is not compatible with VAX-C usage for variables, but since vtables are
4858 only used internally by g++, we can get away with this hack. */
4860 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4861 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4866 #ifdef NOT_VAX_11_C_COMPATIBLE
4868 * Place a global symbol at the
4869 * beginning of the Psect
4871 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4875 #endif /* NOT_VAX_11_C_COMPATIBLE */
4878 * Local initialized data
4882 * Make a VMS data symbol entry
4884 vsp
= (struct VMS_Symbol
*)
4885 xmalloc (sizeof (*vsp
));
4888 VMS_Initialized_Data_Size (sp
,
4889 text_siz
+ data_siz
);
4890 vsp
->Psect_Index
= Data_Psect
;
4892 Local_Initialized_Data_Size
;
4893 Local_Initialized_Data_Size
+= vsp
->Size
;
4894 vsp
->Next
= VMS_Symbols
;
4896 sp
->sy_number
= (int) vsp
;
4899 * Global Text definition
4901 case N_TEXT
| N_EXT
:
4903 unsigned short Entry_Mask
;
4906 * Get the entry mask
4908 fragP
= sp
->sy_frag
;
4909 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4910 ((fragP
->fr_literal
[1] & 0xff)
4913 * Define the Procedure entry pt.
4915 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4922 * Local Text definition
4926 * Make a VMS data symbol entry
4928 if (Text_Psect
!= -1)
4930 vsp
= (struct VMS_Symbol
*)
4931 xmalloc (sizeof (*vsp
));
4934 vsp
->Psect_Index
= Text_Psect
;
4935 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4936 vsp
->Next
= VMS_Symbols
;
4938 sp
->sy_number
= (int) vsp
;
4946 * Make a GSD global symbol reference
4949 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4959 * Ignore STAB symbols
4960 * Including .stabs emitted by g++
4962 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4967 if (S_GET_TYPE (sp
) != 22)
4968 printf (" ERROR, unknown type (%d)\n",
4974 * Define the Data Psect
4976 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4981 Data_Psect
= Psect_Number
++;
4982 VMS_Psect_Spec ("$data",
4983 Local_Initialized_Data_Size
,
4986 * Scan the VMS symbols and fill in the data psect
4988 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4991 * Only look for undefined psects
4993 if (vsp
->Psect_Index
< 0)
4996 * And only initialized data
4998 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4999 vsp
->Psect_Index
= Data_Psect
;
5004 /******* Text Information and Relocation Records *******/
5006 * Write the text segment data
5011 * Scan the text fragments
5013 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
5016 * Stop if we get to the data fragments
5018 if (fragP
== data_frag_root
)
5021 * Ignore fragments with no data
5023 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5026 * Go the the appropriate offset in the
5029 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5031 * Store the "fixed" part
5034 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5038 * Store the "variable" part
5040 if (fragP
->fr_var
&& fragP
->fr_offset
)
5041 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5048 * Now we go through the text segment fixups and
5049 * generate TIR records to fix up addresses within
5052 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5055 * We DO handle the case of "Symbol - Symbol" as
5056 * long as it is in the same segment.
5058 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5063 * They need to be in the same segment
5065 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5066 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5067 error ("Fixup data addsy and subsy didn't have the same type");
5069 * And they need to be in one that we
5070 * can check the psect on
5072 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5073 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5074 error ("Fixup data addsy and subsy didn't have an appropriate type");
5076 * This had better not be PC relative!
5079 error ("Fixup data was erroneously \"pcrel\"");
5081 * Subtract their values to get the
5084 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5085 S_GET_VALUE (fixP
->fx_subsy
);
5087 * Now generate the fixup object records
5088 * Set the psect and store the data
5090 VMS_Set_Psect (Text_Psect
,
5092 fixP
->fx_frag
->fr_address
,
5094 VMS_Store_Immediate_Data (&i
,
5103 * Size will HAVE to be "long"
5105 if (fixP
->fx_size
!= sizeof (long))
5106 error ("Fixup datum was not a longword");
5108 * Symbol must be "added" (if it is ever
5110 * fix this assumption)
5112 if (fixP
->fx_addsy
== 0)
5113 error ("Fixup datum was not \"fixP->fx_addsy\"");
5115 * Store the symbol value in a PIC fashion
5117 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5122 fixP
->fx_frag
->fr_address
,
5125 * Check for indirect address reference,
5126 * which has to be fixed up (as the linker
5127 * will screw it up with TIR_S_C_STO_PICR).
5130 VMS_Fix_Indirect_Reference (Text_Psect
,
5132 fixP
->fx_frag
->fr_address
,
5138 * Store the Data segment:
5140 * Since this is REALLY hard to do any other way,
5141 * we actually manufacture the data segment and
5142 * the store the appropriate values out of it.
5143 * The segment was manufactured before, now we just
5144 * dump it into the appropriate psects.
5150 * Now we can run through all the data symbols
5151 * and store the data
5153 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5156 * Ignore anything other than data symbols
5158 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5161 * Set the Psect + Offset
5163 VMS_Set_Psect (vsp
->Psect_Index
,
5169 VMS_Store_Immediate_Data (Data_Segment
+
5170 S_GET_VALUE (vsp
->Symbol
) -
5176 * Now we go through the data segment fixups and
5177 * generate TIR records to fix up addresses within
5180 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5183 * Find the symbol for the containing datum
5185 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5188 * Only bother with Data symbols
5191 if (S_GET_TYPE (sp
) != N_DATA
)
5194 * Ignore symbol if After fixup
5196 if (S_GET_VALUE (sp
) >
5198 fixP
->fx_frag
->fr_address
))
5201 * See if the datum is here
5203 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5205 fixP
->fx_frag
->fr_address
))
5208 * We DO handle the case of "Symbol - Symbol" as
5209 * long as it is in the same segment.
5211 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5216 * They need to be in the same segment
5218 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5219 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5220 error ("Fixup data addsy and subsy didn't have the same type");
5222 * And they need to be in one that we
5223 * can check the psect on
5225 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5226 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5227 error ("Fixup data addsy and subsy didn't have an appropriate type");
5229 * This had better not be PC relative!
5232 error ("Fixup data was erroneously \"pcrel\"");
5234 * Subtract their values to get the
5237 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5238 S_GET_VALUE (fixP
->fx_subsy
);
5240 * Now generate the fixup object records
5241 * Set the psect and store the data
5243 VMS_Set_Psect (vsp
->Psect_Index
,
5244 fixP
->fx_frag
->fr_address
+
5246 S_GET_VALUE (vsp
->Symbol
) +
5249 VMS_Store_Immediate_Data (&i
,
5258 * Size will HAVE to be "long"
5260 if (fixP
->fx_size
!= sizeof (long))
5261 error ("Fixup datum was not a longword");
5263 * Symbol must be "added" (if it is ever
5265 * fix this assumption)
5267 if (fixP
->fx_addsy
== 0)
5268 error ("Fixup datum was not \"fixP->fx_addsy\"");
5270 * Store the symbol value in a PIC fashion
5272 VMS_Store_PIC_Symbol_Reference (
5277 fixP
->fx_frag
->fr_address
+
5279 S_GET_VALUE (vsp
->Symbol
) +
5292 * Write the Traceback Begin Module record
5294 VMS_TBT_Module_Begin ();
5296 * Scan the symbols and write out the routines
5297 * (this makes the assumption that symbols are in
5298 * order of ascending text segment offset)
5301 struct symbol
*Current_Routine
= 0;
5302 int Current_Line_Number
= 0;
5303 int Current_Offset
= -1;
5304 struct input_file
*Current_File
;
5306 /* Output debugging info for global variables and static variables that are not
5307 * specific to one routine. We also need to examine all stabs directives, to
5308 * find the definitions to all of the advanced data types, and this is done by
5309 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5310 * the object file, since there can be forward references in the stabs
5311 * directives. When through with parsing, the text of the stabs directive
5312 * is altered, with the definitions removed, so that later passes will see
5313 * directives as they would be written if the type were already defined.
5315 * We also look for files and include files, and make a list of them. We
5316 * examine the source file numbers to establish the actual lines that code was
5317 * generated from, and then generate offsets.
5320 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5323 * Deal with STAB symbols
5325 if (S_IS_DEBUG (symbolP
))
5328 * Dispatch on STAB type
5330 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5333 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5334 Current_File
->max_line
= S_GET_DESC (symbolP
);
5335 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5336 Current_File
->min_line
= S_GET_DESC (symbolP
);
5339 Current_File
= find_file (symbolP
);
5340 Current_File
->flag
= 1;
5341 Current_File
->min_line
= 1;
5344 Current_File
= find_file (symbolP
);
5347 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5350 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5352 case N_FUN
: /* For static constant symbols */
5354 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5360 /* now we take a quick sweep through the files and assign offsets
5361 to each one. This will essentially be the starting line number to the
5362 debugger for each file. Output the info for the debugger to specify the
5363 files, and then tell it how many lines to use */
5365 int File_Number
= 0;
5366 int Debugger_Offset
= 0;
5368 Current_File
= file_root
;
5369 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5371 if (Current_File
== (struct input_file
*) NULL
)
5373 if (Current_File
->max_line
== 0)
5375 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5378 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5381 /* show a few extra lines at the start of the region selected */
5382 if (Current_File
->min_line
> 2)
5383 Current_File
->min_line
-= 2;
5384 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5385 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5386 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5387 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5390 Current_File
->file_number
= ++File_Number
;
5391 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5392 Current_File
->file_number
);
5393 if (!file_available
)
5395 Current_File
->file_number
= 0;
5400 VMS_TBT_Source_Lines (Current_File
->file_number
,
5401 Current_File
->min_line
,
5402 Current_File
->max_line
- Current_File
->min_line
+ 1);
5405 Current_File
= (struct input_file
*) NULL
;
5407 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5410 * Deal with text symbols
5412 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5415 * Ignore symbols starting with "L",
5416 * as they are local symbols
5418 if (*S_GET_NAME (symbolP
) == 'L')
5421 * If there is a routine start defined,
5424 if (Current_Routine
)
5429 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5432 * Store the routine begin traceback info
5434 if (Text_Psect
!= -1)
5436 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5437 Current_Routine
= symbolP
;
5439 /* Output local symbols, i.e. all symbols that are associated with a specific
5440 * routine. We output them now so the debugger recognizes them as local to
5447 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5449 if (!S_IS_DEBUG (symbolP1
))
5451 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5453 pnt
= S_GET_NAME (symbolP
);
5454 pnt1
= S_GET_NAME (symbolP1
);
5457 while (*pnt
++ == *pnt1
++)
5460 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5461 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5464 if (symbolP1
!= (symbolS
*) NULL
)
5465 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5466 } /* local symbol block */
5473 * Deal with STAB symbols
5475 if (S_IS_DEBUG (symbolP
))
5478 * Dispatch on STAB type
5480 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5486 /* Offset the line into the correct portion
5488 if (Current_File
->file_number
== 0)
5490 /* Sometimes the same offset gets several source
5491 * lines assigned to it.
5492 * We should be selective about which lines
5493 * we allow, we should prefer lines that are
5494 * in the main source file when debugging
5495 * inline functions. */
5496 if ((Current_File
->file_number
!= 1) &&
5497 S_GET_VALUE (symbolP
) ==
5500 /* calculate actual debugger source line */
5501 S_GET_DESC (symbolP
)
5502 += Current_File
->offset
;
5504 * If this is the 1st N_SLINE, setup
5505 * PC/Line correlation. Otherwise
5506 * do the delta PC/Line. If the offset
5507 * for the line number is not +ve we need
5508 * to do another PC/Line correlation
5511 if (Current_Offset
== -1)
5513 VMS_TBT_Line_PC_Correlation (
5514 S_GET_DESC (symbolP
),
5515 S_GET_VALUE (symbolP
),
5521 if ((S_GET_DESC (symbolP
) -
5522 Current_Line_Number
) <= 0)
5525 * Line delta is not +ve, we
5526 * need to close the line and
5527 * start a new PC/Line
5530 VMS_TBT_Line_PC_Correlation (0,
5531 S_GET_VALUE (symbolP
) -
5535 VMS_TBT_Line_PC_Correlation (
5536 S_GET_DESC (symbolP
),
5537 S_GET_VALUE (symbolP
),
5544 * Line delta is +ve, all is well
5546 VMS_TBT_Line_PC_Correlation (
5547 S_GET_DESC (symbolP
) -
5548 Current_Line_Number
,
5549 S_GET_VALUE (symbolP
) -
5556 * Update the current line/PC
5558 Current_Line_Number
= S_GET_DESC (symbolP
);
5559 Current_Offset
= S_GET_VALUE (symbolP
);
5569 * Remember that we had a source file
5570 * and emit the source file debugger
5574 find_file (symbolP
);
5576 /* We need to make sure that we are really in the actual source file when
5577 * we compute the maximum line number. Otherwise the debugger gets really
5581 find_file (symbolP
);
5587 * If there is a routine start defined,
5588 * terminate it (and the line numbers)
5590 if (Current_Routine
)
5593 * Terminate the line numbers
5595 VMS_TBT_Line_PC_Correlation (0,
5596 text_siz
- S_GET_VALUE (Current_Routine
),
5600 * Terminate the routine
5602 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5606 * Write the Traceback End Module TBT record
5608 VMS_TBT_Module_End ();
5611 * Write the End Of Module record
5613 if (Entry_Point_Symbol
== 0)
5614 Write_VMS_EOM_Record (-1, 0);
5616 Write_VMS_EOM_Record (Text_Psect
,
5617 S_GET_VALUE (Entry_Point_Symbol
));
5620 * All done, close the object file
5622 Close_VMS_Object_File ();
5625 /* end of obj-vms.c */