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
28 /* What we do if there is a goof. */
29 #define error as_fatal
31 #ifdef HO_VMS /* These are of no use if we are cross assembling. */
32 #include <fab.h> /* Define File Access Block */
33 #include <nam.h> /* Define NAM Block */
34 #include <xab.h> /* Define XAB - all different types*/
37 * Version string of the compiler that produced the code we are
38 * assembling. (And this assembler, if we do not have compiler info.)
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 /* description of what this is */
117 enum advanced_type advanced
;
118 /* this record is for this type */
120 /* For advanced types this is the type referred to. I.e., the type
121 a pointer points to, or the type of object that makes up an
124 /* Use this type when generating a variable def */
126 /* used for arrays - this will be present for all */
128 /* entries, but will be meaningless for non-arrays */
130 /* Size in bytes of the data type. For an array, this is the size
131 of one element in the array */
133 /* Number of the structure/union/enum - used for ref */
137 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
;
140 * We need this structure to keep track of forward references to
141 * struct/union/enum that have not been defined yet. When they are ultimately
142 * defined, then we can go back and generate the TIR commands to make a back
148 struct forward_ref
*next
;
154 struct forward_ref
*f_ref_root
=
155 {(struct forward_ref
*) NULL
};
158 * This routine is used to compare the names of certain types to various
159 * fixed types that are known by the debugger.
161 #define type_check(x) !strcmp( symbol_name , x )
164 * This variable is used to keep track of the name of the symbol we are
165 * working on while we are parsing the stabs directives.
167 static char *symbol_name
;
169 /* We use this counter to assign numbers to all of the structures, unions
170 * and enums that we define. When we actually declare a variable to the
171 * debugger, we can simply do it by number, rather than describing the
172 * whole thing each time.
175 static structure_count
= 0;
177 /* This variable is used to indicate that we are making the last attempt to
178 parse the stabs, and that we should define as much as we can, and ignore
181 static int final_pass
;
183 /* This variable is used to keep track of the current structure number
184 * for a given variable. If this is < 0, that means that the structure
185 * has not yet been defined to the debugger. This is still cool, since
186 * the VMS object language has ways of fixing things up after the fact,
187 * so we just make a note of this, and generate fixups at the end.
189 static int struct_number
;
193 * Variable descriptors are used tell the debugger the data types of certain
194 * more complicated variables (basically anything involving a structure,
195 * union, enum, array or pointer). Some non-pointer variables of the
196 * basic types that the debugger knows about do not require a variable
199 * Since it is impossible to have a variable descriptor longer than 128
200 * bytes by virtue of the way that the VMS object language is set up,
201 * it makes not sense to make the arrays any longer than this, or worrying
202 * about dynamic sizing of the array.
204 * These are the arrays and counters that we use to build a variable
208 #define MAX_DEBUG_RECORD 128
209 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
210 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
211 static int Lpnt
; /* index into Local */
212 static int Apoint
; /* index into Asuffix */
213 static char overflow
; /* flag to indicate we have written too much*/
214 static int total_len
; /* used to calculate the total length of variable
215 descriptor plus array descriptor - used for len byte*/
217 /* Flag if we have told user about finding global constants in the text
219 static gave_compiler_message
= 0;
221 /* A pointer to the current routine that we are working on. */
223 static symbolS
*Current_Routine
;
225 /* The psect number for $code a.k.a. the text section. */
227 static int Text_Psect
;
231 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
233 static int VMS_Object_File_FD
; /* File Descriptor for object file */
234 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
235 static int Object_Record_Offset
;/* Offset to end of data */
236 static int Current_Object_Record_Type
; /* Type of record in above */
239 * Macros for moving data around. Must work on big-endian systems.
241 #ifdef HO_VMS /* These are more efficient for VMS->VMS systems */
242 #define COPY_LONG(dest,val) {*(long *) dest = val; }
243 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
245 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
246 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
249 * Macros for placing data into the object record buffer
252 #define PUT_LONG(val) \
253 { md_number_to_chars(Object_Record_Buffer + \
254 Object_Record_Offset, val, 4); \
255 Object_Record_Offset += 4; }
257 #define PUT_SHORT(val) \
258 { md_number_to_chars(Object_Record_Buffer + \
259 Object_Record_Offset, val, 2); \
260 Object_Record_Offset += 2; }
262 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
264 #define PUT_COUNTED_STRING(cp) {\
265 register char *p = cp; \
266 PUT_CHAR(strlen(p)); \
267 while (*p) PUT_CHAR(*p++);}
270 * Macro for determining if a Name has psect attributes attached
273 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
274 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
276 #define HAS_PSECT_ATTRIBUTES(Name) \
277 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
278 PSECT_ATTRIBUTES_STRING, \
279 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
282 /* in: segT out: N_TYPE bits */
283 const short seg_N_TYPE
[] =
289 N_UNDF
, /* unknown */
291 N_UNDF
, /* expression */
295 N_REGISTER
, /* register */
298 const segT N_TYPE_seg
[N_TYPE
+ 2] =
299 { /* N_TYPE == 0x1E = 32-2 */
300 SEG_UNKNOWN
, /* N_UNDF == 0 */
302 SEG_ABSOLUTE
, /* N_ABS == 2 */
304 SEG_TEXT
, /* N_TEXT == 4 */
306 SEG_DATA
, /* N_DATA == 6 */
308 SEG_BSS
, /* N_BSS == 8 */
310 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
311 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
312 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
313 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
318 /* The following code defines the special types of pseudo-ops that we
329 temp
= get_absolute_expression ();
330 subseg_new (SEG_DATA
, (subsegT
) temp
);
332 demand_empty_rest_of_line ();
338 * Handle .stabX directives, which used to be open-coded.
339 * So much creeping featurism overloaded the semantics that we decided
340 * to put all .stabX thinking in one place. Here.
342 * We try to make any .stabX directive legal. Other people's AS will often
343 * do assembly-time consistency checks: eg assigning meaning to n_type bits
344 * and "protecting" you from setting them to certain values. (They also zero
345 * certain bits before emitting symbols. Tut tut.)
347 * If an expression is not absolute we either gripe or use the relocation
348 * information. Other people's assemblers silently forget information they
349 * don't need and invent information they need that you didn't supply.
351 * .stabX directives always make a symbol table entry. It may be junk if
352 * the rest of your .stabX directive is malformed.
360 #endif /* NO_LISTING */
362 register symbolS
*symbolP
= 0;
363 register char *string
;
366 int goof
; /* TRUE if we have aborted. */
370 * Enter with input_line_pointer pointing past .stabX and any following
373 goof
= 0; /* JF who forgot this?? */
376 string
= demand_copy_C_string (&length
);
378 if (*input_line_pointer
== ',')
379 input_line_pointer
++;
382 as_bad ("I need a comma after symbol's name");
390 * Input_line_pointer->after ','. String->symbol name.
394 symbolP
= symbol_new (string
,
401 S_SET_NAME (symbolP
, NULL
); /* .stabd feature. */
402 S_SET_VALUE (symbolP
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
403 symbolP
->sy_frag
= frag_now
;
407 symbolP
->sy_frag
= &zero_address_frag
;
411 symbolP
->sy_frag
= &zero_address_frag
;
419 if (get_absolute_expression_and_terminator (&longint
) == ',')
420 symbolP
->sy_symbol
.n_type
= saved_type
= longint
;
423 as_bad ("I want a comma after the n_type expression");
425 input_line_pointer
--; /* Backup over a non-',' char. */
431 if (get_absolute_expression_and_terminator (&longint
) == ',')
432 S_SET_OTHER (symbolP
, longint
);
435 as_bad ("I want a comma after the n_other expression");
437 input_line_pointer
--; /* Backup over a non-',' char. */
443 S_SET_DESC (symbolP
, get_absolute_expression ());
444 if (what
== 's' || what
== 'n')
446 if (*input_line_pointer
!= ',')
448 as_bad ("I want a comma after the n_desc expression");
453 input_line_pointer
++;
458 if ((!goof
) && (what
== 's' || what
== 'n'))
460 pseudo_set (symbolP
);
461 symbolP
->sy_symbol
.n_type
= saved_type
;
465 if (listing
&& !goof
)
467 if (symbolP
->sy_symbol
.n_type
== N_SLINE
)
470 listing_source_line(symbolP
->sy_symbol
.n_desc
);
472 else if (symbolP
->sy_symbol
.n_type
== N_SO
473 || symbolP
->sy_symbol
.n_type
== N_SOL
)
475 listing_source_file(string
);
481 ignore_rest_of_line ();
483 demand_empty_rest_of_line ();
484 } /* obj_aout_stab() */
486 const pseudo_typeS obj_pseudo_table
[] =
488 {"stabd", obj_aout_stab
, 'd'},/* stabs */
489 {"stabn", obj_aout_stab
, 'n'},/* stabs */
490 {"stabs", obj_aout_stab
, 's'},/* stabs */
491 {"const", s_const
, 0},
494 }; /* obj_pseudo_table */
497 vms_resolve_symbol_redef (sym
)
501 * If the new symbol is .comm AND it has a size of zero,
502 * we ignore it (i.e. the old symbol overrides it)
504 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)) &&
505 ((obstack_next_free (&frags
) - frag_now
->fr_literal
) == 0))
507 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
512 * If the old symbol is .comm and it has a size of zero,
513 * we override it with the new symbol value.
515 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
516 && (S_GET_VALUE(sym
) == 0))
518 as_warn ("compiler redefined zero-size common symbol `%s'",
520 sym
->sy_frag
= frag_now
;
521 S_GET_OTHER(sym
) = const_flag
;
522 S_SET_VALUE(sym
, obstack_next_free(& frags
) - frag_now
->fr_literal
);
523 /* Keep N_EXT bit. */
524 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
533 obj_read_begin_hook ()
536 } /* obj_read_begin_hook() */
539 obj_crawl_symbol_chain (headers
)
540 object_headers
*headers
;
544 int symbol_number
= 0;
546 { /* crawl symbol table */
547 register int symbol_number
= 0;
550 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
551 while ((symbolP
= *symbolPP
) != NULL
)
553 resolve_symbol_value (symbolP
);
555 /* OK, here is how we decide which symbols go out into the
556 brave new symtab. Symbols that do are:
558 * symbols with no name (stabd's?)
559 * symbols with debug info in their N_TYPE
561 Symbols that don't are:
562 * symbols that are registers
563 * symbols with \1 as their 3rd character (numeric labels)
564 * "local labels" as defined by S_LOCAL_NAME(name)
565 if the -L switch was passed to gas.
567 All other symbols are output. We complain if a deleted
568 symbol was marked external. */
571 if (!S_IS_REGISTER (symbolP
))
573 symbolP
->sy_name_offset
= 0;
574 symbolPP
= &(symbol_next (symbolP
));
578 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
580 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
583 } /* if this symbol should be in the output */
584 } /* for each symbol */
586 H_SET_STRING_SIZE (headers
, string_byte_count
);
587 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
588 } /* crawl symbol table */
590 } /* obj_crawl_symbol_chain() */
593 /****** VMS OBJECT FILE HACKING ROUTINES *******/
597 * Create the VMS object file
600 Create_VMS_Object_File ()
602 #if defined(eunice) || !defined(HO_VMS)
603 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
605 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
606 "mbc=16", "deq=64", "fop=tef", "shr=nil");
611 if (VMS_Object_File_FD
< 0)
613 char Error_Line
[256];
615 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
620 * Initialize object file hacking variables
622 Object_Record_Offset
= 0;
623 Current_Object_Record_Type
= -1;
628 * Flush the object record buffer to the object file
631 Flush_VMS_Object_Record_Buffer ()
637 * If the buffer is empty, we are done
639 if (Object_Record_Offset
== 0)
642 * Write the data to the file
644 #ifndef HO_VMS /* For cross-assembly purposes. */
645 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
646 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
647 #endif /* not HO_VMS */
648 i
= write (VMS_Object_File_FD
,
649 Object_Record_Buffer
,
650 Object_Record_Offset
);
651 if (i
!= Object_Record_Offset
)
652 error ("I/O error writing VMS object file");
653 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
655 /* pad it if needed */
657 if (Object_Record_Offset
& 1 != 0)
658 write (VMS_Object_File_FD
, &zero
, 1);
659 #endif /* not HO_VMS */
661 * The buffer is now empty
663 Object_Record_Offset
= 0;
668 * Declare a particular type of object file record
671 Set_VMS_Object_File_Record (Type
)
675 * If the type matches, we are done
677 if (Type
== Current_Object_Record_Type
)
680 * Otherwise: flush the buffer
682 Flush_VMS_Object_Record_Buffer ();
686 Current_Object_Record_Type
= Type
;
692 * Close the VMS Object file
695 Close_VMS_Object_File ()
697 short int m_one
= -1;
698 #ifndef HO_VMS /* For cross-assembly purposes. */
699 /* Write a 0xffff into the file, which means "End of File" */
700 write (VMS_Object_File_FD
, &m_one
, 2);
701 #endif /* not HO_VMS */
702 close (VMS_Object_File_FD
);
707 * Store immediate data in current Psect
710 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
718 * We are writing a "Record_Type" record
720 Set_VMS_Object_File_Record (Record_Type
);
722 * We can only store 128 bytes at a time
727 * Store a maximum of 128 bytes
729 i
= (Size
> 128) ? 128 : Size
;
732 * If we cannot accommodate this record, flush the
735 if ((Object_Record_Offset
+ i
+ 1) >=
736 sizeof (Object_Record_Buffer
))
737 Flush_VMS_Object_Record_Buffer ();
739 * If the buffer is empty we must insert record type
741 if (Object_Record_Offset
== 0)
742 PUT_CHAR (Record_Type
);
746 PUT_CHAR (-i
& 0xff);
751 PUT_CHAR (*Pointer
++);
753 * Flush the buffer if it is more than 75% full
755 if (Object_Record_Offset
>
756 (sizeof (Object_Record_Buffer
) * 3 / 4))
757 Flush_VMS_Object_Record_Buffer ();
762 * Make a data reference
765 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
772 * We are writing a "Record_Type" record
774 Set_VMS_Object_File_Record (Record_Type
);
776 * If the buffer is empty we must insert the record type
778 if (Object_Record_Offset
== 0)
779 PUT_CHAR (Record_Type
);
781 * Stack the Psect base + Longword Offset
785 if (Psect_Index
> 127)
787 PUT_CHAR (TIR_S_C_STA_WPL
);
788 PUT_SHORT (Psect_Index
);
793 PUT_CHAR (TIR_S_C_STA_PL
);
794 PUT_CHAR (Psect_Index
);
802 PUT_CHAR (TIR_S_C_STA_WPL
);
803 PUT_SHORT (Psect_Index
);
806 else if (Offset
> 127)
808 PUT_CHAR (TIR_S_C_STA_WPW
);
809 PUT_SHORT (Psect_Index
);
814 PUT_CHAR (TIR_S_C_STA_WPB
);
815 PUT_SHORT (Psect_Index
);
820 * Set relocation base
822 PUT_CHAR (TIR_S_C_STO_PIDR
);
824 * Flush the buffer if it is more than 75% full
826 if (Object_Record_Offset
>
827 (sizeof (Object_Record_Buffer
) * 3 / 4))
828 Flush_VMS_Object_Record_Buffer ();
832 * Make a debugger reference to a struct, union or enum.
835 VMS_Store_Struct (Struct_Index
)
839 * We are writing a "OBJ_S_C_DBG" record
841 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
843 * If the buffer is empty we must insert the record type
845 if (Object_Record_Offset
== 0)
846 PUT_CHAR (OBJ_S_C_DBG
);
847 PUT_CHAR (TIR_S_C_STA_UW
);
848 PUT_SHORT (Struct_Index
);
849 PUT_CHAR (TIR_S_C_CTL_STKDL
);
850 PUT_CHAR (TIR_S_C_STO_L
);
852 * Flush the buffer if it is more than 75% full
854 if (Object_Record_Offset
>
855 (sizeof (Object_Record_Buffer
) * 3 / 4))
856 Flush_VMS_Object_Record_Buffer ();
860 * Make a debugger reference to partially define a struct, union or enum.
863 VMS_Def_Struct (Struct_Index
)
867 * We are writing a "OBJ_S_C_DBG" record
869 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
871 * If the buffer is empty we must insert the record type
873 if (Object_Record_Offset
== 0)
874 PUT_CHAR (OBJ_S_C_DBG
);
875 PUT_CHAR (TIR_S_C_STA_UW
);
876 PUT_SHORT (Struct_Index
);
877 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
879 * Flush the buffer if it is more than 75% full
881 if (Object_Record_Offset
>
882 (sizeof (Object_Record_Buffer
) * 3 / 4))
883 Flush_VMS_Object_Record_Buffer ();
887 VMS_Set_Struct (Struct_Index
)
889 { /* see previous functions for comments */
890 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
891 if (Object_Record_Offset
== 0)
892 PUT_CHAR (OBJ_S_C_DBG
);
893 PUT_CHAR (TIR_S_C_STA_UW
);
894 PUT_SHORT (Struct_Index
);
895 PUT_CHAR (TIR_S_C_CTL_STLOC
);
896 if (Object_Record_Offset
>
897 (sizeof (Object_Record_Buffer
) * 3 / 4))
898 Flush_VMS_Object_Record_Buffer ();
902 * Write the Traceback Module Begin record
905 VMS_TBT_Module_Begin ()
907 register char *cp
, *cp1
;
909 char Module_Name
[256];
913 * Get module name (the FILENAME part of the object file)
919 if ((*cp
== ']') || (*cp
== '>') ||
920 (*cp
== ':') || (*cp
== '/'))
926 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
930 * Limit it to 31 characters
932 while (--cp1
>= Module_Name
)
935 if (strlen (Module_Name
) > 31)
938 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
942 * Arrange to store the data locally (leave room for size byte)
948 *cp
++ = DST_S_C_MODBEG
;
954 * Language type == "C"
956 COPY_LONG (cp
, DST_S_C_C
);
959 * Store the module name
961 *cp
++ = strlen (Module_Name
);
966 * Now we can store the record size
971 * Put it into the object record
973 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
978 * Write the Traceback Module End record
981 VMS_TBT_Module_End ()
989 Local
[1] = DST_S_C_MODEND
;
991 * Put it into the object record
993 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
998 * Write the Traceback Routine Begin record
1001 VMS_TBT_Routine_Begin (symbolP
, Psect
)
1002 struct symbol
*symbolP
;
1005 register char *cp
, *cp1
;
1012 * Strip the leading "_" from the name
1014 Name
= S_GET_NAME (symbolP
);
1018 * Get the text psect offset
1020 Offset
= S_GET_VALUE (symbolP
);
1022 * Calculate the record size
1024 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1032 Local
[1] = DST_S_C_RTNBEG
;
1038 * Store the data so far
1040 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1042 * Make sure we are still generating a OBJ_S_C_TBT record
1044 if (Object_Record_Offset
== 0)
1045 PUT_CHAR (OBJ_S_C_TBT
);
1047 * Now get the symbol address
1049 PUT_CHAR (TIR_S_C_STA_WPL
);
1053 * Store the data reference
1055 PUT_CHAR (TIR_S_C_STO_PIDR
);
1057 * Store the counted string as data
1061 Size
= strlen (cp1
) + 1;
1065 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1070 * Write the Traceback Routine End record
1071 * We *must* search the symbol table to find the next routine, since
1072 * the assember has a way of reassembling the symbol table OUT OF ORDER
1073 * Thus the next routine in the symbol list is not necessarily the
1074 * next one in memory. For debugging to work correctly we must know the
1075 * size of the routine.
1078 VMS_TBT_Routine_End (Max_Size
, sp
)
1083 int Size
= 0x7fffffff;
1087 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1089 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1091 if (*S_GET_NAME (symbolP
) == 'L')
1093 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
1094 (S_GET_VALUE (symbolP
) < Size
))
1095 Size
= S_GET_VALUE (symbolP
);
1096 /* check if gcc_compiled. has size of zero */
1097 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
1099 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1100 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1101 Size
= S_GET_VALUE (symbolP
);
1105 if (Size
== 0x7fffffff)
1107 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
1115 Local
[1] = DST_S_C_RTNEND
;
1123 COPY_LONG (&Local
[3], Size
);
1127 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1131 * Write the Traceback Block End record
1134 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1135 struct symbol
*symbolP
;
1139 register char *cp
, *cp1
;
1146 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1152 * Begin Block - We simulate with a phony routine
1154 Local
[1] = DST_S_C_BLKBEG
;
1160 * Store the data so far
1162 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1164 * Make sure we are still generating a OBJ_S_C_DBG record
1166 if (Object_Record_Offset
== 0)
1167 PUT_CHAR (OBJ_S_C_DBG
);
1169 * Now get the symbol address
1171 PUT_CHAR (TIR_S_C_STA_WPL
);
1174 * Get the text psect offset
1176 Offset
= S_GET_VALUE (symbolP
);
1179 * Store the data reference
1181 PUT_CHAR (TIR_S_C_STO_PIDR
);
1183 * Store the counted string as data
1187 Size
= strlen (cp1
) + 1;
1191 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1196 * Write the Traceback Block End record
1199 VMS_TBT_Block_End (Size
)
1205 * End block - simulate with a phony end routine
1208 Local
[1] = DST_S_C_BLKEND
;
1209 COPY_LONG (&Local
[3], Size
);
1214 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1220 * Write a Line number / PC correlation record
1223 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1233 * If not delta, set our PC/Line number correlation
1240 Local
[0] = 1 + 1 + 2 + 1 + 4;
1242 * Line Number/PC correlation
1244 Local
[1] = DST_S_C_LINE_NUM
;
1248 Local
[2] = DST_S_C_SET_LINE_NUM
;
1249 COPY_SHORT (&Local
[3], Line_Number
- 1);
1253 Local
[5] = DST_S_C_SET_ABS_PC
;
1254 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1256 * Make sure we are still generating a OBJ_S_C_TBT record
1258 if (Object_Record_Offset
== 0)
1259 PUT_CHAR (OBJ_S_C_TBT
);
1262 PUT_CHAR (TIR_S_C_STA_PL
);
1267 PUT_CHAR (TIR_S_C_STA_WPL
);
1271 PUT_CHAR (TIR_S_C_STO_PIDR
);
1273 * Do a PC offset of 0 to register the line number
1276 Local
[1] = DST_S_C_LINE_NUM
;
1277 Local
[2] = 0; /* Increment PC by 0 and register line # */
1278 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1283 * If Delta is negative, terminate the line numbers
1287 Local
[0] = 1 + 1 + 4;
1288 Local
[1] = DST_S_C_LINE_NUM
;
1289 Local
[2] = DST_S_C_TERM_L
;
1290 COPY_LONG (&Local
[3], Offset
);
1291 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1298 * Do a PC/Line delta
1301 *cp
++ = DST_S_C_LINE_NUM
;
1302 if (Line_Number
> 1)
1305 * We need to increment the line number
1307 if (Line_Number
- 1 <= 255)
1309 *cp
++ = DST_S_C_INCR_LINUM
;
1310 *cp
++ = Line_Number
- 1;
1314 *cp
++ = DST_S_C_INCR_LINUM_W
;
1315 COPY_SHORT (cp
, Line_Number
- 1);
1316 cp
+= sizeof (short);
1328 if (Offset
< 0x10000)
1330 *cp
++ = DST_S_C_DELTA_PC_W
;
1331 COPY_SHORT (cp
, Offset
);
1332 cp
+= sizeof (short);
1336 *cp
++ = DST_S_C_DELTA_PC_L
;
1337 COPY_LONG (cp
, Offset
);
1338 cp
+= sizeof (long);
1341 Local
[0] = cp
- (Local
+ 1);
1342 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1348 * Describe a source file to the debugger
1351 VMS_TBT_Source_File (Filename
, ID_Number
)
1355 register char *cp
, *cp1
;
1358 #ifndef HO_VMS /* Used for cross-assembly */
1359 i
= strlen (Filename
);
1361 static struct FAB Fab
;
1362 static struct NAM Nam
;
1363 static struct XABDAT Date_Xab
;
1364 static struct XABFHC File_Header_Xab
;
1365 char Es_String
[255], Rs_String
[255];
1370 Fab
.fab$b_bid
= FAB$C_BID
;
1371 Fab
.fab$b_bln
= sizeof (Fab
);
1372 Fab
.fab$l_nam
= (&Nam
);
1373 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1375 * Setup the Nam block so we can find out the FULL name
1376 * of the source file.
1378 Nam
.nam$b_bid
= NAM$C_BID
;
1379 Nam
.nam$b_bln
= sizeof (Nam
);
1380 Nam
.nam$l_rsa
= Rs_String
;
1381 Nam
.nam$b_rss
= sizeof (Rs_String
);
1382 Nam
.nam$l_esa
= Es_String
;
1383 Nam
.nam$b_ess
= sizeof (Es_String
);
1385 * Setup the Date and File Header Xabs
1387 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1388 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1389 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1390 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1391 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1393 * Get the file information
1395 Fab
.fab$l_fna
= Filename
;
1396 Fab
.fab$b_fns
= strlen (Filename
);
1397 Status
= sys$
open (&Fab
);
1400 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1406 * Calculate the size of the resultant string
1413 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1415 * Source declaration
1417 Local
[1] = DST_S_C_SOURCE
;
1419 * Make formfeeds count as source records
1421 Local
[2] = DST_S_C_SRC_FORMFEED
;
1423 * Declare source file
1425 Local
[3] = DST_S_C_SRC_DECLFILE
;
1426 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1435 COPY_SHORT (cp
, ID_Number
);
1436 cp
+= sizeof (short);
1439 * Creation Date. Unknown, so we fill with zeroes.
1442 cp
+= sizeof (long);
1444 cp
+= sizeof (long);
1449 cp
+= sizeof (long);
1454 cp
+= sizeof (short);
1464 #else /* Use this code when assembling for VMS on a VMS system */
1468 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1469 cp
+= sizeof (long);
1470 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1471 cp
+= sizeof (long);
1475 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1476 cp
+= sizeof (long);
1480 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1481 cp
+= sizeof (short);
1485 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1495 * Library module name (none)
1501 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1507 * Give the number of source lines to the debugger
1510 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1512 int Starting_Line_Number
;
1513 int Number_Of_Lines
;
1521 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1523 * Source declaration
1525 Local
[1] = DST_S_C_SOURCE
;
1530 *cp
++ = DST_S_C_SRC_SETFILE
;
1534 COPY_SHORT (cp
, ID_Number
);
1535 cp
+= sizeof (short);
1539 *cp
++ = DST_S_C_SRC_SETREC_L
;
1540 COPY_LONG (cp
, Starting_Line_Number
);
1541 cp
+= sizeof (long);
1545 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1546 COPY_SHORT (cp
, Number_Of_Lines
);
1547 cp
+= sizeof (short);
1551 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1557 /* This routine locates a file in the list of files. If an entry does not
1558 * exist, one is created. For include files, a new entry is always created
1559 * such that inline functions can be properly debugged. */
1560 static struct input_file
*
1564 struct input_file
*same_file
;
1565 struct input_file
*fpnt
;
1566 same_file
= (struct input_file
*) NULL
;
1567 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1569 if (fpnt
== (struct input_file
*) NULL
)
1571 if (fpnt
->spnt
== sp
)
1574 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1576 if (fpnt
== (struct input_file
*) NULL
)
1578 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1580 if (fpnt
->flag
== 1)
1586 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1587 if (file_root
== (struct input_file
*) NULL
)
1591 struct input_file
*fpnt1
;
1592 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1595 fpnt
->next
= (struct input_file
*) NULL
;
1596 fpnt
->name
= S_GET_NAME (sp
);
1597 fpnt
->min_line
= 0x7fffffff;
1601 fpnt
->file_number
= 0;
1603 fpnt
->same_file_fpnt
= same_file
;
1608 * The following functions and definitions are used to generate object records
1609 * that will describe program variables to the VMS debugger.
1611 * This file contains many of the routines needed to output debugging info into
1612 * the object file that the VMS debugger needs to understand symbols. These
1613 * routines are called very late in the assembly process, and thus we can be
1614 * fairly lax about changing things, since the GSD and the TIR sections have
1615 * already been output.
1619 /* This routine converts a number string into an integer, and stops when it
1620 * sees an invalid character the return value is the address of the character
1621 * just past the last character read. No error is generated.
1624 cvt_integer (str
, rtn
)
1629 neg
= *str
== '-' ? ++str
, -1 : 1;
1630 ival
= 0; /* first get the number of the type for dbx */
1631 while ((*str
<= '9') && (*str
>= '0'))
1632 ival
= 10 * ival
+ *str
++ - '0';
1637 /* this routine fixes the names that are generated by C++, ".this" is a good
1638 * example. The period does not work for the debugger, since it looks like
1639 * the syntax for a structure element, and thus it gets mightily confused
1641 * We also use this to strip the PsectAttribute hack from the name before we
1642 * write a debugger record */
1650 * Kill any leading "_"
1655 * Is there a Psect Attribute to skip??
1657 if (HAS_PSECT_ATTRIBUTES (pnt
))
1662 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1665 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1673 /* Here we fix the .this -> $this conversion */
1674 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1682 /* When defining a structure, this routine is called to find the name of
1683 * the actual structure. It is assumed that str points to the equal sign
1684 * in the definition, and it moves backward until it finds the start of the
1685 * name. If it finds a 0, then it knows that this structure def is in the
1686 * outermost level, and thus symbol_name points to the symbol name.
1689 get_struct_name (str
)
1694 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1699 while ((*pnt
!= ';') && (*pnt
!= '='))
1703 while ((*pnt
< '0') || (*pnt
> '9'))
1705 while ((*pnt
>= '0') && (*pnt
<= '9'))
1710 /* search symbol list for type number dbx_type. Return a pointer to struct */
1711 static struct VMS_DBG_Symbol
*
1712 find_symbol (dbx_type
)
1715 struct VMS_DBG_Symbol
*spnt
;
1716 spnt
= VMS_Symbol_type_list
;
1717 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1719 if (spnt
->dbx_type
== dbx_type
)
1723 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1724 return 0; /*Dunno what this is*/
1725 if(spnt
->advanced
== ALIAS
)
1726 return find_symbol(spnt
->type2
);
1731 /* this routine puts info into either Local or Asuffix, depending on the sign
1732 * of size. The reason is that it is easier to build the variable descriptor
1733 * backwards, while the array descriptor is best built forwards. In the end
1734 * they get put together, if there is not a struct/union/enum along the way
1753 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1757 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1760 Apoint
= MAX_DEBUG_RECORD
- 1;
1763 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1768 /* this routine generates the array descriptor for a given array */
1770 array_suffix (spnt2
)
1771 struct VMS_DBG_Symbol
*spnt2
;
1773 struct VMS_DBG_Symbol
*spnt
;
1774 struct VMS_DBG_Symbol
*spnt1
;
1780 while (spnt
->advanced
!= ARRAY
)
1782 spnt
= find_symbol (spnt
->type2
);
1783 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1789 while (spnt1
->advanced
== ARRAY
)
1792 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1793 spnt1
= find_symbol (spnt1
->type2
);
1795 total_size
= total_size
* spnt1
->data_size
;
1796 push (spnt1
->data_size
, 2);
1797 if (spnt1
->VMS_type
== 0xa3)
1800 push (spnt1
->VMS_type
, 1);
1802 for (i
= 0; i
< 6; i
++)
1806 push (total_size
, 4);
1809 while (spnt1
->advanced
== ARRAY
)
1811 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1812 spnt1
= find_symbol (spnt1
->type2
);
1815 while (spnt1
->advanced
== ARRAY
)
1817 push (spnt1
->index_min
, 4);
1818 push (spnt1
->index_max
, 4);
1819 spnt1
= find_symbol (spnt1
->type2
);
1823 /* this routine generates the start of a variable descriptor based upon
1824 * a struct/union/enum that has yet to be defined. We define this spot as
1825 * a new location, and save four bytes for the address. When the struct is
1826 * finally defined, then we can go back and plug in the correct address
1829 new_forward_ref (dbx_type
)
1832 struct forward_ref
*fpnt
;
1833 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1834 fpnt
->next
= f_ref_root
;
1836 fpnt
->dbx_type
= dbx_type
;
1837 fpnt
->struc_numb
= ++structure_count
;
1838 fpnt
->resolved
= 'N';
1841 push (total_len
, -2);
1842 struct_number
= -fpnt
->struc_numb
;
1845 /* this routine generates the variable descriptor used to describe non-basic
1846 * variables. It calls itself recursively until it gets to the bottom of it
1847 * all, and then builds the descriptor backwards. It is easiest to do it this
1848 *way since we must periodically write length bytes, and it is easiest if we know
1849 *the value when it is time to write it.
1852 gen1 (spnt
, array_suffix_len
)
1853 struct VMS_DBG_Symbol
*spnt
;
1854 int array_suffix_len
;
1856 struct VMS_DBG_Symbol
*spnt1
;
1858 switch (spnt
->advanced
)
1861 push (DBG_S_C_VOID
, -1);
1863 push (total_len
, -2);
1867 if (array_suffix_len
== 0)
1869 push (spnt
->VMS_type
, -1);
1870 push (DBG_S_C_BASIC
, -1);
1872 push (total_len
, -2);
1882 struct_number
= spnt
->struc_numb
;
1883 if (struct_number
< 0)
1885 new_forward_ref (spnt
->dbx_type
);
1888 push (DBG_S_C_STRUCT
, -1);
1890 push (total_len
, -2);
1893 spnt1
= find_symbol (spnt
->type2
);
1895 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1896 new_forward_ref (spnt
->type2
);
1898 i
= gen1 (spnt1
, 0);
1900 { /* (*void) is a special case, do not put pointer suffix*/
1901 push (DBG_S_C_POINTER
, -1);
1903 push (total_len
, -2);
1908 while (spnt1
->advanced
== ARRAY
)
1910 spnt1
= find_symbol (spnt1
->type2
);
1911 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1913 printf ("gcc-as warning(debugger output):");
1914 printf ("Forward reference error, dbx type %d\n",
1919 /* It is too late to generate forward references, so the user gets a message.
1920 * This should only happen on a compiler error */
1921 i
= gen1 (spnt1
, 1);
1923 array_suffix (spnt
);
1924 array_suffix_len
= Apoint
- i
;
1925 switch (spnt1
->advanced
)
1933 push (total_len
, -2);
1936 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1938 total_len
+= array_suffix_len
+ 8;
1939 push (total_len
, -2);
1943 /* This generates a suffix for a variable. If it is not a defined type yet,
1944 * then dbx_type contains the type we are expecting so we can generate a
1945 * forward reference. This calls gen1 to build most of the descriptor, and
1946 * then it puts the icing on at the end. It then dumps whatever is needed
1947 * to get a complete descriptor (i.e. struct reference, array suffix ).
1950 generate_suffix (spnt
, dbx_type
)
1951 struct VMS_DBG_Symbol
*spnt
;
1956 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1957 struct VMS_DBG_Symbol
*spnt1
;
1959 Lpnt
= MAX_DEBUG_RECORD
- 1;
1963 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1964 new_forward_ref (dbx_type
);
1967 if (spnt
->VMS_type
!= 0xa3)
1968 return 0; /* no suffix needed */
1973 push (total_len
, -1);
1974 /* if the variable descriptor overflows the record, output a descriptor for
1975 * a pointer to void.
1977 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1979 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1980 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1984 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1985 Local
[i
++] = Local
[++Lpnt
];
1987 /* we use this for a reference to a structure that has already been defined */
1988 if (struct_number
> 0)
1990 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1992 VMS_Store_Struct (struct_number
);
1994 /* we use this for a forward reference to a structure that has yet to be
1995 *defined. We store four bytes of zero to make room for the actual address once
1998 if (struct_number
< 0)
2000 struct_number
= -struct_number
;
2001 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2003 VMS_Def_Struct (struct_number
);
2004 for (i
= 0; i
< 4; i
++)
2006 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2011 Local
[Lpnt
++] = Asuffix
[i
++];
2013 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2017 /* This routine generates a symbol definition for a C sybmol for the debugger.
2018 * It takes a psect and offset for global symbols - if psect < 0, then this is
2019 * a local variable and the offset is relative to FP. In this case it can
2020 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2023 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2024 struct VMS_DBG_Symbol
*spnt
;
2034 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
2036 { /* this is a local variable, referenced to SP */
2037 maxlen
= 7 + strlen (Name_pnt
);
2038 Local
[i
++] = maxlen
;
2039 Local
[i
++] = spnt
->VMS_type
;
2041 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
2043 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
2044 COPY_LONG (&Local
[i
], Offset
);
2049 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
2050 Local
[i
++] = 7 + strlen (Name_pnt
);
2051 Local
[i
++] = spnt
->VMS_type
;
2053 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2055 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2057 Local
[i
++] = strlen (Name_pnt
);
2058 while (*Name_pnt
!= '\0')
2059 Local
[i
++] = *Name_pnt
++;
2060 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2061 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2062 generate_suffix (spnt
, 0);
2066 /* This routine parses the stabs entries in order to make the definition
2067 * for the debugger of local symbols and function parameters
2070 VMS_local_stab_Parse (sp
)
2076 struct VMS_DBG_Symbol
*spnt
;
2077 struct VMS_Symbol
*vsp
;
2081 str
= S_GET_NAME (sp
);
2082 pnt
= (char *) strchr (str
, ':');
2083 if (pnt
== (char *) NULL
)
2084 return; /* no colon present */
2085 pnt1
= pnt
++; /* save this for later, and skip colon */
2087 return 0; /* ignore static constants */
2088 /* there is one little catch that we must be aware of. Sometimes function
2089 * parameters are optimized into registers, and the compiler, in its infiite
2090 * wisdom outputs stabs records for *both*. In general we want to use the
2091 * register if it is present, so we must search the rest of the symbols for
2092 * this function to see if this parameter is assigned to a register.
2100 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2102 if (!S_IS_DEBUG (sp1
))
2104 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2106 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2107 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2109 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2111 str1
= S_GET_NAME (sp1
); /* and get the name */
2113 while (*pnt2
!= ':')
2120 if ((*str1
!= ':') || (*pnt2
!= ':'))
2122 return; /* they are the same! lets skip this one */
2124 /* first find the dbx symbol type from list, and then find VMS type */
2125 pnt
++; /* skip p in case no register */
2128 pnt
= cvt_integer (pnt
, &dbx_type
);
2129 spnt
= find_symbol (dbx_type
);
2130 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2131 return 0; /*Dunno what this is*/
2133 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2134 *pnt1
= ':'; /* and restore the string */
2138 /* This routine parses a stabs entry to find the information required to define
2139 * a variable. It is used for global and static variables.
2140 * Basically we need to know the address of the symbol. With older versions
2141 * of the compiler, const symbols are
2142 * treated differently, in that if they are global they are written into the
2143 * text psect. The global symbol entry for such a const is actually written
2144 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2145 * of psects, we must search the entry points as well. static consts are even
2146 * harder, since they are never assigned a memory address. The compiler passes
2147 * a stab to tell us the value, but I am not sure what to do with it.
2151 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2154 int type1
, type2
, Text_Psect
;
2160 struct VMS_DBG_Symbol
*spnt
;
2161 struct VMS_Symbol
*vsp
;
2165 str
= S_GET_NAME (sp
);
2166 pnt
= (char *) strchr (str
, ':');
2167 if (pnt
== (char *) NULL
)
2168 return; /* no colon present */
2169 pnt1
= pnt
; /* save this for later*/
2171 if (*pnt
== expected_type
)
2173 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2174 spnt
= find_symbol (dbx_type
);
2175 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2176 return 0; /*Dunno what this is*/
2177 /* now we need to search the symbol table to find the psect and offset for
2182 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2184 pnt
= S_GET_NAME (vsp
->Symbol
);
2185 if (pnt
!= (char *) NULL
)
2187 /* make sure name is the same, and make sure correct symbol type */
2188 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2189 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2190 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2194 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2196 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2197 *pnt1
= ':'; /* and restore the string */
2200 /* the symbol was not in the symbol list, but it may be an "entry point"
2201 if it was a constant */
2202 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2205 * Dispatch on STAB type
2207 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2209 pnt
= S_GET_NAME (sp1
);
2212 if (strcmp (pnt
, str
) == 0)
2214 if (!gave_compiler_message
&& expected_type
== 'G')
2216 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2217 printf ("global constant(s) in the text psect. These will not be available to\n");
2218 printf ("other modules, since this is not the correct way to handle this. You\n");
2219 printf ("have two options: 1) get a patched compiler that does not put global\n");
2220 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2221 printf ("definitions of global variables in your source module(s). Don't say\n");
2222 printf ("I didn't warn you!");
2223 gave_compiler_message
= 1;
2225 VMS_DBG_record (spnt
,
2230 *S_GET_NAME (sp1
) = 'L';
2231 /* fool assembler to not output this
2232 * as a routine in the TBT */
2237 *pnt1
= ':'; /* and restore the string */
2242 VMS_GSYM_Parse (sp
, Text_Psect
)
2245 { /* Global variables */
2246 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2251 VMS_LCSYM_Parse (sp
, Text_Psect
)
2254 { /* Static symbols - uninitialized */
2255 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2259 VMS_STSYM_Parse (sp
, Text_Psect
)
2262 { /* Static symbols - initialized */
2263 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2267 /* for register symbols, we must figure out what range of addresses within the
2268 * psect are valid. We will use the brackets in the stab directives to give us
2269 * guidance as to the PC range that this variable is in scope. I am still not
2270 * completely comfortable with this but as I learn more, I seem to get a better
2271 * handle on what is going on.
2275 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2276 symbolS
*sp
, *Current_Routine
;
2283 struct VMS_DBG_Symbol
*spnt
;
2288 int Min_Offset
= -1; /* min PC of validity */
2289 int Max_Offset
= 0; /* max PC of validity */
2291 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2294 * Dispatch on STAB type
2296 switch (S_GET_RAW_TYPE (symbolP
))
2300 Min_Offset
= S_GET_VALUE (symbolP
);
2305 S_GET_VALUE (symbolP
) - 1;
2308 if ((Min_Offset
!= -1) && (bcnt
== 0))
2310 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2312 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2313 if (*pnt
== 'F' || *pnt
== 'f') break;
2316 /* check to see that the addresses were defined. If not, then there were no
2317 * brackets in the function, and we must try to search for the next function
2318 * Since functions can be in any order, we should search all of the symbol list
2319 * to find the correct ending address. */
2320 if (Min_Offset
== -1)
2322 int Max_Source_Offset
;
2324 Min_Offset
= S_GET_VALUE (sp
);
2325 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2328 * Dispatch on STAB type
2330 This_Offset
= S_GET_VALUE (symbolP
);
2331 switch (S_GET_RAW_TYPE (symbolP
))
2333 case N_TEXT
| N_EXT
:
2334 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2335 Max_Offset
= This_Offset
;
2338 if (This_Offset
> Max_Source_Offset
)
2339 Max_Source_Offset
= This_Offset
;
2342 /* if this is the last routine, then we use the PC of the last source line
2343 * as a marker of the max PC for which this reg is valid */
2344 if (Max_Offset
== 0x7fffffff)
2345 Max_Offset
= Max_Source_Offset
;
2348 str
= S_GET_NAME (sp
);
2349 pnt
= (char *) strchr (str
, ':');
2350 if (pnt
== (char *) NULL
)
2351 return; /* no colon present */
2352 pnt1
= pnt
; /* save this for later*/
2356 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2357 spnt
= find_symbol (dbx_type
);
2358 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2359 return 0; /*Dunno what this is yet*/
2361 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2362 maxlen
= 25 + strlen (pnt
);
2363 Local
[i
++] = maxlen
;
2364 Local
[i
++] = spnt
->VMS_type
;
2366 Local
[i
++] = strlen (pnt
) + 1;
2370 Local
[i
++] = strlen (pnt
);
2371 while (*pnt
!= '\0')
2372 Local
[i
++] = *pnt
++;
2378 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2380 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2381 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2383 Local
[i
++] = S_GET_VALUE (sp
);
2387 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2389 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2390 generate_suffix (spnt
, 0);
2393 /* this function examines a structure definition, checking all of the elements
2394 * to make sure that all of them are fully defined. The only thing that we
2395 * kick out are arrays of undefined structs, since we do not know how big
2396 * they are. All others we can handle with a normal forward reference.
2399 forward_reference (pnt
)
2403 struct VMS_DBG_Symbol
*spnt
;
2404 struct VMS_DBG_Symbol
*spnt1
;
2405 pnt
= cvt_integer (pnt
+ 1, &i
);
2407 return 0; /* no forward references */
2410 pnt
= (char *) strchr (pnt
, ':');
2411 pnt
= cvt_integer (pnt
+ 1, &i
);
2412 spnt
= find_symbol (i
);
2413 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2414 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2417 spnt1
= find_symbol (spnt
->type2
);
2418 if ((spnt
->advanced
== ARRAY
) &&
2419 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2421 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2426 pnt
= cvt_integer (pnt
+ 1, &i
);
2427 pnt
= cvt_integer (pnt
+ 1, &i
);
2428 } while (*++pnt
!= ';');
2429 return 0; /* no forward refences found */
2432 /* Used to check a single element of a structure on the final pass*/
2435 final_forward_reference (spnt
)
2436 struct VMS_DBG_Symbol
* spnt
;
2438 struct VMS_DBG_Symbol
* spnt1
;
2439 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2440 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2441 spnt1
= find_symbol(spnt
->type2
);
2442 if((spnt
->advanced
== ARRAY
) &&
2443 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2444 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2448 return 0; /* no forward refences found */
2451 /* This routine parses the stabs directives to find any definitions of dbx type
2452 * numbers. It makes a note of all of them, creating a structure element
2453 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2454 * debugger that describes the struct/union/enum, so that further references
2455 * to these data types will be by number
2456 * We have to process pointers right away, since there can be references
2457 * to them later in the same stabs directive. We cannot have forward
2458 * references to pointers, (but we can have a forward reference to a pointer to
2459 * a structure/enum/union) and this is why we process them immediately.
2460 * After we process the pointer, then we search for defs that are nested even
2462 * 8/15/92: We have to process arrays right away too, because there can
2463 * be multiple references to identical array types in one structure
2464 * definition, and only the first one has the definition. (We tend to
2465 * parse from the back going forward.
2468 VMS_typedef_parse (str
)
2476 struct forward_ref
*fpnt
;
2478 int convert_integer
;
2479 struct VMS_DBG_Symbol
*spnt
;
2480 struct VMS_DBG_Symbol
*spnt1
;
2481 /* check for any nested def's */
2482 pnt
= (char *) strchr (str
+ 1, '=');
2483 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2484 && (str
[1] != 'a' || str
[2] != 'r'))
2485 if (VMS_typedef_parse (pnt
) == 1)
2487 /* now find dbx_type of entry */
2490 { /* check for static constants */
2491 *str
= '\0'; /* for now we ignore them */
2494 while ((*pnt
<= '9') && (*pnt
>= '0'))
2496 pnt
++; /* and get back to the number */
2497 cvt_integer (pnt
, &i1
);
2498 spnt
= find_symbol (i1
);
2499 /* first we see if this has been defined already, due to a forward reference*/
2500 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2502 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2504 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2505 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2506 VMS_Symbol_type_list
= spnt
;
2510 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2511 spnt
->next
= VMS_Symbol_type_list
;
2512 VMS_Symbol_type_list
= spnt
;
2514 spnt
->dbx_type
= i1
; /* and save the type */
2516 /* for structs and unions, do a partial parse, otherwise we sometimes get
2517 * circular definitions that are impossible to resolve. We read enough info
2518 * so that any reference to this type has enough info to be resolved
2520 pnt
= str
+ 1; /* point to character past equal sign */
2521 if ((*pnt
== 'u') || (*pnt
== 's'))
2524 if ((*pnt
<= '9') && (*pnt
>= '0'))
2526 if (type_check ("void"))
2527 { /* this is the void symbol */
2529 spnt
->advanced
= VOID
;
2532 if (type_check ("unknown type"))
2533 { /* this is the void symbol */
2535 spnt
->advanced
= UNKNOWN
;
2538 pnt1
= cvt_integer(pnt
,&i1
);
2539 if(i1
!= spnt
->dbx_type
)
2541 spnt
->advanced
= ALIAS
;
2546 printf ("gcc-as warning(debugger output):");
2547 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2548 return 1; /* do not know what this is */
2550 /* now define this module*/
2551 pnt
= str
+ 1; /* point to character past equal sign */
2555 spnt
->advanced
= BASIC
;
2556 if (type_check ("int"))
2558 spnt
->VMS_type
= DBG_S_C_SLINT
;
2559 spnt
->data_size
= 4;
2561 else if (type_check ("long int"))
2563 spnt
->VMS_type
= DBG_S_C_SLINT
;
2564 spnt
->data_size
= 4;
2566 else if (type_check ("unsigned int"))
2568 spnt
->VMS_type
= DBG_S_C_ULINT
;
2569 spnt
->data_size
= 4;
2571 else if (type_check ("long unsigned int"))
2573 spnt
->VMS_type
= DBG_S_C_ULINT
;
2574 spnt
->data_size
= 4;
2576 else if (type_check ("short int"))
2578 spnt
->VMS_type
= DBG_S_C_SSINT
;
2579 spnt
->data_size
= 2;
2581 else if (type_check ("short unsigned int"))
2583 spnt
->VMS_type
= DBG_S_C_USINT
;
2584 spnt
->data_size
= 2;
2586 else if (type_check ("char"))
2588 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2589 spnt
->data_size
= 1;
2591 else if (type_check ("signed char"))
2593 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2594 spnt
->data_size
= 1;
2596 else if (type_check ("unsigned char"))
2598 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2599 spnt
->data_size
= 1;
2601 else if (type_check ("float"))
2603 spnt
->VMS_type
= DBG_S_C_REAL4
;
2604 spnt
->data_size
= 4;
2606 else if (type_check ("double"))
2608 spnt
->VMS_type
= DBG_S_C_REAL8
;
2609 spnt
->data_size
= 8;
2611 pnt1
= (char *) strchr (str
, ';') + 1;
2616 spnt
->advanced
= STRUCT
;
2618 spnt
->advanced
= UNION
;
2619 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2620 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2621 if (!final_pass
&& forward_reference(pnt
))
2623 spnt
->struc_numb
= -1;
2626 spnt
->struc_numb
= ++structure_count
;
2628 pnt
= get_struct_name (str
);
2629 VMS_Def_Struct (spnt
->struc_numb
);
2631 while (fpnt
!= (struct forward_ref
*) NULL
)
2633 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2635 fpnt
->resolved
= 'Y';
2636 VMS_Set_Struct (fpnt
->struc_numb
);
2637 VMS_Store_Struct (spnt
->struc_numb
);
2641 VMS_Set_Struct (spnt
->struc_numb
);
2643 Local
[i
++] = 11 + strlen (pnt
);
2644 Local
[i
++] = DBG_S_C_STRUCT_START
;
2646 for (i1
= 0; i1
< 4; i1
++)
2648 Local
[i
++] = strlen (pnt
);
2650 while (*pnt2
!= '\0')
2651 Local
[i
++] = *pnt2
++;
2652 i2
= spnt
->data_size
* 8; /* number of bits */
2653 COPY_LONG(&Local
[i
], i2
);
2655 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2657 if (pnt
!= symbol_name
)
2659 pnt
+= strlen (pnt
);
2661 }; /* replace colon for later */
2662 while (*++pnt1
!= ';')
2664 pnt
= (char *) strchr (pnt1
, ':');
2667 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2668 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2669 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2670 if ((dtype
== 1) && (i3
!= 32))
2673 push (19 + strlen (pnt2
), 1);
2675 push (1 + strlen (pnt2
), 4);
2676 push (strlen (pnt2
), 1);
2677 while (*pnt2
!= '\0')
2679 push (i3
, 2); /* size of bitfield */
2682 push (i2
, 4); /* start position */
2683 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2688 Local
[i
++] = 7 + strlen (pnt2
);
2689 spnt1
= find_symbol (dtype
);
2690 /* check if this is a forward reference */
2691 if(final_pass
&& final_forward_reference(spnt1
))
2693 printf("gcc-as warning(debugger output):");
2694 printf("structure element %s has undefined type\n",pnt2
);
2698 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2699 Local
[i
++] = spnt1
->VMS_type
;
2701 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2702 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2703 COPY_LONG (&Local
[i
], i2
);
2705 Local
[i
++] = strlen (pnt2
);
2706 while (*pnt2
!= '\0')
2707 Local
[i
++] = *pnt2
++;
2708 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2710 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2711 generate_suffix (spnt1
, dtype
);
2712 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2713 generate_suffix (spnt1
, 0);
2717 Local
[i
++] = 0x01; /* length byte */
2718 Local
[i
++] = DBG_S_C_STRUCT_END
;
2719 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2723 spnt
->advanced
= ENUM
;
2724 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2725 spnt
->struc_numb
= ++structure_count
;
2726 spnt
->data_size
= 4;
2727 VMS_Def_Struct (spnt
->struc_numb
);
2729 while (fpnt
!= (struct forward_ref
*) NULL
)
2731 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2733 fpnt
->resolved
= 'Y';
2734 VMS_Set_Struct (fpnt
->struc_numb
);
2735 VMS_Store_Struct (spnt
->struc_numb
);
2739 VMS_Set_Struct (spnt
->struc_numb
);
2741 Local
[i
++] = 3 + strlen (symbol_name
);
2742 Local
[i
++] = DBG_S_C_ENUM_START
;
2744 Local
[i
++] = strlen (symbol_name
);
2746 while (*pnt2
!= '\0')
2747 Local
[i
++] = *pnt2
++;
2748 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2750 while (*++pnt
!= ';')
2752 pnt1
= (char *) strchr (pnt
, ':');
2754 pnt1
= cvt_integer (pnt1
, &i1
);
2755 Local
[i
++] = 7 + strlen (pnt
);
2756 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2758 COPY_LONG (&Local
[i
], i1
);
2760 Local
[i
++] = strlen (pnt
);
2762 while (*pnt
!= '\0')
2763 Local
[i
++] = *pnt
++;
2764 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2766 pnt
= pnt1
; /* Skip final semicolon */
2768 Local
[i
++] = 0x01; /* len byte */
2769 Local
[i
++] = DBG_S_C_ENUM_END
;
2770 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2775 spnt
->advanced
= ARRAY
;
2776 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2777 pnt
= (char *) strchr (pnt
, ';');
2778 if (pnt
== (char *) NULL
)
2780 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2781 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2782 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2783 pnt
=(char*)strchr(str
+1,'=');
2784 if((pnt
!= (char*) NULL
))
2785 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2788 spnt
->advanced
= FUNCTION
;
2789 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2790 /* this masquerades as a basic type*/
2791 spnt
->data_size
= 4;
2792 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2795 spnt
->advanced
= POINTER
;
2796 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2797 spnt
->data_size
= 4;
2798 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2799 pnt
= (char *) strchr (str
+ 1, '=');
2800 if ((pnt
!= (char *) NULL
))
2801 if (VMS_typedef_parse (pnt
) == 1)
2805 spnt
->advanced
= UNKNOWN
;
2807 printf ("gcc-as warning(debugger output):");
2808 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2809 return 1; /* unable to decipher */
2811 /* this removes the evidence of the definition so that the outer levels of
2812 parsing do not have to worry about it */
2814 while (*pnt1
!= '\0')
2822 * This is the root routine that parses the stabs entries for definitions.
2823 * it calls VMS_typedef_parse, which can in turn call itself.
2824 * We need to be careful, since sometimes there are forward references to
2825 * other symbol types, and these cannot be resolved until we have completed
2828 * Also check and see if we are using continuation stabs, if we are, then
2829 * paste together the entire contents of the stab before we pass it to
2830 * VMS_typedef_parse.
2839 char *parse_buffer
= 0;
2841 int incomplete
, i
, pass
, incom1
;
2842 struct VMS_DBG_Symbol
*spnt
;
2843 struct VMS_Symbol
*vsp
;
2844 struct forward_ref
*fpnt
;
2851 incom1
= incomplete
;
2853 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2856 * Deal with STAB symbols
2858 if (S_IS_DEBUG (sp
))
2861 * Dispatch on STAB type
2863 switch (S_GET_RAW_TYPE (sp
))
2871 case N_FUN
: /*sometimes these contain typedefs*/
2872 str
= S_GET_NAME (sp
);
2874 pnt
= str
+ strlen(str
) -1;
2875 if (*pnt
== '?') /* Continuation stab. */
2881 tlen
+= strlen(str
) - 1;
2882 spnext
= symbol_next (spnext
);
2883 str
= S_GET_NAME (spnext
);
2884 pnt
= str
+ strlen(str
) - 1;
2885 } while (*pnt
== '?');
2886 tlen
+= strlen(str
);
2887 parse_buffer
= (char *) malloc (tlen
+ 1);
2888 strcpy(parse_buffer
, S_GET_NAME (sp
));
2889 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2893 spnext
= symbol_next (spnext
);
2894 str
= S_GET_NAME (spnext
);
2895 strcat (pnt2
, S_GET_NAME (spnext
));
2896 pnt2
+= strlen(str
) - 1;
2897 *str
= '\0'; /* Erase this string */
2898 if (*pnt2
!= '?') break;
2904 pnt
= (char *) strchr (str
, ':');
2905 if (pnt
!= (char *) NULL
)
2909 pnt2
= (char *) strchr (pnt1
, '=');
2910 if (pnt2
!= (char *) NULL
)
2911 incomplete
+= VMS_typedef_parse (pnt2
);
2913 /* At this point the parse buffer should just contain name:nn.
2914 If it does not, then we are in real trouble. Anyway,
2915 this is always shorter than the original line. */
2916 strcpy(S_GET_NAME (sp
), parse_buffer
);
2917 free (parse_buffer
);
2920 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2927 /* Make one last pass, if needed, and define whatever we can that is left */
2928 if(final_pass
== 0 && incomplete
== incom1
)
2931 incom1
++; /* Force one last pass through */
2933 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2934 /* repeat until all refs resolved if possible */
2935 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2936 if (incomplete
!= 0)
2938 printf ("gcc-as warning(debugger output):");
2939 printf ("Unable to resolve %d circular references.\n", incomplete
);
2943 while (fpnt
!= (struct forward_ref
*) NULL
)
2945 if (fpnt
->resolved
!= 'Y')
2947 if (find_symbol (fpnt
->dbx_type
) !=
2948 (struct VMS_DBG_Symbol
*) NULL
)
2950 printf ("gcc-as warning(debugger output):");
2951 printf ("Forward reference error, dbx type %d\n",
2956 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2957 pnt2
= (char *) strchr (&fixit
[1], '=');
2958 VMS_typedef_parse (pnt2
);
2965 Define_Local_Symbols (s1
, s2
)
2969 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2971 if (symbolP1
== (symbolS
*) NULL
)
2973 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2975 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2976 if (*pnt
== 'F' || *pnt
== 'f') break;
2979 * Deal with STAB symbols
2981 if (S_IS_DEBUG (symbolP1
))
2984 * Dispatch on STAB type
2986 switch (S_GET_RAW_TYPE (symbolP1
))
2990 VMS_local_stab_Parse (symbolP1
);
2993 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
3001 /* This function crawls the symbol chain searching for local symbols that need
3002 * to be described to the debugger. When we enter a new scope with a "{", it
3003 * creates a new "block", which helps the debugger keep track of which scope
3004 * we are currently in.
3008 Define_Routine (symbolP
, Level
)
3018 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
3020 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3022 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3023 if (*pnt
== 'F' || *pnt
== 'f') break;
3026 * Deal with STAB symbols
3028 if (S_IS_DEBUG (symbolP1
))
3031 * Dispatch on STAB type
3033 switch (S_GET_RAW_TYPE (symbolP1
))
3038 sprintf (str
, "$%d", rcount
++);
3039 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3041 Offset
= S_GET_VALUE (symbolP1
);
3042 Define_Local_Symbols (sstart
, symbolP1
);
3044 Define_Routine (symbolP1
, Level
+ 1);
3046 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3055 /* we end up here if there were no brackets in this function. Define
3057 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3063 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3065 symbolS
*Curr_Routine
;
3068 Current_Routine
= Curr_Routine
;
3069 Text_Psect
= Txt_Psect
;
3070 Define_Routine (symbolP
, 0);
3077 #include <sys/types.h>
3080 /* Manufacure a VMS like time on a unix based system. */
3081 get_VMS_time_on_unix (Now
)
3087 pnt
= ctime (&timeb
);
3093 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3096 #endif /* not HO_VMS */
3098 * Write the MHD (Module Header) records
3101 Write_VMS_MHD_Records ()
3103 register char *cp
, *cp1
;
3110 char Module_Name
[256];
3114 * We are writing a module header record
3116 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3118 * ***************************
3119 * *MAIN MODULE HEADER RECORD*
3120 * ***************************
3122 * Store record type and header type
3124 PUT_CHAR (OBJ_S_C_HDR
);
3125 PUT_CHAR (MHD_S_C_MHD
);
3127 * Structure level is 0
3129 PUT_CHAR (OBJ_S_C_STRLVL
);
3131 * Maximum record size is size of the object record buffer
3133 PUT_SHORT (sizeof (Object_Record_Buffer
));
3135 * Get module name (the FILENAME part of the object file)
3141 if ((*cp
== ']') || (*cp
== '>') ||
3142 (*cp
== ':') || (*cp
== '/'))
3148 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3152 * Limit it to 31 characters and store in the object record
3154 while (--cp1
>= Module_Name
)
3157 if (strlen (Module_Name
) > 31)
3160 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3161 Module_Name
[31] = 0;
3163 PUT_COUNTED_STRING (Module_Name
);
3165 * Module Version is "V1.0"
3167 PUT_COUNTED_STRING ("V1.0");
3169 * Creation time is "now" (17 chars of time string)
3172 get_VMS_time_on_unix (&Now
[0]);
3174 Descriptor
.Size
= 17;
3175 Descriptor
.Ptr
= Now
;
3176 sys$
asctim (0, &Descriptor
, 0, 0);
3178 for (i
= 0; i
< 17; i
++)
3181 * Patch time is "never" (17 zeros)
3183 for (i
= 0; i
< 17; i
++)
3188 Flush_VMS_Object_Record_Buffer ();
3190 * *************************
3191 * *LANGUAGE PROCESSOR NAME*
3192 * *************************
3194 * Store record type and header type
3196 PUT_CHAR (OBJ_S_C_HDR
);
3197 PUT_CHAR (MHD_S_C_LNM
);
3199 * Store language processor name and version
3200 * (not a counted string!)
3202 cp
= compiler_version_string
;
3208 cp
= strchr (GAS_VERSION
, '.');
3218 Flush_VMS_Object_Record_Buffer ();
3223 * Write the EOM (End Of Module) record
3226 Write_VMS_EOM_Record (Psect
, Offset
)
3231 * We are writing an end-of-module record
3233 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3237 PUT_CHAR (OBJ_S_C_EOM
);
3239 * Store the error severity (0)
3243 * Store the entry point, if it exists
3248 * Store the entry point Psect
3252 * Store the entry point Psect offset
3259 Flush_VMS_Object_Record_Buffer ();
3263 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3269 register unsigned char *p
= ptr
;
3270 register unsigned char *end
= p
+ strlen (ptr
);
3271 register unsigned char c
;
3272 register int hash
= 0;
3277 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3283 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3286 VMS_Case_Hack_Symbol (In
, Out
)
3296 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3298 int Case_Hack_Bits
= 0;
3300 static char Hex_Table
[16] =
3301 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3304 * Kill any leading "_"
3306 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3309 new_name
= Out
; /* save this for later*/
3311 #if barfoo /* Dead code */
3312 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3316 /* We may need to truncate the symbol, save the hash for later*/
3317 if (strlen (In
) > 23)
3318 result
= hash_string (In
);
3320 * Is there a Psect Attribute to skip??
3322 if (HAS_PSECT_ATTRIBUTES (In
))
3327 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3330 if ((In
[0] == '$') && (In
[1] == '$'))
3340 /* if (strlen(In) > 31 && flagseen['+'])
3341 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3343 * Do the case conversion
3345 i
= 23; /* Maximum of 23 chars */
3346 while (*In
&& (--i
>= 0))
3348 Case_Hack_Bits
<<= 1;
3351 if ((destructor
== 1) && (i
== 21))
3353 switch (vms_name_mapping
)
3358 Case_Hack_Bits
|= 1;
3360 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3363 case 3: *Out
++ = *In
++;
3369 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3375 * If we saw a dollar sign, we don't do case hacking
3377 if (flagseen
['h'] || Saw_Dollar
)
3381 * If we have more than 23 characters and everything is lowercase
3382 * we can insert the full 31 characters
3387 * We have more than 23 characters
3388 * If we must add the case hack, then we have truncated the str
3392 if (Case_Hack_Bits
== 0)
3395 * And so far they are all lower case:
3396 * Check up to 8 more characters
3397 * and ensure that they are lowercase
3399 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3400 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3406 if ((i
== 8) || (In
[i
] == 0))
3409 * They are: Copy up to 31 characters
3410 * to the output string
3413 while ((--i
>= 0) && (*In
))
3414 switch (vms_name_mapping
){
3415 case 0: *Out
++ = islower(*In
) ?
3419 case 3: *Out
++ = *In
++;
3421 case 2: *Out
++ = isupper(*In
) ?
3430 * If there were any uppercase characters in the name we
3431 * take on the case hacking string
3434 /* Old behavior for regular GNU-C compiler */
3437 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3442 for (i
= 0; i
< 6; i
++)
3444 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3445 Case_Hack_Bits
>>= 4;
3451 Out
= pnt
; /*Cut back to 23 characters maximum */
3453 for (i
= 0; i
< 7; i
++)
3455 init
= result
& 0x01f;
3457 *Out
++ = '0' + init
;
3459 *Out
++ = 'A' + init
- 10;
3460 result
= result
>> 5;
3468 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3469 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3474 * Scan a symbol name for a psect attribute specification
3476 #define GLOBALSYMBOL_BIT 0x10000
3477 #define GLOBALVALUE_BIT 0x20000
3481 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3483 int *Attribute_Pointer
;
3494 {"PIC", GPS_S_M_PIC
},
3495 {"LIB", GPS_S_M_LIB
},
3496 {"OVR", GPS_S_M_OVR
},
3497 {"REL", GPS_S_M_REL
},
3498 {"GBL", GPS_S_M_GBL
},
3499 {"SHR", GPS_S_M_SHR
},
3500 {"EXE", GPS_S_M_EXE
},
3502 {"WRT", GPS_S_M_WRT
},
3503 {"VEC", GPS_S_M_VEC
},
3504 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3505 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3515 * Check for a PSECT attribute list
3517 if (!HAS_PSECT_ATTRIBUTES (Name
))
3518 return; /* If not, return */
3520 * Skip the attribute list indicator
3522 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3524 * Process the attributes ("_" separated, "$" terminated)
3526 while (*Name
!= '$')
3529 * Assume not negating
3535 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3538 * We are negating (and skip the NO)
3544 * Find the token delimiter
3547 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3550 * Look for the token in the attribute list
3552 for (i
= 0; Attributes
[i
].Name
; i
++)
3555 * If the strings match, set/clear the attr.
3557 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3563 *Attribute_Pointer
&=
3564 ~Attributes
[i
].Value
;
3566 *Attribute_Pointer
|=
3567 Attributes
[i
].Value
;
3575 * Now skip the attribute
3589 * Define a global symbol
3592 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3600 * We are writing a GSD record
3602 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3604 * If the buffer is empty we must insert the GSD record type
3606 if (Object_Record_Offset
== 0)
3607 PUT_CHAR (OBJ_S_C_GSD
);
3609 * We are writing a Global symbol definition subrecord
3611 if (Psect_Number
<= 255)
3613 PUT_CHAR (GSD_S_C_SYM
);
3617 PUT_CHAR (GSD_S_C_SYMW
);
3620 * Data type is undefined
3624 * Switch on Definition/Reference
3626 if ((Defined
& 1) != 0)
3630 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3631 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3633 if ((Defined
& 2) == 0)
3635 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3639 PUT_SHORT (GSY_S_M_DEF
);
3644 if (Psect_Number
<= 255)
3646 PUT_CHAR (Psect_Number
);
3650 PUT_SHORT (Psect_Number
);
3655 PUT_LONG (Psect_Offset
);
3661 * Flags = "RELOCATABLE" for regular symbol,
3662 * = "" for globalvalue (Defined & 2 == 1)
3664 if ((Defined
& 2) == 0)
3666 PUT_SHORT (GSY_S_M_REL
);
3674 * Finally, the global symbol name
3676 VMS_Case_Hack_Symbol (Name
, Local
);
3677 PUT_COUNTED_STRING (Local
);
3679 * Flush the buffer if it is more than 75% full
3681 if (Object_Record_Offset
>
3682 (sizeof (Object_Record_Buffer
) * 3 / 4))
3683 Flush_VMS_Object_Record_Buffer ();
3691 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3695 struct VMS_Symbol
*vsp
;
3698 int Psect_Attributes
;
3701 * Generate the appropriate PSECT flags given the PSECT type
3703 if (strcmp (Type
, "COMMON") == 0)
3706 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3708 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3709 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3711 else if (strcmp (Type
, "CONST") == 0)
3714 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3716 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3717 GPS_S_M_SHR
| GPS_S_M_RD
);
3719 else if (strcmp (Type
, "DATA") == 0)
3722 * The Data psects are PIC,REL,RD,WRT
3725 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3727 else if (strcmp (Type
, "TEXT") == 0)
3730 * The Text psects are PIC,REL,SHR,EXE,RD
3733 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3734 GPS_S_M_EXE
| GPS_S_M_RD
);
3739 * Error: Unknown psect type
3741 error ("Unknown VMS psect type");
3744 * Modify the psect attributes according to any attribute string
3746 if (HAS_PSECT_ATTRIBUTES (Name
))
3747 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3749 * Check for globalref/def/val.
3751 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3754 * globalvalue symbols were generated before. This code
3755 * prevents unsightly psect buildup, and makes sure that
3756 * fixup references are emitted correctly.
3758 vsp
->Psect_Index
= -1; /* to catch errors */
3759 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3760 return 1; /* decrement psect counter */
3763 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3765 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3767 case N_UNDF
| N_EXT
:
3768 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3769 vsp
->Psect_Offset
, 0);
3770 vsp
->Psect_Index
= -1;
3771 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3772 return 1; /* return and indicate no psect */
3773 case N_DATA
| N_EXT
:
3774 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3775 vsp
->Psect_Offset
, 1);
3776 /* In this case we still generate the psect */
3780 char Error_Line
[256];
3781 sprintf (Error_Line
,
3782 "Globalsymbol attribute for symbol %s was unexpected.\n",
3790 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3792 * We are writing a GSD record
3794 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3796 * If the buffer is empty we must insert the GSD record type
3798 if (Object_Record_Offset
== 0)
3799 PUT_CHAR (OBJ_S_C_GSD
);
3801 * We are writing a PSECT definition subrecord
3803 PUT_CHAR (GSD_S_C_PSC
);
3805 * Psects are always LONGWORD aligned
3809 * Specify the psect attributes
3811 PUT_SHORT (Psect_Attributes
);
3813 * Specify the allocation
3817 * Finally, the psect name
3819 VMS_Case_Hack_Symbol (Name
, Local
);
3820 PUT_COUNTED_STRING (Local
);
3822 * Flush the buffer if it is more than 75% full
3824 if (Object_Record_Offset
>
3825 (sizeof (Object_Record_Buffer
) * 3 / 4))
3826 Flush_VMS_Object_Record_Buffer ();
3832 * Given the pointer to a symbol we calculate how big the data at the
3833 * symbol is. We do this by looking for the next symbol (local or
3834 * global) which will indicate the start of another datum.
3837 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3838 register struct symbol
*sp
;
3841 register struct symbol
*sp1
, *Next_Symbol
;
3844 * Find the next symbol
3845 * it delimits this datum
3848 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3851 * The data type must match
3853 if (S_GET_TYPE (sp1
) != N_DATA
)
3856 * The symbol must be AFTER this symbol
3858 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3861 * We ignore THIS symbol
3866 * If there is already a candidate selected for the
3867 * next symbol, see if we are a better candidate
3872 * We are a better candidate if we are "closer"
3875 if (S_GET_VALUE (sp1
) >
3876 S_GET_VALUE (Next_Symbol
))
3879 * Win: Make this the candidate
3886 * This is the 1st candidate
3892 * Calculate its size
3894 return (Next_Symbol
?
3895 (S_GET_VALUE (Next_Symbol
) -
3897 (End_Of_Data
- S_GET_VALUE (sp
)));
3901 * Check symbol names for the Psect hack with a globalvalue, and then
3902 * generate globalvalues for those that have it.
3905 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3910 register symbolS
*sp
;
3911 char *stripped_name
, *Name
;
3913 int Psect_Attributes
;
3917 * Scan the symbol table for globalvalues, and emit def/ref when
3918 * required. These will be caught again later and converted to
3921 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3924 * See if this is something we want to look at.
3926 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3927 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3930 * See if this has globalvalue specification.
3932 Name
= S_GET_NAME (sp
);
3934 if (!HAS_PSECT_ATTRIBUTES (Name
))
3937 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3938 strcpy (stripped_name
, Name
);
3939 Psect_Attributes
= 0;
3940 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3942 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3944 switch (S_GET_RAW_TYPE (sp
))
3946 case N_UNDF
| N_EXT
:
3947 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3949 case N_DATA
| N_EXT
:
3950 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3952 error ("Invalid data type for globalvalue");
3953 globalvalue
= md_chars_to_number (Data_Segment
+
3954 S_GET_VALUE (sp
) - text_siz
, Size
);
3955 /* Three times for good luck. The linker seems to get confused
3956 if there are fewer than three */
3957 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3958 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3959 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3962 printf (" Invalid globalvalue of %s\n", stripped_name
);
3966 free (stripped_name
); /* clean up */
3973 * Define a procedure entry pt/mask
3976 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3985 * We are writing a GSD record
3987 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3989 * If the buffer is empty we must insert the GSD record type
3991 if (Object_Record_Offset
== 0)
3992 PUT_CHAR (OBJ_S_C_GSD
);
3994 * We are writing a Procedure Entry Pt/Mask subrecord
3996 if (Psect_Number
<= 255)
3998 PUT_CHAR (GSD_S_C_EPM
);
4002 PUT_CHAR (GSD_S_C_EPMW
);
4005 * Data type is undefined
4009 * Flags = "RELOCATABLE" and "DEFINED"
4011 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4015 if (Psect_Number
<= 255)
4017 PUT_CHAR (Psect_Number
);
4021 PUT_SHORT (Psect_Number
);
4026 PUT_LONG (Psect_Offset
);
4030 PUT_SHORT (Entry_Mask
);
4032 * Finally, the global symbol name
4034 VMS_Case_Hack_Symbol (Name
, Local
);
4035 PUT_COUNTED_STRING (Local
);
4037 * Flush the buffer if it is more than 75% full
4039 if (Object_Record_Offset
>
4040 (sizeof (Object_Record_Buffer
) * 3 / 4))
4041 Flush_VMS_Object_Record_Buffer ();
4046 * Set the current location counter to a particular Psect and Offset
4049 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4055 * We are writing a "Record_Type" record
4057 Set_VMS_Object_File_Record (Record_Type
);
4059 * If the buffer is empty we must insert the record type
4061 if (Object_Record_Offset
== 0)
4062 PUT_CHAR (Record_Type
);
4064 * Stack the Psect base + Longword Offset
4066 if (Psect_Index
< 255)
4068 PUT_CHAR (TIR_S_C_STA_PL
);
4069 PUT_CHAR (Psect_Index
);
4073 PUT_CHAR (TIR_S_C_STA_WPL
);
4074 PUT_SHORT (Psect_Index
);
4078 * Set relocation base
4080 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4082 * Flush the buffer if it is more than 75% full
4084 if (Object_Record_Offset
>
4085 (sizeof (Object_Record_Buffer
) * 3 / 4))
4086 Flush_VMS_Object_Record_Buffer ();
4091 * Store repeated immediate data in current Psect
4094 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4096 register char *Pointer
;
4102 * Ignore zero bytes/words/longwords
4104 if ((Size
== sizeof (char)) && (*Pointer
== 0))
4106 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
4108 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
4111 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4112 * then we do it manually
4116 while (--Repeat_Count
>= 0)
4117 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4121 * We are writing a "Record_Type" record
4123 Set_VMS_Object_File_Record (Record_Type
);
4125 * If the buffer is empty we must insert record type
4127 if (Object_Record_Offset
== 0)
4128 PUT_CHAR (Record_Type
);
4130 * Stack the repeat count
4132 PUT_CHAR (TIR_S_C_STA_LW
);
4133 PUT_LONG (Repeat_Count
);
4135 * And now the command and its data
4137 PUT_CHAR (TIR_S_C_STO_RIVB
);
4140 PUT_CHAR (*Pointer
++);
4142 * Flush the buffer if it is more than 75% full
4144 if (Object_Record_Offset
>
4145 (sizeof (Object_Record_Buffer
) * 3 / 4))
4146 Flush_VMS_Object_Record_Buffer ();
4151 * Store a Position Independent Reference
4154 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4155 Psect
, Psect_Offset
, Record_Type
)
4156 struct symbol
*Symbol
;
4163 register struct VMS_Symbol
*vsp
=
4164 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4168 * We are writing a "Record_Type" record
4170 Set_VMS_Object_File_Record (Record_Type
);
4172 * If the buffer is empty we must insert record type
4174 if (Object_Record_Offset
== 0)
4175 PUT_CHAR (Record_Type
);
4177 * Set to the appropriate offset in the Psect
4182 * For a Code reference we need to fix the operand
4183 * specifier as well (so back up 1 byte)
4185 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4190 * For a Data reference we just store HERE
4192 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4195 * Make sure we are still generating a "Record Type" record
4197 if (Object_Record_Offset
== 0)
4198 PUT_CHAR (Record_Type
);
4200 * Dispatch on symbol type (so we can stack its value)
4202 switch (S_GET_RAW_TYPE (Symbol
))
4207 #ifdef NOT_VAX_11_C_COMPATIBLE
4208 case N_UNDF
| N_EXT
:
4209 case N_DATA
| N_EXT
:
4210 #endif /* NOT_VAX_11_C_COMPATIBLE */
4212 case N_TEXT
| N_EXT
:
4214 * Get the symbol name (case hacked)
4216 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4218 * Stack the global symbol value
4220 PUT_CHAR (TIR_S_C_STA_GBL
);
4221 PUT_COUNTED_STRING (Local
);
4225 * Stack the longword offset
4227 PUT_CHAR (TIR_S_C_STA_LW
);
4230 * Add the two, leaving the result on the stack
4232 PUT_CHAR (TIR_S_C_OPR_ADD
);
4236 * Uninitialized local data
4240 * Stack the Psect (+offset)
4242 if (vsp
->Psect_Index
< 255)
4244 PUT_CHAR (TIR_S_C_STA_PL
);
4245 PUT_CHAR (vsp
->Psect_Index
);
4249 PUT_CHAR (TIR_S_C_STA_WPL
);
4250 PUT_SHORT (vsp
->Psect_Index
);
4252 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4259 * Stack the Psect (+offset)
4261 if (vsp
->Psect_Index
< 255)
4263 PUT_CHAR (TIR_S_C_STA_PL
);
4264 PUT_CHAR (vsp
->Psect_Index
);
4268 PUT_CHAR (TIR_S_C_STA_WPL
);
4269 PUT_SHORT (vsp
->Psect_Index
);
4271 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4274 * Initialized local or global data
4277 #ifndef NOT_VAX_11_C_COMPATIBLE
4278 case N_UNDF
| N_EXT
:
4279 case N_DATA
| N_EXT
:
4280 #endif /* NOT_VAX_11_C_COMPATIBLE */
4282 * Stack the Psect (+offset)
4284 if (vsp
->Psect_Index
< 255)
4286 PUT_CHAR (TIR_S_C_STA_PL
);
4287 PUT_CHAR (vsp
->Psect_Index
);
4291 PUT_CHAR (TIR_S_C_STA_WPL
);
4292 PUT_SHORT (vsp
->Psect_Index
);
4294 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4298 * Store either a code or data reference
4300 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4302 * Flush the buffer if it is more than 75% full
4304 if (Object_Record_Offset
>
4305 (sizeof (Object_Record_Buffer
) * 3 / 4))
4306 Flush_VMS_Object_Record_Buffer ();
4311 * Check in the text area for an indirect pc-relative reference
4312 * and fix it up with addressing mode 0xff [PC indirect]
4314 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4315 * PIC CODE GENERATING FIXUP ROUTINE.
4318 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4321 register fragS
*fragP
;
4322 struct frag
*text_frag_root
;
4325 * The addressing mode byte is 1 byte before the address
4329 * Is it in THIS frag??
4331 if ((Offset
< fragP
->fr_address
) ||
4332 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4335 * We need to search for the fragment containing this
4338 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4340 if ((Offset
>= fragP
->fr_address
) &&
4341 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4345 * If we couldn't find the frag, things are BAD!!
4348 error ("Couldn't find fixup fragment when checking for indirect reference");
4351 * Check for indirect PC relative addressing mode
4353 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4355 static char Address_Mode
= 0xff;
4358 * Yes: Store the indirect mode back into the image
4359 * to fix up the damage done by STO_PICR
4361 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4362 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4367 * If the procedure "main()" exists we have to add the instruction
4368 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4370 VMS_Check_For_Main ()
4372 register symbolS
*symbolP
;
4373 #ifdef HACK_DEC_C_STARTUP /* JF */
4374 register struct frchain
*frchainP
;
4375 register fragS
*fragP
;
4376 register fragS
**prev_fragPP
;
4377 register struct fix
*fixP
;
4378 register fragS
*New_Frag
;
4380 #endif /* HACK_DEC_C_STARTUP */
4382 symbolP
= (struct symbol
*) symbol_find ("_main");
4383 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4384 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4386 #ifdef HACK_DEC_C_STARTUP
4391 * Remember the entry point symbol
4393 Entry_Point_Symbol
= symbolP
;
4394 #ifdef HACK_DEC_C_STARTUP
4399 * Scan all the fragment chains for the one with "_main"
4400 * (Actually we know the fragment from the symbol, but we need
4401 * the previous fragment so we can change its pointer)
4403 frchainP
= frchain_root
;
4407 * Scan all the fragments in this chain, remembering
4408 * the "previous fragment"
4410 prev_fragPP
= &frchainP
->frch_root
;
4411 fragP
= frchainP
->frch_root
;
4412 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4415 * Is this the fragment?
4417 if (fragP
== symbolP
->sy_frag
)
4420 * Yes: Modify the fragment by replacing
4421 * it with a new fragment.
4423 New_Frag
= (fragS
*)
4424 xmalloc (sizeof (*New_Frag
) +
4429 * The fragments are the same except
4430 * that the "fixed" area is larger
4433 New_Frag
->fr_fix
+= 6;
4435 * Copy the literal data opening a hole
4436 * 2 bytes after "_main" (i.e. just after
4437 * the entry mask). Into which we place
4438 * the JSB instruction.
4440 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4441 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4442 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4443 New_Frag
->fr_literal
[3] = 0xef;
4444 New_Frag
->fr_literal
[4] = 0;
4445 New_Frag
->fr_literal
[5] = 0;
4446 New_Frag
->fr_literal
[6] = 0;
4447 New_Frag
->fr_literal
[7] = 0;
4448 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4449 New_Frag
->fr_literal
[i
+ 6] =
4450 fragP
->fr_literal
[i
];
4452 * Now replace the old fragment with the
4453 * newly generated one.
4455 *prev_fragPP
= New_Frag
;
4457 * Remember the entry point symbol
4459 Entry_Point_Symbol
= symbolP
;
4461 * Scan the text area fixup structures
4462 * as offsets in the fragment may have
4465 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4468 * Look for references to this
4471 if (fixP
->fx_frag
== fragP
)
4474 * Change the fragment
4477 fixP
->fx_frag
= New_Frag
;
4479 * If the offset is after
4480 * the entry mask we need
4481 * to account for the JSB
4482 * instruction we just
4485 if (fixP
->fx_where
>= 2)
4486 fixP
->fx_where
+= 6;
4490 * Scan the symbols as offsets in the
4491 * fragment may have changed
4493 for (symbolP
= symbol_rootP
;
4495 symbolP
= symbol_next (symbolP
))
4498 * Look for references to this
4501 if (symbolP
->sy_frag
== fragP
)
4504 * Change the fragment
4507 symbolP
->sy_frag
= New_Frag
;
4509 * If the offset is after
4510 * the entry mask we need
4511 * to account for the JSB
4512 * instruction we just
4515 if (S_GET_VALUE (symbolP
) >= 2)
4516 S_SET_VALUE (symbolP
,
4517 S_GET_VALUE (symbolP
) + 6);
4521 * Make a symbol reference to
4522 * "_c$main_args" so we can get
4523 * its address inserted into the
4526 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4527 S_GET_NAME (symbolP
) = "_c$main_args";
4528 S_SET_TYPE (symbolP
, N_UNDF
);
4529 S_GET_OTHER (symbolP
) = 0;
4530 S_GET_DESC (symbolP
) = 0;
4531 S_SET_VALUE (symbolP
, 0);
4532 symbolP
->sy_name_offset
= 0;
4533 symbolP
->sy_number
= 0;
4534 symbolP
->sy_frag
= New_Frag
;
4535 symbolP
->sy_resolved
= 0;
4536 symbolP
->sy_resolving
= 0;
4537 /* this actually inserts at the beginning of the list */
4538 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4540 symbol_rootP
= symbolP
;
4542 * Generate a text fixup structure
4543 * to get "_c$main_args" stored into the
4546 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4547 fixP
->fx_frag
= New_Frag
;
4549 fixP
->fx_addsy
= symbolP
;
4551 fixP
->fx_offset
= 0;
4552 fixP
->fx_size
= sizeof (long);
4554 fixP
->fx_next
= text_fix_root
;
4555 text_fix_root
= fixP
;
4557 * Now make sure we exit from the loop
4563 * Try the next fragment
4565 prev_fragPP
= &fragP
->fr_next
;
4566 fragP
= fragP
->fr_next
;
4569 * Try the next fragment chain
4572 frchainP
= frchainP
->frch_next
;
4575 #endif /* HACK_DEC_C_STARTUP */
4580 * Write a VAX/VMS object file (everything else has been done!)
4582 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4587 struct frag
*text_frag_root
;
4588 struct frag
*data_frag_root
;
4590 register fragS
*fragP
;
4591 register symbolS
*symbolP
;
4592 register symbolS
*sp
;
4593 register struct fix
*fixP
;
4594 register struct VMS_Symbol
*vsp
;
4596 int Local_Initialized_Data_Size
= 0;
4598 int Psect_Number
= 0; /* Psect Index Number */
4599 int Text_Psect
= -1; /* Text Psect Index */
4600 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4601 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4604 * Create the VMS object file
4606 Create_VMS_Object_File ();
4608 * Write the module header records
4610 Write_VMS_MHD_Records ();
4613 * Store the Data segment:
4615 * Since this is REALLY hard to do any other way,
4616 * we actually manufacture the data segment and
4617 * the store the appropriate values out of it.
4618 * We need to generate this early, so that globalvalues
4619 * can be properly emitted.
4624 * Allocate the data segment
4626 Data_Segment
= (char *) xmalloc (data_siz
);
4628 * Run through the data fragments, filling in the segment
4630 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4632 register long int count
;
4633 register char *fill_literal
;
4634 register long int fill_size
;
4637 i
= fragP
->fr_address
- text_siz
;
4639 memcpy (Data_Segment
+ i
,
4644 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4645 fill_size
= fragP
->fr_var
;
4646 for (count
= fragP
->fr_offset
; count
; count
--)
4649 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4657 * Generate the VMS object file records
4658 * 1st GSD then TIR records
4661 /******* Global Symbol Dictionary *******/
4663 * Emit globalvalues now. We must do this before the text psect
4664 * is defined, or we will get linker warnings about multiply defined
4665 * symbols. All of the globalvalues "reference" psect 0, although
4666 * it really does not have anything to do with it.
4668 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4670 * Define the Text Psect
4672 Text_Psect
= Psect_Number
++;
4673 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4675 * Define the BSS Psect
4679 Bss_Psect
= Psect_Number
++;
4680 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4682 #ifndef gxx_bug_fixed
4684 * The g++ compiler does not write out external references to vtables
4685 * correctly. Check for this and holler if we see it happening.
4686 * If that compiler bug is ever fixed we can remove this.
4688 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4691 * Dispatch on symbol type
4693 switch (S_GET_RAW_TYPE (sp
)) {
4699 * Make a GSD global symbol reference
4702 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4704 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4705 as_warn("g++ wrote an extern reference to %s as a routine.",
4707 as_warn("I will fix it, but I hope that it was not really a routine");
4714 #endif /* gxx_bug_fixed */
4716 * Now scan the symbols and emit the appropriate GSD records
4718 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4721 * Dispatch on symbol type
4723 switch (S_GET_RAW_TYPE (sp
))
4726 * Global uninitialized data
4728 case N_UNDF
| N_EXT
:
4730 * Make a VMS data symbol entry
4732 vsp
= (struct VMS_Symbol
*)
4733 xmalloc (sizeof (*vsp
));
4735 vsp
->Size
= S_GET_VALUE (sp
);
4736 vsp
->Psect_Index
= Psect_Number
++;
4737 vsp
->Psect_Offset
= 0;
4738 vsp
->Next
= VMS_Symbols
;
4740 sp
->sy_number
= (int) vsp
;
4742 * Make the psect for this data
4744 if (S_GET_OTHER (sp
))
4745 Globalref
= VMS_Psect_Spec (
4751 Globalref
= VMS_Psect_Spec (
4759 /* See if this is an external vtable. We want to help the linker find
4760 these things in libraries, so we make a symbol reference. This
4761 is not compatible with VAX-C usage for variables, but since vtables are
4762 only used internally by g++, we can get away with this hack. */
4764 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4765 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4770 #ifdef NOT_VAX_11_C_COMPATIBLE
4772 * Place a global symbol at the
4773 * beginning of the Psect
4775 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4779 #endif /* NOT_VAX_11_C_COMPATIBLE */
4782 * Local uninitialized data
4786 * Make a VMS data symbol entry
4788 vsp
= (struct VMS_Symbol
*)
4789 xmalloc (sizeof (*vsp
));
4792 vsp
->Psect_Index
= Bss_Psect
;
4795 bss_address_frag
.fr_address
;
4796 vsp
->Next
= VMS_Symbols
;
4798 sp
->sy_number
= (int) vsp
;
4801 * Global initialized data
4803 case N_DATA
| N_EXT
:
4805 * Make a VMS data symbol entry
4807 vsp
= (struct VMS_Symbol
*)
4808 xmalloc (sizeof (*vsp
));
4810 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4811 text_siz
+ data_siz
);
4812 vsp
->Psect_Index
= Psect_Number
++;
4813 vsp
->Psect_Offset
= 0;
4814 vsp
->Next
= VMS_Symbols
;
4816 sp
->sy_number
= (int) vsp
;
4820 if (S_GET_OTHER (sp
))
4821 Globalref
= VMS_Psect_Spec (
4827 Globalref
= VMS_Psect_Spec (
4835 /* See if this is an external vtable. We want to help the linker find
4836 these things in libraries, so we make a symbol definition. This
4837 is not compatible with VAX-C usage for variables, but since vtables are
4838 only used internally by g++, we can get away with this hack. */
4840 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4841 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4846 #ifdef NOT_VAX_11_C_COMPATIBLE
4848 * Place a global symbol at the
4849 * beginning of the Psect
4851 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4855 #endif /* NOT_VAX_11_C_COMPATIBLE */
4858 * Local initialized data
4862 * Make a VMS data symbol entry
4864 vsp
= (struct VMS_Symbol
*)
4865 xmalloc (sizeof (*vsp
));
4868 VMS_Initialized_Data_Size (sp
,
4869 text_siz
+ data_siz
);
4870 vsp
->Psect_Index
= Data_Psect
;
4872 Local_Initialized_Data_Size
;
4873 Local_Initialized_Data_Size
+= vsp
->Size
;
4874 vsp
->Next
= VMS_Symbols
;
4876 sp
->sy_number
= (int) vsp
;
4879 * Global Text definition
4881 case N_TEXT
| N_EXT
:
4883 unsigned short Entry_Mask
;
4886 * Get the entry mask
4888 fragP
= sp
->sy_frag
;
4889 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4890 ((fragP
->fr_literal
[1] & 0xff)
4893 * Define the Procedure entry pt.
4895 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4902 * Local Text definition
4906 * Make a VMS data symbol entry
4908 if (Text_Psect
!= -1)
4910 vsp
= (struct VMS_Symbol
*)
4911 xmalloc (sizeof (*vsp
));
4914 vsp
->Psect_Index
= Text_Psect
;
4915 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4916 vsp
->Next
= VMS_Symbols
;
4918 sp
->sy_number
= (int) vsp
;
4926 * Make a GSD global symbol reference
4929 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4939 * Ignore STAB symbols
4940 * Including .stabs emitted by g++
4942 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4947 if (S_GET_TYPE (sp
) != 22)
4948 printf (" ERROR, unknown type (%d)\n",
4954 * Define the Data Psect
4956 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4961 Data_Psect
= Psect_Number
++;
4962 VMS_Psect_Spec ("$data",
4963 Local_Initialized_Data_Size
,
4966 * Scan the VMS symbols and fill in the data psect
4968 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4971 * Only look for undefined psects
4973 if (vsp
->Psect_Index
< 0)
4976 * And only initialized data
4978 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4979 vsp
->Psect_Index
= Data_Psect
;
4984 /******* Text Information and Relocation Records *******/
4986 * Write the text segment data
4991 * Scan the text fragments
4993 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4996 * Stop if we get to the data fragments
4998 if (fragP
== data_frag_root
)
5001 * Ignore fragments with no data
5003 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5006 * Go the the appropriate offset in the
5009 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5011 * Store the "fixed" part
5014 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5018 * Store the "variable" part
5020 if (fragP
->fr_var
&& fragP
->fr_offset
)
5021 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5028 * Now we go through the text segment fixups and
5029 * generate TIR records to fix up addresses within
5032 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5035 * We DO handle the case of "Symbol - Symbol" as
5036 * long as it is in the same segment.
5038 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5043 * They need to be in the same segment
5045 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5046 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5047 error ("Fixup data addsy and subsy didn't have the same type");
5049 * And they need to be in one that we
5050 * can check the psect on
5052 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5053 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5054 error ("Fixup data addsy and subsy didn't have an appropriate type");
5056 * This had better not be PC relative!
5059 error ("Fixup data was erroneously \"pcrel\"");
5061 * Subtract their values to get the
5064 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5065 S_GET_VALUE (fixP
->fx_subsy
);
5067 * Now generate the fixup object records
5068 * Set the psect and store the data
5070 VMS_Set_Psect (Text_Psect
,
5072 fixP
->fx_frag
->fr_address
,
5074 VMS_Store_Immediate_Data (&i
,
5083 * Size will HAVE to be "long"
5085 if (fixP
->fx_size
!= sizeof (long))
5086 error ("Fixup datum was not a longword");
5088 * Symbol must be "added" (if it is ever
5090 * fix this assumption)
5092 if (fixP
->fx_addsy
== 0)
5093 error ("Fixup datum was not \"fixP->fx_addsy\"");
5095 * Store the symbol value in a PIC fashion
5097 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5102 fixP
->fx_frag
->fr_address
,
5105 * Check for indirect address reference,
5106 * which has to be fixed up (as the linker
5107 * will screw it up with TIR_S_C_STO_PICR).
5110 VMS_Fix_Indirect_Reference (Text_Psect
,
5112 fixP
->fx_frag
->fr_address
,
5118 * Store the Data segment:
5120 * Since this is REALLY hard to do any other way,
5121 * we actually manufacture the data segment and
5122 * the store the appropriate values out of it.
5123 * The segment was manufactured before, now we just
5124 * dump it into the appropriate psects.
5130 * Now we can run through all the data symbols
5131 * and store the data
5133 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5136 * Ignore anything other than data symbols
5138 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5141 * Set the Psect + Offset
5143 VMS_Set_Psect (vsp
->Psect_Index
,
5149 VMS_Store_Immediate_Data (Data_Segment
+
5150 S_GET_VALUE (vsp
->Symbol
) -
5156 * Now we go through the data segment fixups and
5157 * generate TIR records to fix up addresses within
5160 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5163 * Find the symbol for the containing datum
5165 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5168 * Only bother with Data symbols
5171 if (S_GET_TYPE (sp
) != N_DATA
)
5174 * Ignore symbol if After fixup
5176 if (S_GET_VALUE (sp
) >
5178 fixP
->fx_frag
->fr_address
))
5181 * See if the datum is here
5183 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5185 fixP
->fx_frag
->fr_address
))
5188 * We DO handle the case of "Symbol - Symbol" as
5189 * long as it is in the same segment.
5191 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5196 * They need to be in the same segment
5198 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5199 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5200 error ("Fixup data addsy and subsy didn't have the same type");
5202 * And they need to be in one that we
5203 * can check the psect on
5205 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5206 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5207 error ("Fixup data addsy and subsy didn't have an appropriate type");
5209 * This had better not be PC relative!
5212 error ("Fixup data was erroneously \"pcrel\"");
5214 * Subtract their values to get the
5217 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5218 S_GET_VALUE (fixP
->fx_subsy
);
5220 * Now generate the fixup object records
5221 * Set the psect and store the data
5223 VMS_Set_Psect (vsp
->Psect_Index
,
5224 fixP
->fx_frag
->fr_address
+
5226 S_GET_VALUE (vsp
->Symbol
) +
5229 VMS_Store_Immediate_Data (&i
,
5238 * Size will HAVE to be "long"
5240 if (fixP
->fx_size
!= sizeof (long))
5241 error ("Fixup datum was not a longword");
5243 * Symbol must be "added" (if it is ever
5245 * fix this assumption)
5247 if (fixP
->fx_addsy
== 0)
5248 error ("Fixup datum was not \"fixP->fx_addsy\"");
5250 * Store the symbol value in a PIC fashion
5252 VMS_Store_PIC_Symbol_Reference (
5257 fixP
->fx_frag
->fr_address
+
5259 S_GET_VALUE (vsp
->Symbol
) +
5272 * Write the Traceback Begin Module record
5274 VMS_TBT_Module_Begin ();
5276 * Scan the symbols and write out the routines
5277 * (this makes the assumption that symbols are in
5278 * order of ascending text segment offset)
5281 struct symbol
*Current_Routine
= 0;
5282 int Current_Line_Number
= 0;
5283 int Current_Offset
= -1;
5284 struct input_file
*Current_File
;
5286 /* Output debugging info for global variables and static variables that are not
5287 * specific to one routine. We also need to examine all stabs directives, to
5288 * find the definitions to all of the advanced data types, and this is done by
5289 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5290 * the object file, since there can be forward references in the stabs
5291 * directives. When through with parsing, the text of the stabs directive
5292 * is altered, with the definitions removed, so that later passes will see
5293 * directives as they would be written if the type were already defined.
5295 * We also look for files and include files, and make a list of them. We
5296 * examine the source file numbers to establish the actual lines that code was
5297 * generated from, and then generate offsets.
5300 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5303 * Deal with STAB symbols
5305 if (S_IS_DEBUG (symbolP
))
5308 * Dispatch on STAB type
5310 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5313 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5314 Current_File
->max_line
= S_GET_DESC (symbolP
);
5315 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5316 Current_File
->min_line
= S_GET_DESC (symbolP
);
5319 Current_File
= find_file (symbolP
);
5320 Current_File
->flag
= 1;
5321 Current_File
->min_line
= 1;
5324 Current_File
= find_file (symbolP
);
5327 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5330 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5332 case N_FUN
: /* For static constant symbols */
5334 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5340 /* now we take a quick sweep through the files and assign offsets
5341 to each one. This will essentially be the starting line number to the
5342 debugger for each file. Output the info for the debugger to specify the
5343 files, and then tell it how many lines to use */
5345 int File_Number
= 0;
5346 int Debugger_Offset
= 0;
5348 Current_File
= file_root
;
5349 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5351 if (Current_File
== (struct input_file
*) NULL
)
5353 if (Current_File
->max_line
== 0)
5355 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5358 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5361 /* show a few extra lines at the start of the region selected */
5362 if (Current_File
->min_line
> 2)
5363 Current_File
->min_line
-= 2;
5364 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5365 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5366 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5367 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5370 Current_File
->file_number
= ++File_Number
;
5371 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5372 Current_File
->file_number
);
5373 if (!file_available
)
5375 Current_File
->file_number
= 0;
5380 VMS_TBT_Source_Lines (Current_File
->file_number
,
5381 Current_File
->min_line
,
5382 Current_File
->max_line
- Current_File
->min_line
+ 1);
5385 Current_File
= (struct input_file
*) NULL
;
5387 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5390 * Deal with text symbols
5392 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5395 * Ignore symbols starting with "L",
5396 * as they are local symbols
5398 if (*S_GET_NAME (symbolP
) == 'L')
5401 * If there is a routine start defined,
5404 if (Current_Routine
)
5409 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5412 * Store the routine begin traceback info
5414 if (Text_Psect
!= -1)
5416 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5417 Current_Routine
= symbolP
;
5419 /* Output local symbols, i.e. all symbols that are associated with a specific
5420 * routine. We output them now so the debugger recognizes them as local to
5427 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5429 if (!S_IS_DEBUG (symbolP1
))
5431 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5433 pnt
= S_GET_NAME (symbolP
);
5434 pnt1
= S_GET_NAME (symbolP1
);
5437 while (*pnt
++ == *pnt1
++)
5440 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5441 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5444 if (symbolP1
!= (symbolS
*) NULL
)
5445 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5446 } /* local symbol block */
5453 * Deal with STAB symbols
5455 if (S_IS_DEBUG (symbolP
))
5458 * Dispatch on STAB type
5460 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5466 /* Offset the line into the correct portion
5468 if (Current_File
->file_number
== 0)
5470 /* Sometimes the same offset gets several source
5471 * lines assigned to it.
5472 * We should be selective about which lines
5473 * we allow, we should prefer lines that are
5474 * in the main source file when debugging
5475 * inline functions. */
5476 if ((Current_File
->file_number
!= 1) &&
5477 S_GET_VALUE (symbolP
) ==
5480 /* calculate actual debugger source line */
5481 S_GET_DESC (symbolP
)
5482 += Current_File
->offset
;
5484 * If this is the 1st N_SLINE, setup
5485 * PC/Line correlation. Otherwise
5486 * do the delta PC/Line. If the offset
5487 * for the line number is not +ve we need
5488 * to do another PC/Line correlation
5491 if (Current_Offset
== -1)
5493 VMS_TBT_Line_PC_Correlation (
5494 S_GET_DESC (symbolP
),
5495 S_GET_VALUE (symbolP
),
5501 if ((S_GET_DESC (symbolP
) -
5502 Current_Line_Number
) <= 0)
5505 * Line delta is not +ve, we
5506 * need to close the line and
5507 * start a new PC/Line
5510 VMS_TBT_Line_PC_Correlation (0,
5511 S_GET_VALUE (symbolP
) -
5515 VMS_TBT_Line_PC_Correlation (
5516 S_GET_DESC (symbolP
),
5517 S_GET_VALUE (symbolP
),
5524 * Line delta is +ve, all is well
5526 VMS_TBT_Line_PC_Correlation (
5527 S_GET_DESC (symbolP
) -
5528 Current_Line_Number
,
5529 S_GET_VALUE (symbolP
) -
5536 * Update the current line/PC
5538 Current_Line_Number
= S_GET_DESC (symbolP
);
5539 Current_Offset
= S_GET_VALUE (symbolP
);
5549 * Remember that we had a source file
5550 * and emit the source file debugger
5554 find_file (symbolP
);
5556 /* We need to make sure that we are really in the actual source file when
5557 * we compute the maximum line number. Otherwise the debugger gets really
5561 find_file (symbolP
);
5567 * If there is a routine start defined,
5568 * terminate it (and the line numbers)
5570 if (Current_Routine
)
5573 * Terminate the line numbers
5575 VMS_TBT_Line_PC_Correlation (0,
5576 text_siz
- S_GET_VALUE (Current_Routine
),
5580 * Terminate the routine
5582 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5586 * Write the Traceback End Module TBT record
5588 VMS_TBT_Module_End ();
5591 * Write the End Of Module record
5593 if (Entry_Point_Symbol
== 0)
5594 Write_VMS_EOM_Record (-1, 0);
5596 Write_VMS_EOM_Record (Text_Psect
,
5597 S_GET_VALUE (Entry_Point_Symbol
));
5600 * All done, close the object file
5602 Close_VMS_Object_File ();
5605 /* end of obj-vms.c */