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 */
293 N_UNDF
, /* bignum/flonum */
294 N_UNDF
, /* difference */
298 N_REGISTER
, /* register */
301 const segT N_TYPE_seg
[N_TYPE
+ 2] =
302 { /* N_TYPE == 0x1E = 32-2 */
303 SEG_UNKNOWN
, /* N_UNDF == 0 */
305 SEG_ABSOLUTE
, /* N_ABS == 2 */
307 SEG_TEXT
, /* N_TEXT == 4 */
309 SEG_DATA
, /* N_DATA == 6 */
311 SEG_BSS
, /* N_BSS == 8 */
313 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
314 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
315 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
316 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
321 /* The following code defines the special types of pseudo-ops that we
332 temp
= get_absolute_expression ();
333 subseg_new (SEG_DATA
, (subsegT
) temp
);
335 demand_empty_rest_of_line ();
341 * Handle .stabX directives, which used to be open-coded.
342 * So much creeping featurism overloaded the semantics that we decided
343 * to put all .stabX thinking in one place. Here.
345 * We try to make any .stabX directive legal. Other people's AS will often
346 * do assembly-time consistency checks: eg assigning meaning to n_type bits
347 * and "protecting" you from setting them to certain values. (They also zero
348 * certain bits before emitting symbols. Tut tut.)
350 * If an expression is not absolute we either gripe or use the relocation
351 * information. Other people's assemblers silently forget information they
352 * don't need and invent information they need that you didn't supply.
354 * .stabX directives always make a symbol table entry. It may be junk if
355 * the rest of your .stabX directive is malformed.
363 #endif /* NO_LISTING */
365 register symbolS
*symbolP
= 0;
366 register char *string
;
369 int goof
; /* TRUE if we have aborted. */
373 * Enter with input_line_pointer pointing past .stabX and any following
376 goof
= 0; /* JF who forgot this?? */
379 string
= demand_copy_C_string (&length
);
381 if (*input_line_pointer
== ',')
382 input_line_pointer
++;
385 as_bad ("I need a comma after symbol's name");
393 * Input_line_pointer->after ','. String->symbol name.
397 symbolP
= symbol_new (string
,
404 S_SET_NAME (symbolP
, NULL
); /* .stabd feature. */
405 S_SET_VALUE (symbolP
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
406 symbolP
->sy_frag
= frag_now
;
410 symbolP
->sy_frag
= &zero_address_frag
;
414 symbolP
->sy_frag
= &zero_address_frag
;
422 if (get_absolute_expression_and_terminator (&longint
) == ',')
423 symbolP
->sy_symbol
.n_type
= saved_type
= longint
;
426 as_bad ("I want a comma after the n_type expression");
428 input_line_pointer
--; /* Backup over a non-',' char. */
434 if (get_absolute_expression_and_terminator (&longint
) == ',')
435 S_SET_OTHER (symbolP
, longint
);
438 as_bad ("I want a comma after the n_other expression");
440 input_line_pointer
--; /* Backup over a non-',' char. */
446 S_SET_DESC (symbolP
, get_absolute_expression ());
447 if (what
== 's' || what
== 'n')
449 if (*input_line_pointer
!= ',')
451 as_bad ("I want a comma after the n_desc expression");
456 input_line_pointer
++;
461 if ((!goof
) && (what
== 's' || what
== 'n'))
463 pseudo_set (symbolP
);
464 symbolP
->sy_symbol
.n_type
= saved_type
;
468 if (listing
&& !goof
)
470 if (symbolP
->sy_symbol
.n_type
== N_SLINE
)
473 listing_source_line(symbolP
->sy_symbol
.n_desc
);
475 else if (symbolP
->sy_symbol
.n_type
== N_SO
476 || symbolP
->sy_symbol
.n_type
== N_SOL
)
478 listing_source_file(string
);
484 ignore_rest_of_line ();
486 demand_empty_rest_of_line ();
487 } /* obj_aout_stab() */
489 const pseudo_typeS obj_pseudo_table
[] =
491 {"stabd", obj_aout_stab
, 'd'},/* stabs */
492 {"stabn", obj_aout_stab
, 'n'},/* stabs */
493 {"stabs", obj_aout_stab
, 's'},/* stabs */
494 {"const", s_const
, 0},
497 }; /* obj_pseudo_table */
500 vms_resolve_symbol_redef (sym
)
504 * If the new symbol is .comm AND it has a size of zero,
505 * we ignore it (i.e. the old symbol overrides it)
507 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)) &&
508 ((obstack_next_free (&frags
) - frag_now
->fr_literal
) == 0))
510 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
515 * If the old symbol is .comm and it has a size of zero,
516 * we override it with the new symbol value.
518 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
519 && (S_GET_VALUE(sym
) == 0))
521 as_warn ("compiler redefined zero-size common symbol `%s'",
523 sym
->sy_frag
= frag_now
;
524 S_GET_OTHER(sym
) = const_flag
;
525 S_SET_VALUE(sym
, obstack_next_free(& frags
) - frag_now
->fr_literal
);
526 /* Keep N_EXT bit. */
527 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
536 obj_read_begin_hook ()
539 } /* obj_read_begin_hook() */
542 obj_crawl_symbol_chain (headers
)
543 object_headers
*headers
;
547 int symbol_number
= 0;
549 /* JF deal with forward references first... */
550 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
552 if (symbolP
->sy_forward
)
554 S_SET_VALUE (symbolP
, S_GET_VALUE (symbolP
)
555 + S_GET_VALUE (symbolP
->sy_forward
)
556 + symbolP
->sy_forward
->sy_frag
->fr_address
);
557 symbolP
->sy_forward
= 0;
558 } /* if it has a forward reference */
559 } /* walk the symbol chain */
561 { /* crawl symbol table */
562 register int symbol_number
= 0;
565 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
566 while ((symbolP
= *symbolPP
) != NULL
)
568 S_SET_VALUE (symbolP
,
569 S_GET_VALUE (symbolP
) + symbolP
->sy_frag
->fr_address
);
571 /* OK, here is how we decide which symbols go out into the
572 brave new symtab. Symbols that do are:
574 * symbols with no name (stabd's?)
575 * symbols with debug info in their N_TYPE
577 Symbols that don't are:
578 * symbols that are registers
579 * symbols with \1 as their 3rd character (numeric labels)
580 * "local labels" as defined by S_LOCAL_NAME(name)
581 if the -L switch was passed to gas.
583 All other symbols are output. We complain if a deleted
584 symbol was marked external. */
587 if (!S_IS_REGISTER (symbolP
))
589 symbolP
->sy_name_offset
= 0;
590 symbolPP
= &(symbol_next (symbolP
));
594 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
596 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
599 } /* if this symbol should be in the output */
600 } /* for each symbol */
602 H_SET_STRING_SIZE (headers
, string_byte_count
);
603 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
604 } /* crawl symbol table */
606 } /* obj_crawl_symbol_chain() */
609 /****** VMS OBJECT FILE HACKING ROUTINES *******/
613 * Create the VMS object file
616 Create_VMS_Object_File ()
618 #if defined(eunice) || !defined(HO_VMS)
619 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
621 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
622 "mbc=16", "deq=64", "fop=tef", "shr=nil");
627 if (VMS_Object_File_FD
< 0)
629 char Error_Line
[256];
631 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
636 * Initialize object file hacking variables
638 Object_Record_Offset
= 0;
639 Current_Object_Record_Type
= -1;
644 * Flush the object record buffer to the object file
647 Flush_VMS_Object_Record_Buffer ()
653 * If the buffer is empty, we are done
655 if (Object_Record_Offset
== 0)
658 * Write the data to the file
660 #ifndef HO_VMS /* For cross-assembly purposes. */
661 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
662 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
663 #endif /* not HO_VMS */
664 i
= write (VMS_Object_File_FD
,
665 Object_Record_Buffer
,
666 Object_Record_Offset
);
667 if (i
!= Object_Record_Offset
)
668 error ("I/O error writing VMS object file");
669 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
671 /* pad it if needed */
673 if (Object_Record_Offset
& 1 != 0)
674 write (VMS_Object_File_FD
, &zero
, 1);
675 #endif /* not HO_VMS */
677 * The buffer is now empty
679 Object_Record_Offset
= 0;
684 * Declare a particular type of object file record
687 Set_VMS_Object_File_Record (Type
)
691 * If the type matches, we are done
693 if (Type
== Current_Object_Record_Type
)
696 * Otherwise: flush the buffer
698 Flush_VMS_Object_Record_Buffer ();
702 Current_Object_Record_Type
= Type
;
708 * Close the VMS Object file
711 Close_VMS_Object_File ()
713 short int m_one
= -1;
714 #ifndef HO_VMS /* For cross-assembly purposes. */
715 /* Write a 0xffff into the file, which means "End of File" */
716 write (VMS_Object_File_FD
, &m_one
, 2);
717 #endif /* not HO_VMS */
718 close (VMS_Object_File_FD
);
723 * Store immediate data in current Psect
726 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
734 * We are writing a "Record_Type" record
736 Set_VMS_Object_File_Record (Record_Type
);
738 * We can only store 128 bytes at a time
743 * Store a maximum of 128 bytes
745 i
= (Size
> 128) ? 128 : Size
;
748 * If we cannot accommodate this record, flush the
751 if ((Object_Record_Offset
+ i
+ 1) >=
752 sizeof (Object_Record_Buffer
))
753 Flush_VMS_Object_Record_Buffer ();
755 * If the buffer is empty we must insert record type
757 if (Object_Record_Offset
== 0)
758 PUT_CHAR (Record_Type
);
762 PUT_CHAR (-i
& 0xff);
767 PUT_CHAR (*Pointer
++);
769 * Flush the buffer if it is more than 75% full
771 if (Object_Record_Offset
>
772 (sizeof (Object_Record_Buffer
) * 3 / 4))
773 Flush_VMS_Object_Record_Buffer ();
778 * Make a data reference
781 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
788 * We are writing a "Record_Type" record
790 Set_VMS_Object_File_Record (Record_Type
);
792 * If the buffer is empty we must insert the record type
794 if (Object_Record_Offset
== 0)
795 PUT_CHAR (Record_Type
);
797 * Stack the Psect base + Longword Offset
801 if (Psect_Index
> 127)
803 PUT_CHAR (TIR_S_C_STA_WPL
);
804 PUT_SHORT (Psect_Index
);
809 PUT_CHAR (TIR_S_C_STA_PL
);
810 PUT_CHAR (Psect_Index
);
818 PUT_CHAR (TIR_S_C_STA_WPL
);
819 PUT_SHORT (Psect_Index
);
822 else if (Offset
> 127)
824 PUT_CHAR (TIR_S_C_STA_WPW
);
825 PUT_SHORT (Psect_Index
);
830 PUT_CHAR (TIR_S_C_STA_WPB
);
831 PUT_SHORT (Psect_Index
);
836 * Set relocation base
838 PUT_CHAR (TIR_S_C_STO_PIDR
);
840 * Flush the buffer if it is more than 75% full
842 if (Object_Record_Offset
>
843 (sizeof (Object_Record_Buffer
) * 3 / 4))
844 Flush_VMS_Object_Record_Buffer ();
848 * Make a debugger reference to a struct, union or enum.
851 VMS_Store_Struct (Struct_Index
)
855 * We are writing a "OBJ_S_C_DBG" record
857 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
859 * If the buffer is empty we must insert the record type
861 if (Object_Record_Offset
== 0)
862 PUT_CHAR (OBJ_S_C_DBG
);
863 PUT_CHAR (TIR_S_C_STA_UW
);
864 PUT_SHORT (Struct_Index
);
865 PUT_CHAR (TIR_S_C_CTL_STKDL
);
866 PUT_CHAR (TIR_S_C_STO_L
);
868 * Flush the buffer if it is more than 75% full
870 if (Object_Record_Offset
>
871 (sizeof (Object_Record_Buffer
) * 3 / 4))
872 Flush_VMS_Object_Record_Buffer ();
876 * Make a debugger reference to partially define a struct, union or enum.
879 VMS_Def_Struct (Struct_Index
)
883 * We are writing a "OBJ_S_C_DBG" record
885 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
887 * If the buffer is empty we must insert the record type
889 if (Object_Record_Offset
== 0)
890 PUT_CHAR (OBJ_S_C_DBG
);
891 PUT_CHAR (TIR_S_C_STA_UW
);
892 PUT_SHORT (Struct_Index
);
893 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
895 * Flush the buffer if it is more than 75% full
897 if (Object_Record_Offset
>
898 (sizeof (Object_Record_Buffer
) * 3 / 4))
899 Flush_VMS_Object_Record_Buffer ();
903 VMS_Set_Struct (Struct_Index
)
905 { /* see previous functions for comments */
906 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
907 if (Object_Record_Offset
== 0)
908 PUT_CHAR (OBJ_S_C_DBG
);
909 PUT_CHAR (TIR_S_C_STA_UW
);
910 PUT_SHORT (Struct_Index
);
911 PUT_CHAR (TIR_S_C_CTL_STLOC
);
912 if (Object_Record_Offset
>
913 (sizeof (Object_Record_Buffer
) * 3 / 4))
914 Flush_VMS_Object_Record_Buffer ();
918 * Write the Traceback Module Begin record
921 VMS_TBT_Module_Begin ()
923 register char *cp
, *cp1
;
925 char Module_Name
[256];
929 * Get module name (the FILENAME part of the object file)
935 if ((*cp
== ']') || (*cp
== '>') ||
936 (*cp
== ':') || (*cp
== '/'))
942 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
946 * Limit it to 31 characters
948 while (--cp1
>= Module_Name
)
951 if (strlen (Module_Name
) > 31)
954 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
958 * Arrange to store the data locally (leave room for size byte)
964 *cp
++ = DST_S_C_MODBEG
;
970 * Language type == "C"
972 COPY_LONG (cp
, DST_S_C_C
);
975 * Store the module name
977 *cp
++ = strlen (Module_Name
);
982 * Now we can store the record size
987 * Put it into the object record
989 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
994 * Write the Traceback Module End record
997 VMS_TBT_Module_End ()
1005 Local
[1] = DST_S_C_MODEND
;
1007 * Put it into the object record
1009 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
1014 * Write the Traceback Routine Begin record
1017 VMS_TBT_Routine_Begin (symbolP
, Psect
)
1018 struct symbol
*symbolP
;
1021 register char *cp
, *cp1
;
1028 * Strip the leading "_" from the name
1030 Name
= S_GET_NAME (symbolP
);
1034 * Get the text psect offset
1036 Offset
= S_GET_VALUE (symbolP
);
1038 * Calculate the record size
1040 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1048 Local
[1] = DST_S_C_RTNBEG
;
1054 * Store the data so far
1056 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1058 * Make sure we are still generating a OBJ_S_C_TBT record
1060 if (Object_Record_Offset
== 0)
1061 PUT_CHAR (OBJ_S_C_TBT
);
1063 * Now get the symbol address
1065 PUT_CHAR (TIR_S_C_STA_WPL
);
1069 * Store the data reference
1071 PUT_CHAR (TIR_S_C_STO_PIDR
);
1073 * Store the counted string as data
1077 Size
= strlen (cp1
) + 1;
1081 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1086 * Write the Traceback Routine End record
1087 * We *must* search the symbol table to find the next routine, since
1088 * the assember has a way of reassembling the symbol table OUT OF ORDER
1089 * Thus the next routine in the symbol list is not necessarily the
1090 * next one in memory. For debugging to work correctly we must know the
1091 * size of the routine.
1094 VMS_TBT_Routine_End (Max_Size
, sp
)
1099 int Size
= 0x7fffffff;
1103 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1105 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1107 if (*S_GET_NAME (symbolP
) == 'L')
1109 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
1110 (S_GET_VALUE (symbolP
) < Size
))
1111 Size
= S_GET_VALUE (symbolP
);
1112 /* check if gcc_compiled. has size of zero */
1113 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
1115 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1116 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1117 Size
= S_GET_VALUE (symbolP
);
1121 if (Size
== 0x7fffffff)
1123 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
1131 Local
[1] = DST_S_C_RTNEND
;
1139 COPY_LONG (&Local
[3], Size
);
1143 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1147 * Write the Traceback Block End record
1150 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1151 struct symbol
*symbolP
;
1155 register char *cp
, *cp1
;
1162 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1168 * Begin Block - We simulate with a phony routine
1170 Local
[1] = DST_S_C_BLKBEG
;
1176 * Store the data so far
1178 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1180 * Make sure we are still generating a OBJ_S_C_DBG record
1182 if (Object_Record_Offset
== 0)
1183 PUT_CHAR (OBJ_S_C_DBG
);
1185 * Now get the symbol address
1187 PUT_CHAR (TIR_S_C_STA_WPL
);
1190 * Get the text psect offset
1192 Offset
= S_GET_VALUE (symbolP
);
1195 * Store the data reference
1197 PUT_CHAR (TIR_S_C_STO_PIDR
);
1199 * Store the counted string as data
1203 Size
= strlen (cp1
) + 1;
1207 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1212 * Write the Traceback Block End record
1215 VMS_TBT_Block_End (Size
)
1221 * End block - simulate with a phony end routine
1224 Local
[1] = DST_S_C_BLKEND
;
1225 COPY_LONG (&Local
[3], Size
);
1230 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1236 * Write a Line number / PC correlation record
1239 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1249 * If not delta, set our PC/Line number correlation
1256 Local
[0] = 1 + 1 + 2 + 1 + 4;
1258 * Line Number/PC correlation
1260 Local
[1] = DST_S_C_LINE_NUM
;
1264 Local
[2] = DST_S_C_SET_LINE_NUM
;
1265 COPY_SHORT (&Local
[3], Line_Number
- 1);
1269 Local
[5] = DST_S_C_SET_ABS_PC
;
1270 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1272 * Make sure we are still generating a OBJ_S_C_TBT record
1274 if (Object_Record_Offset
== 0)
1275 PUT_CHAR (OBJ_S_C_TBT
);
1278 PUT_CHAR (TIR_S_C_STA_PL
);
1283 PUT_CHAR (TIR_S_C_STA_WPL
);
1287 PUT_CHAR (TIR_S_C_STO_PIDR
);
1289 * Do a PC offset of 0 to register the line number
1292 Local
[1] = DST_S_C_LINE_NUM
;
1293 Local
[2] = 0; /* Increment PC by 0 and register line # */
1294 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1299 * If Delta is negative, terminate the line numbers
1303 Local
[0] = 1 + 1 + 4;
1304 Local
[1] = DST_S_C_LINE_NUM
;
1305 Local
[2] = DST_S_C_TERM_L
;
1306 COPY_LONG (&Local
[3], Offset
);
1307 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1314 * Do a PC/Line delta
1317 *cp
++ = DST_S_C_LINE_NUM
;
1318 if (Line_Number
> 1)
1321 * We need to increment the line number
1323 if (Line_Number
- 1 <= 255)
1325 *cp
++ = DST_S_C_INCR_LINUM
;
1326 *cp
++ = Line_Number
- 1;
1330 *cp
++ = DST_S_C_INCR_LINUM_W
;
1331 COPY_SHORT (cp
, Line_Number
- 1);
1332 cp
+= sizeof (short);
1344 if (Offset
< 0x10000)
1346 *cp
++ = DST_S_C_DELTA_PC_W
;
1347 COPY_SHORT (cp
, Offset
);
1348 cp
+= sizeof (short);
1352 *cp
++ = DST_S_C_DELTA_PC_L
;
1353 COPY_LONG (cp
, Offset
);
1354 cp
+= sizeof (long);
1357 Local
[0] = cp
- (Local
+ 1);
1358 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1364 * Describe a source file to the debugger
1367 VMS_TBT_Source_File (Filename
, ID_Number
)
1371 register char *cp
, *cp1
;
1374 #ifndef HO_VMS /* Used for cross-assembly */
1375 i
= strlen (Filename
);
1377 static struct FAB Fab
;
1378 static struct NAM Nam
;
1379 static struct XABDAT Date_Xab
;
1380 static struct XABFHC File_Header_Xab
;
1381 char Es_String
[255], Rs_String
[255];
1386 Fab
.fab$b_bid
= FAB$C_BID
;
1387 Fab
.fab$b_bln
= sizeof (Fab
);
1388 Fab
.fab$l_nam
= (&Nam
);
1389 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1391 * Setup the Nam block so we can find out the FULL name
1392 * of the source file.
1394 Nam
.nam$b_bid
= NAM$C_BID
;
1395 Nam
.nam$b_bln
= sizeof (Nam
);
1396 Nam
.nam$l_rsa
= Rs_String
;
1397 Nam
.nam$b_rss
= sizeof (Rs_String
);
1398 Nam
.nam$l_esa
= Es_String
;
1399 Nam
.nam$b_ess
= sizeof (Es_String
);
1401 * Setup the Date and File Header Xabs
1403 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1404 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1405 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1406 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1407 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1409 * Get the file information
1411 Fab
.fab$l_fna
= Filename
;
1412 Fab
.fab$b_fns
= strlen (Filename
);
1413 Status
= sys$
open (&Fab
);
1416 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1422 * Calculate the size of the resultant string
1429 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1431 * Source declaration
1433 Local
[1] = DST_S_C_SOURCE
;
1435 * Make formfeeds count as source records
1437 Local
[2] = DST_S_C_SRC_FORMFEED
;
1439 * Declare source file
1441 Local
[3] = DST_S_C_SRC_DECLFILE
;
1442 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1451 COPY_SHORT (cp
, ID_Number
);
1452 cp
+= sizeof (short);
1455 * Creation Date. Unknown, so we fill with zeroes.
1458 cp
+= sizeof (long);
1460 cp
+= sizeof (long);
1465 cp
+= sizeof (long);
1470 cp
+= sizeof (short);
1480 #else /* Use this code when assembling for VMS on a VMS system */
1484 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1485 cp
+= sizeof (long);
1486 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1487 cp
+= sizeof (long);
1491 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1492 cp
+= sizeof (long);
1496 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1497 cp
+= sizeof (short);
1501 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1511 * Library module name (none)
1517 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1523 * Give the number of source lines to the debugger
1526 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1528 int Starting_Line_Number
;
1529 int Number_Of_Lines
;
1537 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1539 * Source declaration
1541 Local
[1] = DST_S_C_SOURCE
;
1546 *cp
++ = DST_S_C_SRC_SETFILE
;
1550 COPY_SHORT (cp
, ID_Number
);
1551 cp
+= sizeof (short);
1555 *cp
++ = DST_S_C_SRC_SETREC_L
;
1556 COPY_LONG (cp
, Starting_Line_Number
);
1557 cp
+= sizeof (long);
1561 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1562 COPY_SHORT (cp
, Number_Of_Lines
);
1563 cp
+= sizeof (short);
1567 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1573 /* This routine locates a file in the list of files. If an entry does not
1574 * exist, one is created. For include files, a new entry is always created
1575 * such that inline functions can be properly debugged. */
1576 static struct input_file
*
1580 struct input_file
*same_file
;
1581 struct input_file
*fpnt
;
1582 same_file
= (struct input_file
*) NULL
;
1583 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1585 if (fpnt
== (struct input_file
*) NULL
)
1587 if (fpnt
->spnt
== sp
)
1590 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1592 if (fpnt
== (struct input_file
*) NULL
)
1594 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1596 if (fpnt
->flag
== 1)
1602 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1603 if (file_root
== (struct input_file
*) NULL
)
1607 struct input_file
*fpnt1
;
1608 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1611 fpnt
->next
= (struct input_file
*) NULL
;
1612 fpnt
->name
= S_GET_NAME (sp
);
1613 fpnt
->min_line
= 0x7fffffff;
1617 fpnt
->file_number
= 0;
1619 fpnt
->same_file_fpnt
= same_file
;
1624 * The following functions and definitions are used to generate object records
1625 * that will describe program variables to the VMS debugger.
1627 * This file contains many of the routines needed to output debugging info into
1628 * the object file that the VMS debugger needs to understand symbols. These
1629 * routines are called very late in the assembly process, and thus we can be
1630 * fairly lax about changing things, since the GSD and the TIR sections have
1631 * already been output.
1635 /* This routine converts a number string into an integer, and stops when it
1636 * sees an invalid character the return value is the address of the character
1637 * just past the last character read. No error is generated.
1640 cvt_integer (str
, rtn
)
1645 neg
= *str
== '-' ? ++str
, -1 : 1;
1646 ival
= 0; /* first get the number of the type for dbx */
1647 while ((*str
<= '9') && (*str
>= '0'))
1648 ival
= 10 * ival
+ *str
++ - '0';
1653 /* this routine fixes the names that are generated by C++, ".this" is a good
1654 * example. The period does not work for the debugger, since it looks like
1655 * the syntax for a structure element, and thus it gets mightily confused
1657 * We also use this to strip the PsectAttribute hack from the name before we
1658 * write a debugger record */
1666 * Kill any leading "_"
1671 * Is there a Psect Attribute to skip??
1673 if (HAS_PSECT_ATTRIBUTES (pnt
))
1678 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1681 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1689 /* Here we fix the .this -> $this conversion */
1690 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1698 /* When defining a structure, this routine is called to find the name of
1699 * the actual structure. It is assumed that str points to the equal sign
1700 * in the definition, and it moves backward until it finds the start of the
1701 * name. If it finds a 0, then it knows that this structure def is in the
1702 * outermost level, and thus symbol_name points to the symbol name.
1705 get_struct_name (str
)
1710 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1715 while ((*pnt
!= ';') && (*pnt
!= '='))
1719 while ((*pnt
< '0') || (*pnt
> '9'))
1721 while ((*pnt
>= '0') && (*pnt
<= '9'))
1726 /* search symbol list for type number dbx_type. Return a pointer to struct */
1727 static struct VMS_DBG_Symbol
*
1728 find_symbol (dbx_type
)
1731 struct VMS_DBG_Symbol
*spnt
;
1732 spnt
= VMS_Symbol_type_list
;
1733 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1735 if (spnt
->dbx_type
== dbx_type
)
1739 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1740 return 0; /*Dunno what this is*/
1741 if(spnt
->advanced
== ALIAS
)
1742 return find_symbol(spnt
->type2
);
1747 /* this routine puts info into either Local or Asuffix, depending on the sign
1748 * of size. The reason is that it is easier to build the variable descriptor
1749 * backwards, while the array descriptor is best built forwards. In the end
1750 * they get put together, if there is not a struct/union/enum along the way
1769 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1773 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1776 Apoint
= MAX_DEBUG_RECORD
- 1;
1779 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1784 /* this routine generates the array descriptor for a given array */
1786 array_suffix (spnt2
)
1787 struct VMS_DBG_Symbol
*spnt2
;
1789 struct VMS_DBG_Symbol
*spnt
;
1790 struct VMS_DBG_Symbol
*spnt1
;
1796 while (spnt
->advanced
!= ARRAY
)
1798 spnt
= find_symbol (spnt
->type2
);
1799 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1805 while (spnt1
->advanced
== ARRAY
)
1808 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1809 spnt1
= find_symbol (spnt1
->type2
);
1811 total_size
= total_size
* spnt1
->data_size
;
1812 push (spnt1
->data_size
, 2);
1813 if (spnt1
->VMS_type
== 0xa3)
1816 push (spnt1
->VMS_type
, 1);
1818 for (i
= 0; i
< 6; i
++)
1822 push (total_size
, 4);
1825 while (spnt1
->advanced
== ARRAY
)
1827 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1828 spnt1
= find_symbol (spnt1
->type2
);
1831 while (spnt1
->advanced
== ARRAY
)
1833 push (spnt1
->index_min
, 4);
1834 push (spnt1
->index_max
, 4);
1835 spnt1
= find_symbol (spnt1
->type2
);
1839 /* this routine generates the start of a variable descriptor based upon
1840 * a struct/union/enum that has yet to be defined. We define this spot as
1841 * a new location, and save four bytes for the address. When the struct is
1842 * finally defined, then we can go back and plug in the correct address
1845 new_forward_ref (dbx_type
)
1848 struct forward_ref
*fpnt
;
1849 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1850 fpnt
->next
= f_ref_root
;
1852 fpnt
->dbx_type
= dbx_type
;
1853 fpnt
->struc_numb
= ++structure_count
;
1854 fpnt
->resolved
= 'N';
1857 push (total_len
, -2);
1858 struct_number
= -fpnt
->struc_numb
;
1861 /* this routine generates the variable descriptor used to describe non-basic
1862 * variables. It calls itself recursively until it gets to the bottom of it
1863 * all, and then builds the descriptor backwards. It is easiest to do it this
1864 *way since we must periodically write length bytes, and it is easiest if we know
1865 *the value when it is time to write it.
1868 gen1 (spnt
, array_suffix_len
)
1869 struct VMS_DBG_Symbol
*spnt
;
1870 int array_suffix_len
;
1872 struct VMS_DBG_Symbol
*spnt1
;
1874 switch (spnt
->advanced
)
1877 push (DBG_S_C_VOID
, -1);
1879 push (total_len
, -2);
1883 if (array_suffix_len
== 0)
1885 push (spnt
->VMS_type
, -1);
1886 push (DBG_S_C_BASIC
, -1);
1888 push (total_len
, -2);
1898 struct_number
= spnt
->struc_numb
;
1899 if (struct_number
< 0)
1901 new_forward_ref (spnt
->dbx_type
);
1904 push (DBG_S_C_STRUCT
, -1);
1906 push (total_len
, -2);
1909 spnt1
= find_symbol (spnt
->type2
);
1911 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1912 new_forward_ref (spnt
->type2
);
1914 i
= gen1 (spnt1
, 0);
1916 { /* (*void) is a special case, do not put pointer suffix*/
1917 push (DBG_S_C_POINTER
, -1);
1919 push (total_len
, -2);
1924 while (spnt1
->advanced
== ARRAY
)
1926 spnt1
= find_symbol (spnt1
->type2
);
1927 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1929 printf ("gcc-as warning(debugger output):");
1930 printf ("Forward reference error, dbx type %d\n",
1935 /* It is too late to generate forward references, so the user gets a message.
1936 * This should only happen on a compiler error */
1937 i
= gen1 (spnt1
, 1);
1939 array_suffix (spnt
);
1940 array_suffix_len
= Apoint
- i
;
1941 switch (spnt1
->advanced
)
1949 push (total_len
, -2);
1952 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1954 total_len
+= array_suffix_len
+ 8;
1955 push (total_len
, -2);
1959 /* This generates a suffix for a variable. If it is not a defined type yet,
1960 * then dbx_type contains the type we are expecting so we can generate a
1961 * forward reference. This calls gen1 to build most of the descriptor, and
1962 * then it puts the icing on at the end. It then dumps whatever is needed
1963 * to get a complete descriptor (i.e. struct reference, array suffix ).
1966 generate_suffix (spnt
, dbx_type
)
1967 struct VMS_DBG_Symbol
*spnt
;
1972 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1973 struct VMS_DBG_Symbol
*spnt1
;
1975 Lpnt
= MAX_DEBUG_RECORD
- 1;
1979 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1980 new_forward_ref (dbx_type
);
1983 if (spnt
->VMS_type
!= 0xa3)
1984 return 0; /* no suffix needed */
1989 push (total_len
, -1);
1990 /* if the variable descriptor overflows the record, output a descriptor for
1991 * a pointer to void.
1993 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1995 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1996 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
2000 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
2001 Local
[i
++] = Local
[++Lpnt
];
2003 /* we use this for a reference to a structure that has already been defined */
2004 if (struct_number
> 0)
2006 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2008 VMS_Store_Struct (struct_number
);
2010 /* we use this for a forward reference to a structure that has yet to be
2011 *defined. We store four bytes of zero to make room for the actual address once
2014 if (struct_number
< 0)
2016 struct_number
= -struct_number
;
2017 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2019 VMS_Def_Struct (struct_number
);
2020 for (i
= 0; i
< 4; i
++)
2022 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2027 Local
[Lpnt
++] = Asuffix
[i
++];
2029 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2033 /* This routine generates a symbol definition for a C sybmol for the debugger.
2034 * It takes a psect and offset for global symbols - if psect < 0, then this is
2035 * a local variable and the offset is relative to FP. In this case it can
2036 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2039 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2040 struct VMS_DBG_Symbol
*spnt
;
2050 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
2052 { /* this is a local variable, referenced to SP */
2053 maxlen
= 7 + strlen (Name_pnt
);
2054 Local
[i
++] = maxlen
;
2055 Local
[i
++] = spnt
->VMS_type
;
2057 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
2059 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
2060 COPY_LONG (&Local
[i
], Offset
);
2065 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
2066 Local
[i
++] = 7 + strlen (Name_pnt
);
2067 Local
[i
++] = spnt
->VMS_type
;
2069 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2071 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2073 Local
[i
++] = strlen (Name_pnt
);
2074 while (*Name_pnt
!= '\0')
2075 Local
[i
++] = *Name_pnt
++;
2076 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2077 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2078 generate_suffix (spnt
, 0);
2082 /* This routine parses the stabs entries in order to make the definition
2083 * for the debugger of local symbols and function parameters
2086 VMS_local_stab_Parse (sp
)
2092 struct VMS_DBG_Symbol
*spnt
;
2093 struct VMS_Symbol
*vsp
;
2097 str
= S_GET_NAME (sp
);
2098 pnt
= (char *) strchr (str
, ':');
2099 if (pnt
== (char *) NULL
)
2100 return; /* no colon present */
2101 pnt1
= pnt
++; /* save this for later, and skip colon */
2103 return 0; /* ignore static constants */
2104 /* there is one little catch that we must be aware of. Sometimes function
2105 * parameters are optimized into registers, and the compiler, in its infiite
2106 * wisdom outputs stabs records for *both*. In general we want to use the
2107 * register if it is present, so we must search the rest of the symbols for
2108 * this function to see if this parameter is assigned to a register.
2116 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2118 if (!S_IS_DEBUG (sp1
))
2120 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2122 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2123 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2125 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2127 str1
= S_GET_NAME (sp1
); /* and get the name */
2129 while (*pnt2
!= ':')
2136 if ((*str1
!= ':') || (*pnt2
!= ':'))
2138 return; /* they are the same! lets skip this one */
2140 /* first find the dbx symbol type from list, and then find VMS type */
2141 pnt
++; /* skip p in case no register */
2144 pnt
= cvt_integer (pnt
, &dbx_type
);
2145 spnt
= find_symbol (dbx_type
);
2146 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2147 return 0; /*Dunno what this is*/
2149 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2150 *pnt1
= ':'; /* and restore the string */
2154 /* This routine parses a stabs entry to find the information required to define
2155 * a variable. It is used for global and static variables.
2156 * Basically we need to know the address of the symbol. With older versions
2157 * of the compiler, const symbols are
2158 * treated differently, in that if they are global they are written into the
2159 * text psect. The global symbol entry for such a const is actually written
2160 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2161 * of psects, we must search the entry points as well. static consts are even
2162 * harder, since they are never assigned a memory address. The compiler passes
2163 * a stab to tell us the value, but I am not sure what to do with it.
2167 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2170 int type1
, type2
, Text_Psect
;
2176 struct VMS_DBG_Symbol
*spnt
;
2177 struct VMS_Symbol
*vsp
;
2181 str
= S_GET_NAME (sp
);
2182 pnt
= (char *) strchr (str
, ':');
2183 if (pnt
== (char *) NULL
)
2184 return; /* no colon present */
2185 pnt1
= pnt
; /* save this for later*/
2187 if (*pnt
== expected_type
)
2189 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2190 spnt
= find_symbol (dbx_type
);
2191 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2192 return 0; /*Dunno what this is*/
2193 /* now we need to search the symbol table to find the psect and offset for
2198 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2200 pnt
= S_GET_NAME (vsp
->Symbol
);
2201 if (pnt
!= (char *) NULL
)
2203 /* make sure name is the same, and make sure correct symbol type */
2204 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2205 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2206 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2210 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2212 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2213 *pnt1
= ':'; /* and restore the string */
2216 /* the symbol was not in the symbol list, but it may be an "entry point"
2217 if it was a constant */
2218 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2221 * Dispatch on STAB type
2223 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2225 pnt
= S_GET_NAME (sp1
);
2228 if (strcmp (pnt
, str
) == 0)
2230 if (!gave_compiler_message
&& expected_type
== 'G')
2232 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2233 printf ("global constant(s) in the text psect. These will not be available to\n");
2234 printf ("other modules, since this is not the correct way to handle this. You\n");
2235 printf ("have two options: 1) get a patched compiler that does not put global\n");
2236 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2237 printf ("definitions of global variables in your source module(s). Don't say\n");
2238 printf ("I didn't warn you!");
2239 gave_compiler_message
= 1;
2241 VMS_DBG_record (spnt
,
2246 *S_GET_NAME (sp1
) = 'L';
2247 /* fool assembler to not output this
2248 * as a routine in the TBT */
2253 *pnt1
= ':'; /* and restore the string */
2258 VMS_GSYM_Parse (sp
, Text_Psect
)
2261 { /* Global variables */
2262 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2267 VMS_LCSYM_Parse (sp
, Text_Psect
)
2270 { /* Static symbols - uninitialized */
2271 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2275 VMS_STSYM_Parse (sp
, Text_Psect
)
2278 { /* Static symbols - initialized */
2279 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2283 /* for register symbols, we must figure out what range of addresses within the
2284 * psect are valid. We will use the brackets in the stab directives to give us
2285 * guidance as to the PC range that this variable is in scope. I am still not
2286 * completely comfortable with this but as I learn more, I seem to get a better
2287 * handle on what is going on.
2291 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2292 symbolS
*sp
, *Current_Routine
;
2299 struct VMS_DBG_Symbol
*spnt
;
2304 int Min_Offset
= -1; /* min PC of validity */
2305 int Max_Offset
= 0; /* max PC of validity */
2307 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2310 * Dispatch on STAB type
2312 switch (S_GET_RAW_TYPE (symbolP
))
2316 Min_Offset
= S_GET_VALUE (symbolP
);
2321 S_GET_VALUE (symbolP
) - 1;
2324 if ((Min_Offset
!= -1) && (bcnt
== 0))
2326 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2328 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2329 if (*pnt
== 'F' || *pnt
== 'f') break;
2332 /* check to see that the addresses were defined. If not, then there were no
2333 * brackets in the function, and we must try to search for the next function
2334 * Since functions can be in any order, we should search all of the symbol list
2335 * to find the correct ending address. */
2336 if (Min_Offset
== -1)
2338 int Max_Source_Offset
;
2340 Min_Offset
= S_GET_VALUE (sp
);
2341 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2344 * Dispatch on STAB type
2346 This_Offset
= S_GET_VALUE (symbolP
);
2347 switch (S_GET_RAW_TYPE (symbolP
))
2349 case N_TEXT
| N_EXT
:
2350 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2351 Max_Offset
= This_Offset
;
2354 if (This_Offset
> Max_Source_Offset
)
2355 Max_Source_Offset
= This_Offset
;
2358 /* if this is the last routine, then we use the PC of the last source line
2359 * as a marker of the max PC for which this reg is valid */
2360 if (Max_Offset
== 0x7fffffff)
2361 Max_Offset
= Max_Source_Offset
;
2364 str
= S_GET_NAME (sp
);
2365 pnt
= (char *) strchr (str
, ':');
2366 if (pnt
== (char *) NULL
)
2367 return; /* no colon present */
2368 pnt1
= pnt
; /* save this for later*/
2372 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2373 spnt
= find_symbol (dbx_type
);
2374 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2375 return 0; /*Dunno what this is yet*/
2377 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2378 maxlen
= 25 + strlen (pnt
);
2379 Local
[i
++] = maxlen
;
2380 Local
[i
++] = spnt
->VMS_type
;
2382 Local
[i
++] = strlen (pnt
) + 1;
2386 Local
[i
++] = strlen (pnt
);
2387 while (*pnt
!= '\0')
2388 Local
[i
++] = *pnt
++;
2394 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2396 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2397 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2399 Local
[i
++] = S_GET_VALUE (sp
);
2403 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2405 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2406 generate_suffix (spnt
, 0);
2409 /* this function examines a structure definition, checking all of the elements
2410 * to make sure that all of them are fully defined. The only thing that we
2411 * kick out are arrays of undefined structs, since we do not know how big
2412 * they are. All others we can handle with a normal forward reference.
2415 forward_reference (pnt
)
2419 struct VMS_DBG_Symbol
*spnt
;
2420 struct VMS_DBG_Symbol
*spnt1
;
2421 pnt
= cvt_integer (pnt
+ 1, &i
);
2423 return 0; /* no forward references */
2426 pnt
= (char *) strchr (pnt
, ':');
2427 pnt
= cvt_integer (pnt
+ 1, &i
);
2428 spnt
= find_symbol (i
);
2429 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2430 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2433 spnt1
= find_symbol (spnt
->type2
);
2434 if ((spnt
->advanced
== ARRAY
) &&
2435 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2437 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2442 pnt
= cvt_integer (pnt
+ 1, &i
);
2443 pnt
= cvt_integer (pnt
+ 1, &i
);
2444 } while (*++pnt
!= ';');
2445 return 0; /* no forward refences found */
2448 /* Used to check a single element of a structure on the final pass*/
2451 final_forward_reference (spnt
)
2452 struct VMS_DBG_Symbol
* spnt
;
2454 struct VMS_DBG_Symbol
* spnt1
;
2455 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2456 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2457 spnt1
= find_symbol(spnt
->type2
);
2458 if((spnt
->advanced
== ARRAY
) &&
2459 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2460 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2464 return 0; /* no forward refences found */
2467 /* This routine parses the stabs directives to find any definitions of dbx type
2468 * numbers. It makes a note of all of them, creating a structure element
2469 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2470 * debugger that describes the struct/union/enum, so that further references
2471 * to these data types will be by number
2472 * We have to process pointers right away, since there can be references
2473 * to them later in the same stabs directive. We cannot have forward
2474 * references to pointers, (but we can have a forward reference to a pointer to
2475 * a structure/enum/union) and this is why we process them immediately.
2476 * After we process the pointer, then we search for defs that are nested even
2478 * 8/15/92: We have to process arrays right away too, because there can
2479 * be multiple references to identical array types in one structure
2480 * definition, and only the first one has the definition. (We tend to
2481 * parse from the back going forward.
2484 VMS_typedef_parse (str
)
2492 struct forward_ref
*fpnt
;
2494 int convert_integer
;
2495 struct VMS_DBG_Symbol
*spnt
;
2496 struct VMS_DBG_Symbol
*spnt1
;
2497 /* check for any nested def's */
2498 pnt
= (char *) strchr (str
+ 1, '=');
2499 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2500 && (str
[1] != 'a' || str
[2] != 'r'))
2501 if (VMS_typedef_parse (pnt
) == 1)
2503 /* now find dbx_type of entry */
2506 { /* check for static constants */
2507 *str
= '\0'; /* for now we ignore them */
2510 while ((*pnt
<= '9') && (*pnt
>= '0'))
2512 pnt
++; /* and get back to the number */
2513 cvt_integer (pnt
, &i1
);
2514 spnt
= find_symbol (i1
);
2515 /* first we see if this has been defined already, due to a forward reference*/
2516 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2518 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2520 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2521 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2522 VMS_Symbol_type_list
= spnt
;
2526 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2527 spnt
->next
= VMS_Symbol_type_list
;
2528 VMS_Symbol_type_list
= spnt
;
2530 spnt
->dbx_type
= i1
; /* and save the type */
2532 /* for structs and unions, do a partial parse, otherwise we sometimes get
2533 * circular definitions that are impossible to resolve. We read enough info
2534 * so that any reference to this type has enough info to be resolved
2536 pnt
= str
+ 1; /* point to character past equal sign */
2537 if ((*pnt
== 'u') || (*pnt
== 's'))
2540 if ((*pnt
<= '9') && (*pnt
>= '0'))
2542 if (type_check ("void"))
2543 { /* this is the void symbol */
2545 spnt
->advanced
= VOID
;
2548 if (type_check ("unknown type"))
2549 { /* this is the void symbol */
2551 spnt
->advanced
= UNKNOWN
;
2554 pnt1
= cvt_integer(pnt
,&i1
);
2555 if(i1
!= spnt
->dbx_type
)
2557 spnt
->advanced
= ALIAS
;
2562 printf ("gcc-as warning(debugger output):");
2563 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2564 return 1; /* do not know what this is */
2566 /* now define this module*/
2567 pnt
= str
+ 1; /* point to character past equal sign */
2571 spnt
->advanced
= BASIC
;
2572 if (type_check ("int"))
2574 spnt
->VMS_type
= DBG_S_C_SLINT
;
2575 spnt
->data_size
= 4;
2577 else if (type_check ("long int"))
2579 spnt
->VMS_type
= DBG_S_C_SLINT
;
2580 spnt
->data_size
= 4;
2582 else if (type_check ("unsigned int"))
2584 spnt
->VMS_type
= DBG_S_C_ULINT
;
2585 spnt
->data_size
= 4;
2587 else if (type_check ("long unsigned int"))
2589 spnt
->VMS_type
= DBG_S_C_ULINT
;
2590 spnt
->data_size
= 4;
2592 else if (type_check ("short int"))
2594 spnt
->VMS_type
= DBG_S_C_SSINT
;
2595 spnt
->data_size
= 2;
2597 else if (type_check ("short unsigned int"))
2599 spnt
->VMS_type
= DBG_S_C_USINT
;
2600 spnt
->data_size
= 2;
2602 else if (type_check ("char"))
2604 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2605 spnt
->data_size
= 1;
2607 else if (type_check ("signed char"))
2609 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2610 spnt
->data_size
= 1;
2612 else if (type_check ("unsigned char"))
2614 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2615 spnt
->data_size
= 1;
2617 else if (type_check ("float"))
2619 spnt
->VMS_type
= DBG_S_C_REAL4
;
2620 spnt
->data_size
= 4;
2622 else if (type_check ("double"))
2624 spnt
->VMS_type
= DBG_S_C_REAL8
;
2625 spnt
->data_size
= 8;
2627 pnt1
= (char *) strchr (str
, ';') + 1;
2632 spnt
->advanced
= STRUCT
;
2634 spnt
->advanced
= UNION
;
2635 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2636 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2637 if (!final_pass
&& forward_reference(pnt
))
2639 spnt
->struc_numb
= -1;
2642 spnt
->struc_numb
= ++structure_count
;
2644 pnt
= get_struct_name (str
);
2645 VMS_Def_Struct (spnt
->struc_numb
);
2647 while (fpnt
!= (struct forward_ref
*) NULL
)
2649 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2651 fpnt
->resolved
= 'Y';
2652 VMS_Set_Struct (fpnt
->struc_numb
);
2653 VMS_Store_Struct (spnt
->struc_numb
);
2657 VMS_Set_Struct (spnt
->struc_numb
);
2659 Local
[i
++] = 11 + strlen (pnt
);
2660 Local
[i
++] = DBG_S_C_STRUCT_START
;
2662 for (i1
= 0; i1
< 4; i1
++)
2664 Local
[i
++] = strlen (pnt
);
2666 while (*pnt2
!= '\0')
2667 Local
[i
++] = *pnt2
++;
2668 i2
= spnt
->data_size
* 8; /* number of bits */
2669 COPY_LONG(&Local
[i
], i2
);
2671 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2673 if (pnt
!= symbol_name
)
2675 pnt
+= strlen (pnt
);
2677 }; /* replace colon for later */
2678 while (*++pnt1
!= ';')
2680 pnt
= (char *) strchr (pnt1
, ':');
2683 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2684 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2685 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2686 if ((dtype
== 1) && (i3
!= 32))
2689 push (19 + strlen (pnt2
), 1);
2691 push (1 + strlen (pnt2
), 4);
2692 push (strlen (pnt2
), 1);
2693 while (*pnt2
!= '\0')
2695 push (i3
, 2); /* size of bitfield */
2698 push (i2
, 4); /* start position */
2699 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2704 Local
[i
++] = 7 + strlen (pnt2
);
2705 spnt1
= find_symbol (dtype
);
2706 /* check if this is a forward reference */
2707 if(final_pass
&& final_forward_reference(spnt1
))
2709 printf("gcc-as warning(debugger output):");
2710 printf("structure element %s has undefined type\n",pnt2
);
2714 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2715 Local
[i
++] = spnt1
->VMS_type
;
2717 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2718 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2719 COPY_LONG (&Local
[i
], i2
);
2721 Local
[i
++] = strlen (pnt2
);
2722 while (*pnt2
!= '\0')
2723 Local
[i
++] = *pnt2
++;
2724 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2726 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2727 generate_suffix (spnt1
, dtype
);
2728 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2729 generate_suffix (spnt1
, 0);
2733 Local
[i
++] = 0x01; /* length byte */
2734 Local
[i
++] = DBG_S_C_STRUCT_END
;
2735 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2739 spnt
->advanced
= ENUM
;
2740 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2741 spnt
->struc_numb
= ++structure_count
;
2742 spnt
->data_size
= 4;
2743 VMS_Def_Struct (spnt
->struc_numb
);
2745 while (fpnt
!= (struct forward_ref
*) NULL
)
2747 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2749 fpnt
->resolved
= 'Y';
2750 VMS_Set_Struct (fpnt
->struc_numb
);
2751 VMS_Store_Struct (spnt
->struc_numb
);
2755 VMS_Set_Struct (spnt
->struc_numb
);
2757 Local
[i
++] = 3 + strlen (symbol_name
);
2758 Local
[i
++] = DBG_S_C_ENUM_START
;
2760 Local
[i
++] = strlen (symbol_name
);
2762 while (*pnt2
!= '\0')
2763 Local
[i
++] = *pnt2
++;
2764 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2766 while (*++pnt
!= ';')
2768 pnt1
= (char *) strchr (pnt
, ':');
2770 pnt1
= cvt_integer (pnt1
, &i1
);
2771 Local
[i
++] = 7 + strlen (pnt
);
2772 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2774 COPY_LONG (&Local
[i
], i1
);
2776 Local
[i
++] = strlen (pnt
);
2778 while (*pnt
!= '\0')
2779 Local
[i
++] = *pnt
++;
2780 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2782 pnt
= pnt1
; /* Skip final semicolon */
2784 Local
[i
++] = 0x01; /* len byte */
2785 Local
[i
++] = DBG_S_C_ENUM_END
;
2786 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2791 spnt
->advanced
= ARRAY
;
2792 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2793 pnt
= (char *) strchr (pnt
, ';');
2794 if (pnt
== (char *) NULL
)
2796 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2797 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2798 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2799 pnt
=(char*)strchr(str
+1,'=');
2800 if((pnt
!= (char*) NULL
))
2801 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2804 spnt
->advanced
= FUNCTION
;
2805 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2806 /* this masquerades as a basic type*/
2807 spnt
->data_size
= 4;
2808 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2811 spnt
->advanced
= POINTER
;
2812 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2813 spnt
->data_size
= 4;
2814 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2815 pnt
= (char *) strchr (str
+ 1, '=');
2816 if ((pnt
!= (char *) NULL
))
2817 if (VMS_typedef_parse (pnt
) == 1)
2821 spnt
->advanced
= UNKNOWN
;
2823 printf ("gcc-as warning(debugger output):");
2824 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2825 return 1; /* unable to decipher */
2827 /* this removes the evidence of the definition so that the outer levels of
2828 parsing do not have to worry about it */
2830 while (*pnt1
!= '\0')
2838 * This is the root routine that parses the stabs entries for definitions.
2839 * it calls VMS_typedef_parse, which can in turn call itself.
2840 * We need to be careful, since sometimes there are forward references to
2841 * other symbol types, and these cannot be resolved until we have completed
2844 * Also check and see if we are using continuation stabs, if we are, then
2845 * paste together the entire contents of the stab before we pass it to
2846 * VMS_typedef_parse.
2855 char *parse_buffer
= 0;
2857 int incomplete
, i
, pass
, incom1
;
2858 struct VMS_DBG_Symbol
*spnt
;
2859 struct VMS_Symbol
*vsp
;
2860 struct forward_ref
*fpnt
;
2867 incom1
= incomplete
;
2869 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2872 * Deal with STAB symbols
2874 if (S_IS_DEBUG (sp
))
2877 * Dispatch on STAB type
2879 switch (S_GET_RAW_TYPE (sp
))
2887 case N_FUN
: /*sometimes these contain typedefs*/
2888 str
= S_GET_NAME (sp
);
2890 pnt
= str
+ strlen(str
) -1;
2891 if (*pnt
== '?') /* Continuation stab. */
2897 tlen
+= strlen(str
) - 1;
2898 spnext
= symbol_next (spnext
);
2899 str
= S_GET_NAME (spnext
);
2900 pnt
= str
+ strlen(str
) - 1;
2901 } while (*pnt
== '?');
2902 tlen
+= strlen(str
);
2903 parse_buffer
= (char *) malloc (tlen
+ 1);
2904 strcpy(parse_buffer
, S_GET_NAME (sp
));
2905 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2909 spnext
= symbol_next (spnext
);
2910 str
= S_GET_NAME (spnext
);
2911 strcat (pnt2
, S_GET_NAME (spnext
));
2912 pnt2
+= strlen(str
) - 1;
2913 *str
= '\0'; /* Erase this string */
2914 if (*pnt2
!= '?') break;
2920 pnt
= (char *) strchr (str
, ':');
2921 if (pnt
!= (char *) NULL
)
2925 pnt2
= (char *) strchr (pnt1
, '=');
2926 if (pnt2
!= (char *) NULL
)
2927 incomplete
+= VMS_typedef_parse (pnt2
);
2929 /* At this point the parse buffer should just contain name:nn.
2930 If it does not, then we are in real trouble. Anyway,
2931 this is always shorter than the original line. */
2932 strcpy(S_GET_NAME (sp
), parse_buffer
);
2933 free (parse_buffer
);
2936 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2943 /* Make one last pass, if needed, and define whatever we can that is left */
2944 if(final_pass
== 0 && incomplete
== incom1
)
2947 incom1
++; /* Force one last pass through */
2949 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2950 /* repeat until all refs resolved if possible */
2951 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2952 if (incomplete
!= 0)
2954 printf ("gcc-as warning(debugger output):");
2955 printf ("Unable to resolve %d circular references.\n", incomplete
);
2959 while (fpnt
!= (struct forward_ref
*) NULL
)
2961 if (fpnt
->resolved
!= 'Y')
2963 if (find_symbol (fpnt
->dbx_type
) !=
2964 (struct VMS_DBG_Symbol
*) NULL
)
2966 printf ("gcc-as warning(debugger output):");
2967 printf ("Forward reference error, dbx type %d\n",
2972 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2973 pnt2
= (char *) strchr (&fixit
[1], '=');
2974 VMS_typedef_parse (pnt2
);
2981 Define_Local_Symbols (s1
, s2
)
2985 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2987 if (symbolP1
== (symbolS
*) NULL
)
2989 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2991 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2992 if (*pnt
== 'F' || *pnt
== 'f') break;
2995 * Deal with STAB symbols
2997 if (S_IS_DEBUG (symbolP1
))
3000 * Dispatch on STAB type
3002 switch (S_GET_RAW_TYPE (symbolP1
))
3006 VMS_local_stab_Parse (symbolP1
);
3009 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
3017 /* This function crawls the symbol chain searching for local symbols that need
3018 * to be described to the debugger. When we enter a new scope with a "{", it
3019 * creates a new "block", which helps the debugger keep track of which scope
3020 * we are currently in.
3024 Define_Routine (symbolP
, Level
)
3034 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
3036 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3038 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3039 if (*pnt
== 'F' || *pnt
== 'f') break;
3042 * Deal with STAB symbols
3044 if (S_IS_DEBUG (symbolP1
))
3047 * Dispatch on STAB type
3049 switch (S_GET_RAW_TYPE (symbolP1
))
3054 sprintf (str
, "$%d", rcount
++);
3055 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3057 Offset
= S_GET_VALUE (symbolP1
);
3058 Define_Local_Symbols (sstart
, symbolP1
);
3060 Define_Routine (symbolP1
, Level
+ 1);
3062 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3071 /* we end up here if there were no brackets in this function. Define
3073 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3079 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3081 symbolS
*Curr_Routine
;
3084 Current_Routine
= Curr_Routine
;
3085 Text_Psect
= Txt_Psect
;
3086 Define_Routine (symbolP
, 0);
3093 #include <sys/types.h>
3096 /* Manufacure a VMS like time on a unix based system. */
3097 get_VMS_time_on_unix (Now
)
3103 pnt
= ctime (&timeb
);
3109 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3112 #endif /* not HO_VMS */
3114 * Write the MHD (Module Header) records
3117 Write_VMS_MHD_Records ()
3119 register char *cp
, *cp1
;
3126 char Module_Name
[256];
3130 * We are writing a module header record
3132 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3134 * ***************************
3135 * *MAIN MODULE HEADER RECORD*
3136 * ***************************
3138 * Store record type and header type
3140 PUT_CHAR (OBJ_S_C_HDR
);
3141 PUT_CHAR (MHD_S_C_MHD
);
3143 * Structure level is 0
3145 PUT_CHAR (OBJ_S_C_STRLVL
);
3147 * Maximum record size is size of the object record buffer
3149 PUT_SHORT (sizeof (Object_Record_Buffer
));
3151 * Get module name (the FILENAME part of the object file)
3157 if ((*cp
== ']') || (*cp
== '>') ||
3158 (*cp
== ':') || (*cp
== '/'))
3164 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3168 * Limit it to 31 characters and store in the object record
3170 while (--cp1
>= Module_Name
)
3173 if (strlen (Module_Name
) > 31)
3176 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3177 Module_Name
[31] = 0;
3179 PUT_COUNTED_STRING (Module_Name
);
3181 * Module Version is "V1.0"
3183 PUT_COUNTED_STRING ("V1.0");
3185 * Creation time is "now" (17 chars of time string)
3188 get_VMS_time_on_unix (&Now
[0]);
3190 Descriptor
.Size
= 17;
3191 Descriptor
.Ptr
= Now
;
3192 sys$
asctim (0, &Descriptor
, 0, 0);
3194 for (i
= 0; i
< 17; i
++)
3197 * Patch time is "never" (17 zeros)
3199 for (i
= 0; i
< 17; i
++)
3204 Flush_VMS_Object_Record_Buffer ();
3206 * *************************
3207 * *LANGUAGE PROCESSOR NAME*
3208 * *************************
3210 * Store record type and header type
3212 PUT_CHAR (OBJ_S_C_HDR
);
3213 PUT_CHAR (MHD_S_C_LNM
);
3215 * Store language processor name and version
3216 * (not a counted string!)
3218 cp
= compiler_version_string
;
3224 cp
= strchr (GAS_VERSION
, '.');
3234 Flush_VMS_Object_Record_Buffer ();
3239 * Write the EOM (End Of Module) record
3242 Write_VMS_EOM_Record (Psect
, Offset
)
3247 * We are writing an end-of-module record
3249 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3253 PUT_CHAR (OBJ_S_C_EOM
);
3255 * Store the error severity (0)
3259 * Store the entry point, if it exists
3264 * Store the entry point Psect
3268 * Store the entry point Psect offset
3275 Flush_VMS_Object_Record_Buffer ();
3279 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3285 register unsigned char *p
= ptr
;
3286 register unsigned char *end
= p
+ strlen (ptr
);
3287 register unsigned char c
;
3288 register int hash
= 0;
3293 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3299 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3302 VMS_Case_Hack_Symbol (In
, Out
)
3312 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3314 int Case_Hack_Bits
= 0;
3316 static char Hex_Table
[16] =
3317 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3320 * Kill any leading "_"
3322 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3325 new_name
= Out
; /* save this for later*/
3327 #if barfoo /* Dead code */
3328 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3332 /* We may need to truncate the symbol, save the hash for later*/
3333 if (strlen (In
) > 23)
3334 result
= hash_string (In
);
3336 * Is there a Psect Attribute to skip??
3338 if (HAS_PSECT_ATTRIBUTES (In
))
3343 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3346 if ((In
[0] == '$') && (In
[1] == '$'))
3356 /* if (strlen(In) > 31 && flagseen['+'])
3357 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3359 * Do the case conversion
3361 i
= 23; /* Maximum of 23 chars */
3362 while (*In
&& (--i
>= 0))
3364 Case_Hack_Bits
<<= 1;
3367 if ((destructor
== 1) && (i
== 21))
3369 switch (vms_name_mapping
)
3374 Case_Hack_Bits
|= 1;
3376 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3379 case 3: *Out
++ = *In
++;
3385 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3391 * If we saw a dollar sign, we don't do case hacking
3393 if (flagseen
['h'] || Saw_Dollar
)
3397 * If we have more than 23 characters and everything is lowercase
3398 * we can insert the full 31 characters
3403 * We have more than 23 characters
3404 * If we must add the case hack, then we have truncated the str
3408 if (Case_Hack_Bits
== 0)
3411 * And so far they are all lower case:
3412 * Check up to 8 more characters
3413 * and ensure that they are lowercase
3415 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3416 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3422 if ((i
== 8) || (In
[i
] == 0))
3425 * They are: Copy up to 31 characters
3426 * to the output string
3429 while ((--i
>= 0) && (*In
))
3430 switch (vms_name_mapping
){
3431 case 0: *Out
++ = islower(*In
) ?
3435 case 3: *Out
++ = *In
++;
3437 case 2: *Out
++ = isupper(*In
) ?
3446 * If there were any uppercase characters in the name we
3447 * take on the case hacking string
3450 /* Old behavior for regular GNU-C compiler */
3453 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3458 for (i
= 0; i
< 6; i
++)
3460 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3461 Case_Hack_Bits
>>= 4;
3467 Out
= pnt
; /*Cut back to 23 characters maximum */
3469 for (i
= 0; i
< 7; i
++)
3471 init
= result
& 0x01f;
3473 *Out
++ = '0' + init
;
3475 *Out
++ = 'A' + init
- 10;
3476 result
= result
>> 5;
3484 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3485 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3490 * Scan a symbol name for a psect attribute specification
3492 #define GLOBALSYMBOL_BIT 0x10000
3493 #define GLOBALVALUE_BIT 0x20000
3497 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3499 int *Attribute_Pointer
;
3510 {"PIC", GPS_S_M_PIC
},
3511 {"LIB", GPS_S_M_LIB
},
3512 {"OVR", GPS_S_M_OVR
},
3513 {"REL", GPS_S_M_REL
},
3514 {"GBL", GPS_S_M_GBL
},
3515 {"SHR", GPS_S_M_SHR
},
3516 {"EXE", GPS_S_M_EXE
},
3518 {"WRT", GPS_S_M_WRT
},
3519 {"VEC", GPS_S_M_VEC
},
3520 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3521 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3531 * Check for a PSECT attribute list
3533 if (!HAS_PSECT_ATTRIBUTES (Name
))
3534 return; /* If not, return */
3536 * Skip the attribute list indicator
3538 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3540 * Process the attributes ("_" separated, "$" terminated)
3542 while (*Name
!= '$')
3545 * Assume not negating
3551 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3554 * We are negating (and skip the NO)
3560 * Find the token delimiter
3563 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3566 * Look for the token in the attribute list
3568 for (i
= 0; Attributes
[i
].Name
; i
++)
3571 * If the strings match, set/clear the attr.
3573 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3579 *Attribute_Pointer
&=
3580 ~Attributes
[i
].Value
;
3582 *Attribute_Pointer
|=
3583 Attributes
[i
].Value
;
3591 * Now skip the attribute
3605 * Define a global symbol
3608 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3616 * We are writing a GSD record
3618 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3620 * If the buffer is empty we must insert the GSD record type
3622 if (Object_Record_Offset
== 0)
3623 PUT_CHAR (OBJ_S_C_GSD
);
3625 * We are writing a Global symbol definition subrecord
3627 if (Psect_Number
<= 255)
3629 PUT_CHAR (GSD_S_C_SYM
);
3633 PUT_CHAR (GSD_S_C_SYMW
);
3636 * Data type is undefined
3640 * Switch on Definition/Reference
3642 if ((Defined
& 1) != 0)
3646 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3647 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3649 if ((Defined
& 2) == 0)
3651 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3655 PUT_SHORT (GSY_S_M_DEF
);
3660 if (Psect_Number
<= 255)
3662 PUT_CHAR (Psect_Number
);
3666 PUT_SHORT (Psect_Number
);
3671 PUT_LONG (Psect_Offset
);
3677 * Flags = "RELOCATABLE" for regular symbol,
3678 * = "" for globalvalue (Defined & 2 == 1)
3680 if ((Defined
& 2) == 0)
3682 PUT_SHORT (GSY_S_M_REL
);
3690 * Finally, the global symbol name
3692 VMS_Case_Hack_Symbol (Name
, Local
);
3693 PUT_COUNTED_STRING (Local
);
3695 * Flush the buffer if it is more than 75% full
3697 if (Object_Record_Offset
>
3698 (sizeof (Object_Record_Buffer
) * 3 / 4))
3699 Flush_VMS_Object_Record_Buffer ();
3707 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3711 struct VMS_Symbol
*vsp
;
3714 int Psect_Attributes
;
3717 * Generate the appropriate PSECT flags given the PSECT type
3719 if (strcmp (Type
, "COMMON") == 0)
3722 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3724 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3725 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3727 else if (strcmp (Type
, "CONST") == 0)
3730 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3732 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3733 GPS_S_M_SHR
| GPS_S_M_RD
);
3735 else if (strcmp (Type
, "DATA") == 0)
3738 * The Data psects are PIC,REL,RD,WRT
3741 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3743 else if (strcmp (Type
, "TEXT") == 0)
3746 * The Text psects are PIC,REL,SHR,EXE,RD
3749 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3750 GPS_S_M_EXE
| GPS_S_M_RD
);
3755 * Error: Unknown psect type
3757 error ("Unknown VMS psect type");
3760 * Modify the psect attributes according to any attribute string
3762 if (HAS_PSECT_ATTRIBUTES (Name
))
3763 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3765 * Check for globalref/def/val.
3767 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3770 * globalvalue symbols were generated before. This code
3771 * prevents unsightly psect buildup, and makes sure that
3772 * fixup references are emitted correctly.
3774 vsp
->Psect_Index
= -1; /* to catch errors */
3775 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3776 return 1; /* decrement psect counter */
3779 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3781 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3783 case N_UNDF
| N_EXT
:
3784 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3785 vsp
->Psect_Offset
, 0);
3786 vsp
->Psect_Index
= -1;
3787 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3788 return 1; /* return and indicate no psect */
3789 case N_DATA
| N_EXT
:
3790 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3791 vsp
->Psect_Offset
, 1);
3792 /* In this case we still generate the psect */
3796 char Error_Line
[256];
3797 sprintf (Error_Line
,
3798 "Globalsymbol attribute for symbol %s was unexpected.\n",
3806 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3808 * We are writing a GSD record
3810 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3812 * If the buffer is empty we must insert the GSD record type
3814 if (Object_Record_Offset
== 0)
3815 PUT_CHAR (OBJ_S_C_GSD
);
3817 * We are writing a PSECT definition subrecord
3819 PUT_CHAR (GSD_S_C_PSC
);
3821 * Psects are always LONGWORD aligned
3825 * Specify the psect attributes
3827 PUT_SHORT (Psect_Attributes
);
3829 * Specify the allocation
3833 * Finally, the psect name
3835 VMS_Case_Hack_Symbol (Name
, Local
);
3836 PUT_COUNTED_STRING (Local
);
3838 * Flush the buffer if it is more than 75% full
3840 if (Object_Record_Offset
>
3841 (sizeof (Object_Record_Buffer
) * 3 / 4))
3842 Flush_VMS_Object_Record_Buffer ();
3848 * Given the pointer to a symbol we calculate how big the data at the
3849 * symbol is. We do this by looking for the next symbol (local or
3850 * global) which will indicate the start of another datum.
3853 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3854 register struct symbol
*sp
;
3857 register struct symbol
*sp1
, *Next_Symbol
;
3860 * Find the next symbol
3861 * it delimits this datum
3864 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3867 * The data type must match
3869 if (S_GET_TYPE (sp1
) != N_DATA
)
3872 * The symbol must be AFTER this symbol
3874 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3877 * We ignore THIS symbol
3882 * If there is already a candidate selected for the
3883 * next symbol, see if we are a better candidate
3888 * We are a better candidate if we are "closer"
3891 if (S_GET_VALUE (sp1
) >
3892 S_GET_VALUE (Next_Symbol
))
3895 * Win: Make this the candidate
3902 * This is the 1st candidate
3908 * Calculate its size
3910 return (Next_Symbol
?
3911 (S_GET_VALUE (Next_Symbol
) -
3913 (End_Of_Data
- S_GET_VALUE (sp
)));
3917 * Check symbol names for the Psect hack with a globalvalue, and then
3918 * generate globalvalues for those that have it.
3921 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3926 register symbolS
*sp
;
3927 char *stripped_name
, *Name
;
3929 int Psect_Attributes
;
3933 * Scan the symbol table for globalvalues, and emit def/ref when
3934 * required. These will be caught again later and converted to
3937 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3940 * See if this is something we want to look at.
3942 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3943 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3946 * See if this has globalvalue specification.
3948 Name
= S_GET_NAME (sp
);
3950 if (!HAS_PSECT_ATTRIBUTES (Name
))
3953 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3954 strcpy (stripped_name
, Name
);
3955 Psect_Attributes
= 0;
3956 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3958 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3960 switch (S_GET_RAW_TYPE (sp
))
3962 case N_UNDF
| N_EXT
:
3963 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3965 case N_DATA
| N_EXT
:
3966 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3968 error ("Invalid data type for globalvalue");
3969 globalvalue
= md_chars_to_number (Data_Segment
+
3970 S_GET_VALUE (sp
) - text_siz
, Size
);
3971 /* Three times for good luck. The linker seems to get confused
3972 if there are fewer than three */
3973 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3974 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3975 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3978 printf (" Invalid globalvalue of %s\n", stripped_name
);
3982 free (stripped_name
); /* clean up */
3989 * Define a procedure entry pt/mask
3992 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
4001 * We are writing a GSD record
4003 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
4005 * If the buffer is empty we must insert the GSD record type
4007 if (Object_Record_Offset
== 0)
4008 PUT_CHAR (OBJ_S_C_GSD
);
4010 * We are writing a Procedure Entry Pt/Mask subrecord
4012 if (Psect_Number
<= 255)
4014 PUT_CHAR (GSD_S_C_EPM
);
4018 PUT_CHAR (GSD_S_C_EPMW
);
4021 * Data type is undefined
4025 * Flags = "RELOCATABLE" and "DEFINED"
4027 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4031 if (Psect_Number
<= 255)
4033 PUT_CHAR (Psect_Number
);
4037 PUT_SHORT (Psect_Number
);
4042 PUT_LONG (Psect_Offset
);
4046 PUT_SHORT (Entry_Mask
);
4048 * Finally, the global symbol name
4050 VMS_Case_Hack_Symbol (Name
, Local
);
4051 PUT_COUNTED_STRING (Local
);
4053 * Flush the buffer if it is more than 75% full
4055 if (Object_Record_Offset
>
4056 (sizeof (Object_Record_Buffer
) * 3 / 4))
4057 Flush_VMS_Object_Record_Buffer ();
4062 * Set the current location counter to a particular Psect and Offset
4065 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4071 * We are writing a "Record_Type" record
4073 Set_VMS_Object_File_Record (Record_Type
);
4075 * If the buffer is empty we must insert the record type
4077 if (Object_Record_Offset
== 0)
4078 PUT_CHAR (Record_Type
);
4080 * Stack the Psect base + Longword Offset
4082 if (Psect_Index
< 255)
4084 PUT_CHAR (TIR_S_C_STA_PL
);
4085 PUT_CHAR (Psect_Index
);
4089 PUT_CHAR (TIR_S_C_STA_WPL
);
4090 PUT_SHORT (Psect_Index
);
4094 * Set relocation base
4096 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4098 * Flush the buffer if it is more than 75% full
4100 if (Object_Record_Offset
>
4101 (sizeof (Object_Record_Buffer
) * 3 / 4))
4102 Flush_VMS_Object_Record_Buffer ();
4107 * Store repeated immediate data in current Psect
4110 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4112 register char *Pointer
;
4118 * Ignore zero bytes/words/longwords
4120 if ((Size
== sizeof (char)) && (*Pointer
== 0))
4122 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
4124 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
4127 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4128 * then we do it manually
4132 while (--Repeat_Count
>= 0)
4133 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4137 * We are writing a "Record_Type" record
4139 Set_VMS_Object_File_Record (Record_Type
);
4141 * If the buffer is empty we must insert record type
4143 if (Object_Record_Offset
== 0)
4144 PUT_CHAR (Record_Type
);
4146 * Stack the repeat count
4148 PUT_CHAR (TIR_S_C_STA_LW
);
4149 PUT_LONG (Repeat_Count
);
4151 * And now the command and its data
4153 PUT_CHAR (TIR_S_C_STO_RIVB
);
4156 PUT_CHAR (*Pointer
++);
4158 * Flush the buffer if it is more than 75% full
4160 if (Object_Record_Offset
>
4161 (sizeof (Object_Record_Buffer
) * 3 / 4))
4162 Flush_VMS_Object_Record_Buffer ();
4167 * Store a Position Independent Reference
4170 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4171 Psect
, Psect_Offset
, Record_Type
)
4172 struct symbol
*Symbol
;
4179 register struct VMS_Symbol
*vsp
=
4180 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4184 * We are writing a "Record_Type" record
4186 Set_VMS_Object_File_Record (Record_Type
);
4188 * If the buffer is empty we must insert record type
4190 if (Object_Record_Offset
== 0)
4191 PUT_CHAR (Record_Type
);
4193 * Set to the appropriate offset in the Psect
4198 * For a Code reference we need to fix the operand
4199 * specifier as well (so back up 1 byte)
4201 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4206 * For a Data reference we just store HERE
4208 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4211 * Make sure we are still generating a "Record Type" record
4213 if (Object_Record_Offset
== 0)
4214 PUT_CHAR (Record_Type
);
4216 * Dispatch on symbol type (so we can stack its value)
4218 switch (S_GET_RAW_TYPE (Symbol
))
4223 #ifdef NOT_VAX_11_C_COMPATIBLE
4224 case N_UNDF
| N_EXT
:
4225 case N_DATA
| N_EXT
:
4226 #endif /* NOT_VAX_11_C_COMPATIBLE */
4228 case N_TEXT
| N_EXT
:
4230 * Get the symbol name (case hacked)
4232 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4234 * Stack the global symbol value
4236 PUT_CHAR (TIR_S_C_STA_GBL
);
4237 PUT_COUNTED_STRING (Local
);
4241 * Stack the longword offset
4243 PUT_CHAR (TIR_S_C_STA_LW
);
4246 * Add the two, leaving the result on the stack
4248 PUT_CHAR (TIR_S_C_OPR_ADD
);
4252 * Uninitialized local data
4256 * Stack the Psect (+offset)
4258 if (vsp
->Psect_Index
< 255)
4260 PUT_CHAR (TIR_S_C_STA_PL
);
4261 PUT_CHAR (vsp
->Psect_Index
);
4265 PUT_CHAR (TIR_S_C_STA_WPL
);
4266 PUT_SHORT (vsp
->Psect_Index
);
4268 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4275 * Stack the Psect (+offset)
4277 if (vsp
->Psect_Index
< 255)
4279 PUT_CHAR (TIR_S_C_STA_PL
);
4280 PUT_CHAR (vsp
->Psect_Index
);
4284 PUT_CHAR (TIR_S_C_STA_WPL
);
4285 PUT_SHORT (vsp
->Psect_Index
);
4287 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4290 * Initialized local or global data
4293 #ifndef NOT_VAX_11_C_COMPATIBLE
4294 case N_UNDF
| N_EXT
:
4295 case N_DATA
| N_EXT
:
4296 #endif /* NOT_VAX_11_C_COMPATIBLE */
4298 * Stack the Psect (+offset)
4300 if (vsp
->Psect_Index
< 255)
4302 PUT_CHAR (TIR_S_C_STA_PL
);
4303 PUT_CHAR (vsp
->Psect_Index
);
4307 PUT_CHAR (TIR_S_C_STA_WPL
);
4308 PUT_SHORT (vsp
->Psect_Index
);
4310 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4314 * Store either a code or data reference
4316 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4318 * Flush the buffer if it is more than 75% full
4320 if (Object_Record_Offset
>
4321 (sizeof (Object_Record_Buffer
) * 3 / 4))
4322 Flush_VMS_Object_Record_Buffer ();
4327 * Check in the text area for an indirect pc-relative reference
4328 * and fix it up with addressing mode 0xff [PC indirect]
4330 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4331 * PIC CODE GENERATING FIXUP ROUTINE.
4334 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4337 register fragS
*fragP
;
4338 struct frag
*text_frag_root
;
4341 * The addressing mode byte is 1 byte before the address
4345 * Is it in THIS frag??
4347 if ((Offset
< fragP
->fr_address
) ||
4348 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4351 * We need to search for the fragment containing this
4354 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4356 if ((Offset
>= fragP
->fr_address
) &&
4357 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4361 * If we couldn't find the frag, things are BAD!!
4364 error ("Couldn't find fixup fragment when checking for indirect reference");
4367 * Check for indirect PC relative addressing mode
4369 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4371 static char Address_Mode
= 0xff;
4374 * Yes: Store the indirect mode back into the image
4375 * to fix up the damage done by STO_PICR
4377 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4378 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4383 * If the procedure "main()" exists we have to add the instruction
4384 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4386 VMS_Check_For_Main ()
4388 register symbolS
*symbolP
;
4389 #ifdef HACK_DEC_C_STARTUP /* JF */
4390 register struct frchain
*frchainP
;
4391 register fragS
*fragP
;
4392 register fragS
**prev_fragPP
;
4393 register struct fix
*fixP
;
4394 register fragS
*New_Frag
;
4396 #endif /* HACK_DEC_C_STARTUP */
4398 symbolP
= (struct symbol
*) symbol_find ("_main");
4399 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4400 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4402 #ifdef HACK_DEC_C_STARTUP
4407 * Remember the entry point symbol
4409 Entry_Point_Symbol
= symbolP
;
4410 #ifdef HACK_DEC_C_STARTUP
4415 * Scan all the fragment chains for the one with "_main"
4416 * (Actually we know the fragment from the symbol, but we need
4417 * the previous fragment so we can change its pointer)
4419 frchainP
= frchain_root
;
4423 * Scan all the fragments in this chain, remembering
4424 * the "previous fragment"
4426 prev_fragPP
= &frchainP
->frch_root
;
4427 fragP
= frchainP
->frch_root
;
4428 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4431 * Is this the fragment?
4433 if (fragP
== symbolP
->sy_frag
)
4436 * Yes: Modify the fragment by replacing
4437 * it with a new fragment.
4439 New_Frag
= (fragS
*)
4440 xmalloc (sizeof (*New_Frag
) +
4445 * The fragments are the same except
4446 * that the "fixed" area is larger
4449 New_Frag
->fr_fix
+= 6;
4451 * Copy the literal data opening a hole
4452 * 2 bytes after "_main" (i.e. just after
4453 * the entry mask). Into which we place
4454 * the JSB instruction.
4456 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4457 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4458 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4459 New_Frag
->fr_literal
[3] = 0xef;
4460 New_Frag
->fr_literal
[4] = 0;
4461 New_Frag
->fr_literal
[5] = 0;
4462 New_Frag
->fr_literal
[6] = 0;
4463 New_Frag
->fr_literal
[7] = 0;
4464 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4465 New_Frag
->fr_literal
[i
+ 6] =
4466 fragP
->fr_literal
[i
];
4468 * Now replace the old fragment with the
4469 * newly generated one.
4471 *prev_fragPP
= New_Frag
;
4473 * Remember the entry point symbol
4475 Entry_Point_Symbol
= symbolP
;
4477 * Scan the text area fixup structures
4478 * as offsets in the fragment may have
4481 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4484 * Look for references to this
4487 if (fixP
->fx_frag
== fragP
)
4490 * Change the fragment
4493 fixP
->fx_frag
= New_Frag
;
4495 * If the offset is after
4496 * the entry mask we need
4497 * to account for the JSB
4498 * instruction we just
4501 if (fixP
->fx_where
>= 2)
4502 fixP
->fx_where
+= 6;
4506 * Scan the symbols as offsets in the
4507 * fragment may have changed
4509 for (symbolP
= symbol_rootP
;
4511 symbolP
= symbol_next (symbolP
))
4514 * Look for references to this
4517 if (symbolP
->sy_frag
== fragP
)
4520 * Change the fragment
4523 symbolP
->sy_frag
= New_Frag
;
4525 * If the offset is after
4526 * the entry mask we need
4527 * to account for the JSB
4528 * instruction we just
4531 if (S_GET_VALUE (symbolP
) >= 2)
4532 S_SET_VALUE (symbolP
,
4533 S_GET_VALUE (symbolP
) + 6);
4537 * Make a symbol reference to
4538 * "_c$main_args" so we can get
4539 * its address inserted into the
4542 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4543 S_GET_NAME (symbolP
) = "_c$main_args";
4544 S_SET_TYPE (symbolP
, N_UNDF
);
4545 S_GET_OTHER (symbolP
) = 0;
4546 S_GET_DESC (symbolP
) = 0;
4547 S_SET_VALUE (symbolP
, 0);
4548 symbolP
->sy_name_offset
= 0;
4549 symbolP
->sy_number
= 0;
4550 symbolP
->sy_frag
= New_Frag
;
4551 symbolP
->sy_forward
= 0;
4552 /* this actually inserts at the beginning of the list */
4553 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4555 symbol_rootP
= symbolP
;
4557 * Generate a text fixup structure
4558 * to get "_c$main_args" stored into the
4561 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4562 fixP
->fx_frag
= New_Frag
;
4564 fixP
->fx_addsy
= symbolP
;
4566 fixP
->fx_offset
= 0;
4567 fixP
->fx_size
= sizeof (long);
4569 fixP
->fx_next
= text_fix_root
;
4570 text_fix_root
= fixP
;
4572 * Now make sure we exit from the loop
4578 * Try the next fragment
4580 prev_fragPP
= &fragP
->fr_next
;
4581 fragP
= fragP
->fr_next
;
4584 * Try the next fragment chain
4587 frchainP
= frchainP
->frch_next
;
4590 #endif /* HACK_DEC_C_STARTUP */
4595 * Write a VAX/VMS object file (everything else has been done!)
4597 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4602 struct frag
*text_frag_root
;
4603 struct frag
*data_frag_root
;
4605 register fragS
*fragP
;
4606 register symbolS
*symbolP
;
4607 register symbolS
*sp
;
4608 register struct fix
*fixP
;
4609 register struct VMS_Symbol
*vsp
;
4611 int Local_Initialized_Data_Size
= 0;
4613 int Psect_Number
= 0; /* Psect Index Number */
4614 int Text_Psect
= -1; /* Text Psect Index */
4615 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4616 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4619 * Create the VMS object file
4621 Create_VMS_Object_File ();
4623 * Write the module header records
4625 Write_VMS_MHD_Records ();
4628 * Store the Data segment:
4630 * Since this is REALLY hard to do any other way,
4631 * we actually manufacture the data segment and
4632 * the store the appropriate values out of it.
4633 * We need to generate this early, so that globalvalues
4634 * can be properly emitted.
4639 * Allocate the data segment
4641 Data_Segment
= (char *) xmalloc (data_siz
);
4643 * Run through the data fragments, filling in the segment
4645 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4647 register long int count
;
4648 register char *fill_literal
;
4649 register long int fill_size
;
4652 i
= fragP
->fr_address
- text_siz
;
4654 memcpy (Data_Segment
+ i
,
4659 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4660 fill_size
= fragP
->fr_var
;
4661 for (count
= fragP
->fr_offset
; count
; count
--)
4664 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4672 * Generate the VMS object file records
4673 * 1st GSD then TIR records
4676 /******* Global Symbol Dictionary *******/
4678 * Emit globalvalues now. We must do this before the text psect
4679 * is defined, or we will get linker warnings about multiply defined
4680 * symbols. All of the globalvalues "reference" psect 0, although
4681 * it really does not have anything to do with it.
4683 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4685 * Define the Text Psect
4687 Text_Psect
= Psect_Number
++;
4688 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4690 * Define the BSS Psect
4694 Bss_Psect
= Psect_Number
++;
4695 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4697 #ifndef gxx_bug_fixed
4699 * The g++ compiler does not write out external references to vtables
4700 * correctly. Check for this and holler if we see it happening.
4701 * If that compiler bug is ever fixed we can remove this.
4703 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4706 * Dispatch on symbol type
4708 switch (S_GET_RAW_TYPE (sp
)) {
4714 * Make a GSD global symbol reference
4717 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4719 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4720 as_warn("g++ wrote an extern reference to %s as a routine.",
4722 as_warn("I will fix it, but I hope that it was not really a routine");
4729 #endif /* gxx_bug_fixed */
4731 * Now scan the symbols and emit the appropriate GSD records
4733 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4736 * Dispatch on symbol type
4738 switch (S_GET_RAW_TYPE (sp
))
4741 * Global uninitialized data
4743 case N_UNDF
| N_EXT
:
4745 * Make a VMS data symbol entry
4747 vsp
= (struct VMS_Symbol
*)
4748 xmalloc (sizeof (*vsp
));
4750 vsp
->Size
= S_GET_VALUE (sp
);
4751 vsp
->Psect_Index
= Psect_Number
++;
4752 vsp
->Psect_Offset
= 0;
4753 vsp
->Next
= VMS_Symbols
;
4755 sp
->sy_number
= (int) vsp
;
4757 * Make the psect for this data
4759 if (S_GET_OTHER (sp
))
4760 Globalref
= VMS_Psect_Spec (
4766 Globalref
= VMS_Psect_Spec (
4774 /* See if this is an external vtable. We want to help the linker find
4775 these things in libraries, so we make a symbol reference. This
4776 is not compatible with VAX-C usage for variables, but since vtables are
4777 only used internally by g++, we can get away with this hack. */
4779 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4780 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4785 #ifdef NOT_VAX_11_C_COMPATIBLE
4787 * Place a global symbol at the
4788 * beginning of the Psect
4790 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4794 #endif /* NOT_VAX_11_C_COMPATIBLE */
4797 * Local uninitialized data
4801 * Make a VMS data symbol entry
4803 vsp
= (struct VMS_Symbol
*)
4804 xmalloc (sizeof (*vsp
));
4807 vsp
->Psect_Index
= Bss_Psect
;
4810 bss_address_frag
.fr_address
;
4811 vsp
->Next
= VMS_Symbols
;
4813 sp
->sy_number
= (int) vsp
;
4816 * Global initialized data
4818 case N_DATA
| N_EXT
:
4820 * Make a VMS data symbol entry
4822 vsp
= (struct VMS_Symbol
*)
4823 xmalloc (sizeof (*vsp
));
4825 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4826 text_siz
+ data_siz
);
4827 vsp
->Psect_Index
= Psect_Number
++;
4828 vsp
->Psect_Offset
= 0;
4829 vsp
->Next
= VMS_Symbols
;
4831 sp
->sy_number
= (int) vsp
;
4835 if (S_GET_OTHER (sp
))
4836 Globalref
= VMS_Psect_Spec (
4842 Globalref
= VMS_Psect_Spec (
4850 /* See if this is an external vtable. We want to help the linker find
4851 these things in libraries, so we make a symbol definition. This
4852 is not compatible with VAX-C usage for variables, but since vtables are
4853 only used internally by g++, we can get away with this hack. */
4855 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4856 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4861 #ifdef NOT_VAX_11_C_COMPATIBLE
4863 * Place a global symbol at the
4864 * beginning of the Psect
4866 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4870 #endif /* NOT_VAX_11_C_COMPATIBLE */
4873 * Local initialized data
4877 * Make a VMS data symbol entry
4879 vsp
= (struct VMS_Symbol
*)
4880 xmalloc (sizeof (*vsp
));
4883 VMS_Initialized_Data_Size (sp
,
4884 text_siz
+ data_siz
);
4885 vsp
->Psect_Index
= Data_Psect
;
4887 Local_Initialized_Data_Size
;
4888 Local_Initialized_Data_Size
+= vsp
->Size
;
4889 vsp
->Next
= VMS_Symbols
;
4891 sp
->sy_number
= (int) vsp
;
4894 * Global Text definition
4896 case N_TEXT
| N_EXT
:
4898 unsigned short Entry_Mask
;
4901 * Get the entry mask
4903 fragP
= sp
->sy_frag
;
4904 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4905 ((fragP
->fr_literal
[1] & 0xff)
4908 * Define the Procedure entry pt.
4910 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4917 * Local Text definition
4921 * Make a VMS data symbol entry
4923 if (Text_Psect
!= -1)
4925 vsp
= (struct VMS_Symbol
*)
4926 xmalloc (sizeof (*vsp
));
4929 vsp
->Psect_Index
= Text_Psect
;
4930 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4931 vsp
->Next
= VMS_Symbols
;
4933 sp
->sy_number
= (int) vsp
;
4941 * Make a GSD global symbol reference
4944 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4954 * Ignore STAB symbols
4955 * Including .stabs emitted by g++
4957 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4962 if (S_GET_TYPE (sp
) != 22)
4963 printf (" ERROR, unknown type (%d)\n",
4969 * Define the Data Psect
4971 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4976 Data_Psect
= Psect_Number
++;
4977 VMS_Psect_Spec ("$data",
4978 Local_Initialized_Data_Size
,
4981 * Scan the VMS symbols and fill in the data psect
4983 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4986 * Only look for undefined psects
4988 if (vsp
->Psect_Index
< 0)
4991 * And only initialized data
4993 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4994 vsp
->Psect_Index
= Data_Psect
;
4999 /******* Text Information and Relocation Records *******/
5001 * Write the text segment data
5006 * Scan the text fragments
5008 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
5011 * Stop if we get to the data fragments
5013 if (fragP
== data_frag_root
)
5016 * Ignore fragments with no data
5018 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5021 * Go the the appropriate offset in the
5024 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5026 * Store the "fixed" part
5029 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5033 * Store the "variable" part
5035 if (fragP
->fr_var
&& fragP
->fr_offset
)
5036 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5043 * Now we go through the text segment fixups and
5044 * generate TIR records to fix up addresses within
5047 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5050 * We DO handle the case of "Symbol - Symbol" as
5051 * long as it is in the same segment.
5053 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5058 * They need to be in the same segment
5060 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5061 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5062 error ("Fixup data addsy and subsy didn't have the same type");
5064 * And they need to be in one that we
5065 * can check the psect on
5067 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5068 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5069 error ("Fixup data addsy and subsy didn't have an appropriate type");
5071 * This had better not be PC relative!
5074 error ("Fixup data was erroneously \"pcrel\"");
5076 * Subtract their values to get the
5079 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5080 S_GET_VALUE (fixP
->fx_subsy
);
5082 * Now generate the fixup object records
5083 * Set the psect and store the data
5085 VMS_Set_Psect (Text_Psect
,
5087 fixP
->fx_frag
->fr_address
,
5089 VMS_Store_Immediate_Data (&i
,
5098 * Size will HAVE to be "long"
5100 if (fixP
->fx_size
!= sizeof (long))
5101 error ("Fixup datum was not a longword");
5103 * Symbol must be "added" (if it is ever
5105 * fix this assumption)
5107 if (fixP
->fx_addsy
== 0)
5108 error ("Fixup datum was not \"fixP->fx_addsy\"");
5110 * Store the symbol value in a PIC fashion
5112 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5117 fixP
->fx_frag
->fr_address
,
5120 * Check for indirect address reference,
5121 * which has to be fixed up (as the linker
5122 * will screw it up with TIR_S_C_STO_PICR).
5125 VMS_Fix_Indirect_Reference (Text_Psect
,
5127 fixP
->fx_frag
->fr_address
,
5133 * Store the Data segment:
5135 * Since this is REALLY hard to do any other way,
5136 * we actually manufacture the data segment and
5137 * the store the appropriate values out of it.
5138 * The segment was manufactured before, now we just
5139 * dump it into the appropriate psects.
5145 * Now we can run through all the data symbols
5146 * and store the data
5148 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5151 * Ignore anything other than data symbols
5153 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5156 * Set the Psect + Offset
5158 VMS_Set_Psect (vsp
->Psect_Index
,
5164 VMS_Store_Immediate_Data (Data_Segment
+
5165 S_GET_VALUE (vsp
->Symbol
) -
5171 * Now we go through the data segment fixups and
5172 * generate TIR records to fix up addresses within
5175 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5178 * Find the symbol for the containing datum
5180 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5183 * Only bother with Data symbols
5186 if (S_GET_TYPE (sp
) != N_DATA
)
5189 * Ignore symbol if After fixup
5191 if (S_GET_VALUE (sp
) >
5193 fixP
->fx_frag
->fr_address
))
5196 * See if the datum is here
5198 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5200 fixP
->fx_frag
->fr_address
))
5203 * We DO handle the case of "Symbol - Symbol" as
5204 * long as it is in the same segment.
5206 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5211 * They need to be in the same segment
5213 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5214 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5215 error ("Fixup data addsy and subsy didn't have the same type");
5217 * And they need to be in one that we
5218 * can check the psect on
5220 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5221 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5222 error ("Fixup data addsy and subsy didn't have an appropriate type");
5224 * This had better not be PC relative!
5227 error ("Fixup data was erroneously \"pcrel\"");
5229 * Subtract their values to get the
5232 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5233 S_GET_VALUE (fixP
->fx_subsy
);
5235 * Now generate the fixup object records
5236 * Set the psect and store the data
5238 VMS_Set_Psect (vsp
->Psect_Index
,
5239 fixP
->fx_frag
->fr_address
+
5241 S_GET_VALUE (vsp
->Symbol
) +
5244 VMS_Store_Immediate_Data (&i
,
5253 * Size will HAVE to be "long"
5255 if (fixP
->fx_size
!= sizeof (long))
5256 error ("Fixup datum was not a longword");
5258 * Symbol must be "added" (if it is ever
5260 * fix this assumption)
5262 if (fixP
->fx_addsy
== 0)
5263 error ("Fixup datum was not \"fixP->fx_addsy\"");
5265 * Store the symbol value in a PIC fashion
5267 VMS_Store_PIC_Symbol_Reference (
5272 fixP
->fx_frag
->fr_address
+
5274 S_GET_VALUE (vsp
->Symbol
) +
5287 * Write the Traceback Begin Module record
5289 VMS_TBT_Module_Begin ();
5291 * Scan the symbols and write out the routines
5292 * (this makes the assumption that symbols are in
5293 * order of ascending text segment offset)
5296 struct symbol
*Current_Routine
= 0;
5297 int Current_Line_Number
= 0;
5298 int Current_Offset
= -1;
5299 struct input_file
*Current_File
;
5301 /* Output debugging info for global variables and static variables that are not
5302 * specific to one routine. We also need to examine all stabs directives, to
5303 * find the definitions to all of the advanced data types, and this is done by
5304 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5305 * the object file, since there can be forward references in the stabs
5306 * directives. When through with parsing, the text of the stabs directive
5307 * is altered, with the definitions removed, so that later passes will see
5308 * directives as they would be written if the type were already defined.
5310 * We also look for files and include files, and make a list of them. We
5311 * examine the source file numbers to establish the actual lines that code was
5312 * generated from, and then generate offsets.
5315 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5318 * Deal with STAB symbols
5320 if (S_IS_DEBUG (symbolP
))
5323 * Dispatch on STAB type
5325 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5328 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5329 Current_File
->max_line
= S_GET_DESC (symbolP
);
5330 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5331 Current_File
->min_line
= S_GET_DESC (symbolP
);
5334 Current_File
= find_file (symbolP
);
5335 Current_File
->flag
= 1;
5336 Current_File
->min_line
= 1;
5339 Current_File
= find_file (symbolP
);
5342 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5345 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5347 case N_FUN
: /* For static constant symbols */
5349 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5355 /* now we take a quick sweep through the files and assign offsets
5356 to each one. This will essentially be the starting line number to the
5357 debugger for each file. Output the info for the debugger to specify the
5358 files, and then tell it how many lines to use */
5360 int File_Number
= 0;
5361 int Debugger_Offset
= 0;
5363 Current_File
= file_root
;
5364 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5366 if (Current_File
== (struct input_file
*) NULL
)
5368 if (Current_File
->max_line
== 0)
5370 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5373 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5376 /* show a few extra lines at the start of the region selected */
5377 if (Current_File
->min_line
> 2)
5378 Current_File
->min_line
-= 2;
5379 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5380 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5381 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5382 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5385 Current_File
->file_number
= ++File_Number
;
5386 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5387 Current_File
->file_number
);
5388 if (!file_available
)
5390 Current_File
->file_number
= 0;
5395 VMS_TBT_Source_Lines (Current_File
->file_number
,
5396 Current_File
->min_line
,
5397 Current_File
->max_line
- Current_File
->min_line
+ 1);
5400 Current_File
= (struct input_file
*) NULL
;
5402 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5405 * Deal with text symbols
5407 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5410 * Ignore symbols starting with "L",
5411 * as they are local symbols
5413 if (*S_GET_NAME (symbolP
) == 'L')
5416 * If there is a routine start defined,
5419 if (Current_Routine
)
5424 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5427 * Store the routine begin traceback info
5429 if (Text_Psect
!= -1)
5431 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5432 Current_Routine
= symbolP
;
5434 /* Output local symbols, i.e. all symbols that are associated with a specific
5435 * routine. We output them now so the debugger recognizes them as local to
5442 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5444 if (!S_IS_DEBUG (symbolP1
))
5446 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5448 pnt
= S_GET_NAME (symbolP
);
5449 pnt1
= S_GET_NAME (symbolP1
);
5452 while (*pnt
++ == *pnt1
++)
5455 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5456 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5459 if (symbolP1
!= (symbolS
*) NULL
)
5460 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5461 } /* local symbol block */
5468 * Deal with STAB symbols
5470 if (S_IS_DEBUG (symbolP
))
5473 * Dispatch on STAB type
5475 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5481 /* Offset the line into the correct portion
5483 if (Current_File
->file_number
== 0)
5485 /* Sometimes the same offset gets several source
5486 * lines assigned to it.
5487 * We should be selective about which lines
5488 * we allow, we should prefer lines that are
5489 * in the main source file when debugging
5490 * inline functions. */
5491 if ((Current_File
->file_number
!= 1) &&
5492 S_GET_VALUE (symbolP
) ==
5495 /* calculate actual debugger source line */
5496 S_GET_DESC (symbolP
)
5497 += Current_File
->offset
;
5499 * If this is the 1st N_SLINE, setup
5500 * PC/Line correlation. Otherwise
5501 * do the delta PC/Line. If the offset
5502 * for the line number is not +ve we need
5503 * to do another PC/Line correlation
5506 if (Current_Offset
== -1)
5508 VMS_TBT_Line_PC_Correlation (
5509 S_GET_DESC (symbolP
),
5510 S_GET_VALUE (symbolP
),
5516 if ((S_GET_DESC (symbolP
) -
5517 Current_Line_Number
) <= 0)
5520 * Line delta is not +ve, we
5521 * need to close the line and
5522 * start a new PC/Line
5525 VMS_TBT_Line_PC_Correlation (0,
5526 S_GET_VALUE (symbolP
) -
5530 VMS_TBT_Line_PC_Correlation (
5531 S_GET_DESC (symbolP
),
5532 S_GET_VALUE (symbolP
),
5539 * Line delta is +ve, all is well
5541 VMS_TBT_Line_PC_Correlation (
5542 S_GET_DESC (symbolP
) -
5543 Current_Line_Number
,
5544 S_GET_VALUE (symbolP
) -
5551 * Update the current line/PC
5553 Current_Line_Number
= S_GET_DESC (symbolP
);
5554 Current_Offset
= S_GET_VALUE (symbolP
);
5564 * Remember that we had a source file
5565 * and emit the source file debugger
5569 find_file (symbolP
);
5571 /* We need to make sure that we are really in the actual source file when
5572 * we compute the maximum line number. Otherwise the debugger gets really
5576 find_file (symbolP
);
5582 * If there is a routine start defined,
5583 * terminate it (and the line numbers)
5585 if (Current_Routine
)
5588 * Terminate the line numbers
5590 VMS_TBT_Line_PC_Correlation (0,
5591 text_siz
- S_GET_VALUE (Current_Routine
),
5595 * Terminate the routine
5597 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5601 * Write the Traceback End Module TBT record
5603 VMS_TBT_Module_End ();
5606 * Write the End Of Module record
5608 if (Entry_Point_Symbol
== 0)
5609 Write_VMS_EOM_Record (-1, 0);
5611 Write_VMS_EOM_Record (Text_Psect
,
5612 S_GET_VALUE (Entry_Point_Symbol
));
5615 * All done, close the object file
5617 Close_VMS_Object_File ();
5620 /* end of obj-vms.c */