1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992, 1994 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 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 extern int flag_hash_long_names
; /* -+ */
43 extern int flag_one
; /* -1 */
44 extern int flag_show_after_trunc
; /* -H */
45 extern int flag_no_hash_mixed_case
; /* -h NUM */
47 /* Flag that determines how we map names. This takes several values, and
48 * is set with the -h switch. A value of zero implies names should be
49 * upper case, and the presence of the -h switch inhibits the case hack.
50 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
51 * A value of 2 (set with -h2) implies names should be
52 * all lower case, with no case hack. A value of 3 (set with -h3) implies
53 * that case should be preserved. */
55 /* If the -+ switch is given, then the hash is appended to any name that is
56 * longer than 31 characters, irregardless of the setting of the -h switch.
59 char vms_name_mapping
= 0;
62 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
65 * We augment the "gas" symbol structure with this
69 struct VMS_Symbol
*Next
;
70 struct symbol
*Symbol
;
75 struct VMS_Symbol
*VMS_Symbols
= 0;
77 /* We need this to keep track of the various input files, so that we can
78 * give the debugger the correct source line.
83 struct input_file
*next
;
84 struct input_file
*same_file_fpnt
;
94 static struct input_file
*file_root
= (struct input_file
*) NULL
;
97 static struct input_file
*find_file
PARAMS ((symbolS
*));
100 * This enum is used to keep track of the various types of variables that
106 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
110 * This structure contains the information from the stabs directives, and the
111 * information is filled in by VMS_typedef_parse. Everything that is needed
112 * to generate the debugging record for a given symbol is present here.
113 * This could be done more efficiently, using nested struct/unions, but for now
114 * I am happy that it works.
116 struct VMS_DBG_Symbol
118 struct VMS_DBG_Symbol
*next
;
119 /* description of what this is */
120 enum advanced_type advanced
;
121 /* this record is for this type */
123 /* For advanced types this is the type referred to. I.e., the type
124 a pointer points to, or the type of object that makes up an
127 /* Use this type when generating a variable def */
129 /* used for arrays - this will be present for all */
131 /* entries, but will be meaningless for non-arrays */
133 /* Size in bytes of the data type. For an array, this is the size
134 of one element in the array */
136 /* Number of the structure/union/enum - used for ref */
140 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
;
143 * We need this structure to keep track of forward references to
144 * struct/union/enum that have not been defined yet. When they are ultimately
145 * defined, then we can go back and generate the TIR commands to make a back
151 struct forward_ref
*next
;
157 struct forward_ref
*f_ref_root
=
158 {(struct forward_ref
*) NULL
};
161 * This routine is used to compare the names of certain types to various
162 * fixed types that are known by the debugger.
164 #define type_check(x) !strcmp( symbol_name , x )
167 * This variable is used to keep track of the name of the symbol we are
168 * working on while we are parsing the stabs directives.
170 static char *symbol_name
;
172 /* We use this counter to assign numbers to all of the structures, unions
173 * and enums that we define. When we actually declare a variable to the
174 * debugger, we can simply do it by number, rather than describing the
175 * whole thing each time.
178 static structure_count
= 0;
180 /* This variable is used to indicate that we are making the last attempt to
181 parse the stabs, and that we should define as much as we can, and ignore
184 static int final_pass
;
186 /* This variable is used to keep track of the current structure number
187 * for a given variable. If this is < 0, that means that the structure
188 * has not yet been defined to the debugger. This is still cool, since
189 * the VMS object language has ways of fixing things up after the fact,
190 * so we just make a note of this, and generate fixups at the end.
192 static int struct_number
;
194 /* This is used to distinguish between D_float and G_float for telling
195 the debugger about doubles. gcc outputs the same .stabs regardless
196 of whether -mg is used to select alternate doubles. */
198 static int vax_g_doubles
= 0;
202 * Variable descriptors are used tell the debugger the data types of certain
203 * more complicated variables (basically anything involving a structure,
204 * union, enum, array or pointer). Some non-pointer variables of the
205 * basic types that the debugger knows about do not require a variable
208 * Since it is impossible to have a variable descriptor longer than 128
209 * bytes by virtue of the way that the VMS object language is set up,
210 * it makes not sense to make the arrays any longer than this, or worrying
211 * about dynamic sizing of the array.
213 * These are the arrays and counters that we use to build a variable
217 #define MAX_DEBUG_RECORD 128
218 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
219 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
220 static int Lpnt
; /* index into Local */
221 static int Apoint
; /* index into Asuffix */
222 static char overflow
; /* flag to indicate we have written too much*/
223 static int total_len
; /* used to calculate the total length of variable
224 descriptor plus array descriptor - used for len byte*/
226 /* Flag if we have told user about finding global constants in the text
228 static gave_compiler_message
= 0;
230 /* A pointer to the current routine that we are working on. */
232 static symbolS
*Current_Routine
;
234 /* The psect number for $code a.k.a. the text section. */
236 static int Text_Psect
;
240 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
242 static int VMS_Object_File_FD
; /* File Descriptor for object file */
243 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
244 static int Object_Record_Offset
;/* Offset to end of data */
245 static int Current_Object_Record_Type
; /* Type of record in above */
248 * Macros for moving data around. Must work on big-endian systems.
250 #ifdef VMS /* These are more efficient for VMS->VMS systems */
251 #define COPY_LONG(dest,val) {*(long *) dest = val; }
252 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
254 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
255 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
258 * Macros for placing data into the object record buffer
261 #define PUT_LONG(val) \
262 { md_number_to_chars(Object_Record_Buffer + \
263 Object_Record_Offset, val, 4); \
264 Object_Record_Offset += 4; }
266 #define PUT_SHORT(val) \
267 { md_number_to_chars(Object_Record_Buffer + \
268 Object_Record_Offset, val, 2); \
269 Object_Record_Offset += 2; }
271 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
273 #define PUT_COUNTED_STRING(cp) {\
274 register char *p = cp; \
275 PUT_CHAR(strlen(p)); \
276 while (*p) PUT_CHAR(*p++);}
279 * Macro for determining if a Name has psect attributes attached
282 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
283 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
285 #define HAS_PSECT_ATTRIBUTES(Name) \
286 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
287 PSECT_ATTRIBUTES_STRING, \
288 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
291 /* in: segT out: N_TYPE bits */
292 const short seg_N_TYPE
[] =
298 N_UNDF
, /* unknown */
300 N_UNDF
, /* expression */
304 N_REGISTER
, /* register */
307 const segT N_TYPE_seg
[N_TYPE
+ 2] =
308 { /* N_TYPE == 0x1E = 32-2 */
309 SEG_UNKNOWN
, /* N_UNDF == 0 */
311 SEG_ABSOLUTE
, /* N_ABS == 2 */
313 SEG_TEXT
, /* N_TEXT == 4 */
315 SEG_DATA
, /* N_DATA == 6 */
317 SEG_BSS
, /* N_BSS == 8 */
319 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
320 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
321 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
322 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
327 /* The following code defines the special types of pseudo-ops that we
331 char const_flag
= IN_DEFAULT_SECTION
;
338 temp
= get_absolute_expression ();
339 subseg_set (SEG_DATA
, (subsegT
) temp
);
341 demand_empty_rest_of_line ();
344 const pseudo_typeS obj_pseudo_table
[] =
346 {"const", s_const
, 0},
348 }; /* obj_pseudo_table */
351 vms_resolve_symbol_redef (sym
)
355 * If the new symbol is .comm AND it has a size of zero,
356 * we ignore it (i.e. the old symbol overrides it)
358 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)) &&
359 ((obstack_next_free (&frags
) - frag_now
->fr_literal
) == 0))
361 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
366 * If the old symbol is .comm and it has a size of zero,
367 * we override it with the new symbol value.
369 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
370 && (S_GET_VALUE(sym
) == 0))
372 as_warn ("compiler redefined zero-size common symbol `%s'",
374 sym
->sy_frag
= frag_now
;
375 S_SET_OTHER(sym
, const_flag
);
376 S_SET_VALUE(sym
, obstack_next_free(& frags
) - frag_now
->fr_literal
);
377 /* Keep N_EXT bit. */
378 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
385 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
386 dummy label(s) gcc inserts at the beginning of each file it generates.
387 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
388 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
391 vms_check_for_special_label (symbolP
)
394 /* Special labels only occur prior to explicit section directives. */
395 if ((const_flag
& IN_DEFAULT_SECTION
) != 0)
397 char *sym_name
= S_GET_NAME(symbolP
);
399 if (*sym_name
== '_')
402 if (!strcmp (sym_name
, "__vax_g_doubles"))
404 #if 0 /* not necessary */
405 else if (!strcmp (sym_name
, "__vax_d_doubles"))
408 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
409 else if (!strcmp (sym_name
, "gcc_compiled."))
411 else if (!strcmp (sym_name
, "__gnu_language_cplusplus"))
412 flag_hash_long_names
= 1;
419 obj_read_begin_hook ()
424 obj_crawl_symbol_chain (headers
)
425 object_headers
*headers
;
429 int symbol_number
= 0;
431 { /* crawl symbol table */
432 register int symbol_number
= 0;
435 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
436 while ((symbolP
= *symbolPP
) != NULL
)
438 resolve_symbol_value (symbolP
);
440 /* OK, here is how we decide which symbols go out into the
441 brave new symtab. Symbols that do are:
443 * symbols with no name (stabd's?)
444 * symbols with debug info in their N_TYPE
446 Symbols that don't are:
447 * symbols that are registers
448 * symbols with \1 as their 3rd character (numeric labels)
449 * "local labels" as defined by S_LOCAL_NAME(name)
450 if the -L switch was passed to gas.
452 All other symbols are output. We complain if a deleted
453 symbol was marked external. */
456 if (!S_IS_REGISTER (symbolP
))
458 symbolP
->sy_name_offset
= 0;
459 symbolPP
= &(symbol_next (symbolP
));
463 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
465 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
468 } /* if this symbol should be in the output */
469 } /* for each symbol */
471 H_SET_STRING_SIZE (headers
, string_byte_count
);
472 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
473 } /* crawl symbol table */
475 } /* obj_crawl_symbol_chain() */
478 /****** VMS OBJECT FILE HACKING ROUTINES *******/
482 * Create the VMS object file
485 Create_VMS_Object_File ()
487 #if defined(eunice) || !defined(VMS)
488 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
490 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
491 "mbc=16", "deq=64", "fop=tef", "shr=nil");
496 if (VMS_Object_File_FD
< 0)
498 char Error_Line
[256];
500 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
505 * Initialize object file hacking variables
507 Object_Record_Offset
= 0;
508 Current_Object_Record_Type
= -1;
513 * Flush the object record buffer to the object file
516 Flush_VMS_Object_Record_Buffer ()
522 * If the buffer is empty, we are done
524 if (Object_Record_Offset
== 0)
527 * Write the data to the file
529 #ifndef VMS /* For cross-assembly purposes. */
530 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
531 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
533 i
= write (VMS_Object_File_FD
,
534 Object_Record_Buffer
,
535 Object_Record_Offset
);
536 if (i
!= Object_Record_Offset
)
537 error ("I/O error writing VMS object file");
538 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
540 /* pad it if needed */
542 if (Object_Record_Offset
& 1 != 0)
543 write (VMS_Object_File_FD
, &zero
, 1);
546 * The buffer is now empty
548 Object_Record_Offset
= 0;
553 * Declare a particular type of object file record
556 Set_VMS_Object_File_Record (Type
)
560 * If the type matches, we are done
562 if (Type
== Current_Object_Record_Type
)
565 * Otherwise: flush the buffer
567 Flush_VMS_Object_Record_Buffer ();
571 Current_Object_Record_Type
= Type
;
577 * Close the VMS Object file
580 Close_VMS_Object_File ()
582 short int m_one
= -1;
583 /* @@ This should not be here!! The same would presumably be needed
584 if we were writing vax-bsd a.out files on a vms system. Put it
586 #ifndef VMS /* For cross-assembly purposes. */
587 /* Write a 0xffff into the file, which means "End of File" */
588 write (VMS_Object_File_FD
, &m_one
, 2);
590 close (VMS_Object_File_FD
);
595 * Store immediate data in current Psect
598 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
606 * We are writing a "Record_Type" record
608 Set_VMS_Object_File_Record (Record_Type
);
610 * We can only store 128 bytes at a time
615 * Store a maximum of 128 bytes
617 i
= (Size
> 128) ? 128 : Size
;
620 * If we cannot accommodate this record, flush the
623 if ((Object_Record_Offset
+ i
+ 1) >=
624 sizeof (Object_Record_Buffer
))
625 Flush_VMS_Object_Record_Buffer ();
627 * If the buffer is empty we must insert record type
629 if (Object_Record_Offset
== 0)
630 PUT_CHAR (Record_Type
);
634 PUT_CHAR (-i
& 0xff);
639 PUT_CHAR (*Pointer
++);
641 * Flush the buffer if it is more than 75% full
643 if (Object_Record_Offset
>
644 (sizeof (Object_Record_Buffer
) * 3 / 4))
645 Flush_VMS_Object_Record_Buffer ();
650 * Make a data reference
653 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
660 * We are writing a "Record_Type" record
662 Set_VMS_Object_File_Record (Record_Type
);
664 * If the buffer is empty we must insert the record type
666 if (Object_Record_Offset
== 0)
667 PUT_CHAR (Record_Type
);
669 * Stack the Psect base + Longword Offset
673 if (Psect_Index
> 127)
675 PUT_CHAR (TIR_S_C_STA_WPL
);
676 PUT_SHORT (Psect_Index
);
681 PUT_CHAR (TIR_S_C_STA_PL
);
682 PUT_CHAR (Psect_Index
);
690 PUT_CHAR (TIR_S_C_STA_WPL
);
691 PUT_SHORT (Psect_Index
);
694 else if (Offset
> 127)
696 PUT_CHAR (TIR_S_C_STA_WPW
);
697 PUT_SHORT (Psect_Index
);
702 PUT_CHAR (TIR_S_C_STA_WPB
);
703 PUT_SHORT (Psect_Index
);
708 * Set relocation base
710 PUT_CHAR (TIR_S_C_STO_PIDR
);
712 * Flush the buffer if it is more than 75% full
714 if (Object_Record_Offset
>
715 (sizeof (Object_Record_Buffer
) * 3 / 4))
716 Flush_VMS_Object_Record_Buffer ();
720 * Make a debugger reference to a struct, union or enum.
723 VMS_Store_Struct (Struct_Index
)
727 * We are writing a "OBJ_S_C_DBG" record
729 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
731 * If the buffer is empty we must insert the record type
733 if (Object_Record_Offset
== 0)
734 PUT_CHAR (OBJ_S_C_DBG
);
735 PUT_CHAR (TIR_S_C_STA_UW
);
736 PUT_SHORT (Struct_Index
);
737 PUT_CHAR (TIR_S_C_CTL_STKDL
);
738 PUT_CHAR (TIR_S_C_STO_L
);
740 * Flush the buffer if it is more than 75% full
742 if (Object_Record_Offset
>
743 (sizeof (Object_Record_Buffer
) * 3 / 4))
744 Flush_VMS_Object_Record_Buffer ();
748 * Make a debugger reference to partially define a struct, union or enum.
751 VMS_Def_Struct (Struct_Index
)
755 * We are writing a "OBJ_S_C_DBG" record
757 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
759 * If the buffer is empty we must insert the record type
761 if (Object_Record_Offset
== 0)
762 PUT_CHAR (OBJ_S_C_DBG
);
763 PUT_CHAR (TIR_S_C_STA_UW
);
764 PUT_SHORT (Struct_Index
);
765 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
767 * Flush the buffer if it is more than 75% full
769 if (Object_Record_Offset
>
770 (sizeof (Object_Record_Buffer
) * 3 / 4))
771 Flush_VMS_Object_Record_Buffer ();
775 VMS_Set_Struct (Struct_Index
)
777 { /* see previous functions for comments */
778 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
779 if (Object_Record_Offset
== 0)
780 PUT_CHAR (OBJ_S_C_DBG
);
781 PUT_CHAR (TIR_S_C_STA_UW
);
782 PUT_SHORT (Struct_Index
);
783 PUT_CHAR (TIR_S_C_CTL_STLOC
);
784 if (Object_Record_Offset
>
785 (sizeof (Object_Record_Buffer
) * 3 / 4))
786 Flush_VMS_Object_Record_Buffer ();
790 * Write the Traceback Module Begin record
793 VMS_TBT_Module_Begin ()
795 register char *cp
, *cp1
;
797 char Module_Name
[256];
801 * Get module name (the FILENAME part of the object file)
807 if ((*cp
== ']') || (*cp
== '>') ||
808 (*cp
== ':') || (*cp
== '/'))
814 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
818 * Limit it to 31 characters
820 while (--cp1
>= Module_Name
)
823 if (strlen (Module_Name
) > 31)
825 if (flag_hash_long_names
)
826 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
830 * Arrange to store the data locally (leave room for size byte)
836 *cp
++ = DST_S_C_MODBEG
;
842 * Language type == "C"
844 COPY_LONG (cp
, DST_S_C_C
);
847 * Store the module name
849 *cp
++ = strlen (Module_Name
);
854 * Now we can store the record size
859 * Put it into the object record
861 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
866 * Write the Traceback Module End record
869 VMS_TBT_Module_End ()
877 Local
[1] = DST_S_C_MODEND
;
879 * Put it into the object record
881 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
886 * Write the Traceback Routine Begin record
889 VMS_TBT_Routine_Begin (symbolP
, Psect
)
890 struct symbol
*symbolP
;
893 register char *cp
, *cp1
;
900 * Strip the leading "_" from the name
902 Name
= S_GET_NAME (symbolP
);
906 * Get the text psect offset
908 Offset
= S_GET_VALUE (symbolP
);
910 * Calculate the record size
912 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
920 Local
[1] = DST_S_C_RTNBEG
;
926 * Store the data so far
928 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
930 * Make sure we are still generating a OBJ_S_C_TBT record
932 if (Object_Record_Offset
== 0)
933 PUT_CHAR (OBJ_S_C_TBT
);
935 * Now get the symbol address
937 PUT_CHAR (TIR_S_C_STA_WPL
);
941 * Store the data reference
943 PUT_CHAR (TIR_S_C_STO_PIDR
);
945 * Store the counted string as data
949 Size
= strlen (cp1
) + 1;
953 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
958 * Write the Traceback Routine End record
959 * We *must* search the symbol table to find the next routine, since
960 * the assember has a way of reassembling the symbol table OUT OF ORDER
961 * Thus the next routine in the symbol list is not necessarily the
962 * next one in memory. For debugging to work correctly we must know the
963 * size of the routine.
966 VMS_TBT_Routine_End (Max_Size
, sp
)
971 int Size
= 0x7fffffff;
973 valueT sym_value
, sp_value
= S_GET_VALUE (sp
);
975 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
977 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
979 if (*S_GET_NAME (symbolP
) == 'L')
981 sym_value
= S_GET_VALUE (symbolP
);
982 if (sym_value
> sp_value
&& sym_value
< Size
)
986 * Dummy labels like "gcc_compiled." should no longer reach here.
990 /* check if gcc_compiled. has size of zero */
991 if (sym_value
== sp_value
&&
993 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
994 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
999 if (Size
== 0x7fffffff)
1001 Size
-= sp_value
; /* and get the size of the routine */
1009 Local
[1] = DST_S_C_RTNEND
;
1017 COPY_LONG (&Local
[3], Size
);
1021 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1025 * Write the Traceback Block End record
1028 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1029 struct symbol
*symbolP
;
1033 register char *cp
, *cp1
;
1040 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1046 * Begin Block - We simulate with a phony routine
1048 Local
[1] = DST_S_C_BLKBEG
;
1054 * Store the data so far
1056 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1058 * Make sure we are still generating a OBJ_S_C_DBG record
1060 if (Object_Record_Offset
== 0)
1061 PUT_CHAR (OBJ_S_C_DBG
);
1063 * Now get the symbol address
1065 PUT_CHAR (TIR_S_C_STA_WPL
);
1068 * Get the text psect offset
1070 Offset
= S_GET_VALUE (symbolP
);
1073 * Store the data reference
1075 PUT_CHAR (TIR_S_C_STO_PIDR
);
1077 * Store the counted string as data
1081 Size
= strlen (cp1
) + 1;
1085 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1090 * Write the Traceback Block End record
1093 VMS_TBT_Block_End (Size
)
1099 * End block - simulate with a phony end routine
1102 Local
[1] = DST_S_C_BLKEND
;
1103 COPY_LONG (&Local
[3], Size
);
1108 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1114 * Write a Line number / PC correlation record
1117 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1127 * If not delta, set our PC/Line number correlation
1134 Local
[0] = 1 + 1 + 2 + 1 + 4;
1136 * Line Number/PC correlation
1138 Local
[1] = DST_S_C_LINE_NUM
;
1142 Local
[2] = DST_S_C_SET_LINE_NUM
;
1143 COPY_SHORT (&Local
[3], Line_Number
- 1);
1147 Local
[5] = DST_S_C_SET_ABS_PC
;
1148 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1150 * Make sure we are still generating a OBJ_S_C_TBT record
1152 if (Object_Record_Offset
== 0)
1153 PUT_CHAR (OBJ_S_C_TBT
);
1156 PUT_CHAR (TIR_S_C_STA_PL
);
1161 PUT_CHAR (TIR_S_C_STA_WPL
);
1165 PUT_CHAR (TIR_S_C_STO_PIDR
);
1167 * Do a PC offset of 0 to register the line number
1170 Local
[1] = DST_S_C_LINE_NUM
;
1171 Local
[2] = 0; /* Increment PC by 0 and register line # */
1172 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1177 * If Delta is negative, terminate the line numbers
1181 Local
[0] = 1 + 1 + 4;
1182 Local
[1] = DST_S_C_LINE_NUM
;
1183 Local
[2] = DST_S_C_TERM_L
;
1184 COPY_LONG (&Local
[3], Offset
);
1185 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1192 * Do a PC/Line delta
1195 *cp
++ = DST_S_C_LINE_NUM
;
1196 if (Line_Number
> 1)
1199 * We need to increment the line number
1201 if (Line_Number
- 1 <= 255)
1203 *cp
++ = DST_S_C_INCR_LINUM
;
1204 *cp
++ = Line_Number
- 1;
1208 *cp
++ = DST_S_C_INCR_LINUM_W
;
1209 COPY_SHORT (cp
, Line_Number
- 1);
1210 cp
+= sizeof (short);
1222 if (Offset
< 0x10000)
1224 *cp
++ = DST_S_C_DELTA_PC_W
;
1225 COPY_SHORT (cp
, Offset
);
1226 cp
+= sizeof (short);
1230 *cp
++ = DST_S_C_DELTA_PC_L
;
1231 COPY_LONG (cp
, Offset
);
1232 cp
+= sizeof (long);
1235 Local
[0] = cp
- (Local
+ 1);
1236 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1242 * Describe a source file to the debugger
1245 VMS_TBT_Source_File (Filename
, ID_Number
)
1249 register char *cp
, *cp1
;
1252 #ifndef VMS /* Used for cross-assembly */
1253 i
= strlen (Filename
);
1255 static struct FAB Fab
;
1256 static struct NAM Nam
;
1257 static struct XABDAT Date_Xab
;
1258 static struct XABFHC File_Header_Xab
;
1259 char Es_String
[255], Rs_String
[255];
1264 Fab
.fab$b_bid
= FAB$C_BID
;
1265 Fab
.fab$b_bln
= sizeof (Fab
);
1266 Fab
.fab$l_nam
= (&Nam
);
1267 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1269 * Setup the Nam block so we can find out the FULL name
1270 * of the source file.
1272 Nam
.nam$b_bid
= NAM$C_BID
;
1273 Nam
.nam$b_bln
= sizeof (Nam
);
1274 Nam
.nam$l_rsa
= Rs_String
;
1275 Nam
.nam$b_rss
= sizeof (Rs_String
);
1276 Nam
.nam$l_esa
= Es_String
;
1277 Nam
.nam$b_ess
= sizeof (Es_String
);
1279 * Setup the Date and File Header Xabs
1281 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1282 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1283 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1284 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1285 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1287 * Get the file information
1289 Fab
.fab$l_fna
= Filename
;
1290 Fab
.fab$b_fns
= strlen (Filename
);
1291 Status
= sys$
open (&Fab
);
1294 printf ("gas: Couldn't find source file \"%s\", status=%%X%x\n",
1300 * Calculate the size of the resultant string
1307 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1309 * Source declaration
1311 Local
[1] = DST_S_C_SOURCE
;
1313 * Make formfeeds count as source records
1315 Local
[2] = DST_S_C_SRC_FORMFEED
;
1317 * Declare source file
1319 Local
[3] = DST_S_C_SRC_DECLFILE
;
1320 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1329 COPY_SHORT (cp
, ID_Number
);
1330 cp
+= sizeof (short);
1333 * Creation Date. Unknown, so we fill with zeroes.
1336 cp
+= sizeof (long);
1338 cp
+= sizeof (long);
1343 cp
+= sizeof (long);
1348 cp
+= sizeof (short);
1358 #else /* Use this code when assembling for VMS on a VMS system */
1362 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1363 cp
+= sizeof (long);
1364 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1365 cp
+= sizeof (long);
1369 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1370 cp
+= sizeof (long);
1374 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1375 cp
+= sizeof (short);
1379 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1389 * Library module name (none)
1395 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1401 * Give the number of source lines to the debugger
1404 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1406 int Starting_Line_Number
;
1407 int Number_Of_Lines
;
1415 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1417 * Source declaration
1419 Local
[1] = DST_S_C_SOURCE
;
1424 *cp
++ = DST_S_C_SRC_SETFILE
;
1428 COPY_SHORT (cp
, ID_Number
);
1429 cp
+= sizeof (short);
1433 *cp
++ = DST_S_C_SRC_SETREC_L
;
1434 COPY_LONG (cp
, Starting_Line_Number
);
1435 cp
+= sizeof (long);
1439 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1440 COPY_SHORT (cp
, Number_Of_Lines
);
1441 cp
+= sizeof (short);
1445 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1451 /* This routine locates a file in the list of files. If an entry does not
1452 * exist, one is created. For include files, a new entry is always created
1453 * such that inline functions can be properly debugged. */
1454 static struct input_file
*
1458 struct input_file
*same_file
;
1459 struct input_file
*fpnt
;
1460 same_file
= (struct input_file
*) NULL
;
1461 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1463 if (fpnt
== (struct input_file
*) NULL
)
1465 if (fpnt
->spnt
== sp
)
1468 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1470 if (fpnt
== (struct input_file
*) NULL
)
1472 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1474 if (fpnt
->flag
== 1)
1480 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1481 if (file_root
== (struct input_file
*) NULL
)
1485 struct input_file
*fpnt1
;
1486 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1489 fpnt
->next
= (struct input_file
*) NULL
;
1490 fpnt
->name
= S_GET_NAME (sp
);
1491 fpnt
->min_line
= 0x7fffffff;
1495 fpnt
->file_number
= 0;
1497 fpnt
->same_file_fpnt
= same_file
;
1502 * The following functions and definitions are used to generate object records
1503 * that will describe program variables to the VMS debugger.
1505 * This file contains many of the routines needed to output debugging info into
1506 * the object file that the VMS debugger needs to understand symbols. These
1507 * routines are called very late in the assembly process, and thus we can be
1508 * fairly lax about changing things, since the GSD and the TIR sections have
1509 * already been output.
1513 /* This routine converts a number string into an integer, and stops when it
1514 * sees an invalid character. The return value is the address of the character
1515 * just past the last character read. No error is generated.
1518 cvt_integer (str
, rtn
)
1523 neg
= *str
== '-' ? ++str
, -1 : 1;
1525 while ((*str
<= '9') && (*str
>= '0'))
1526 ival
= 10 * ival
+ *str
++ - '0';
1531 /* this routine fixes the names that are generated by C++, ".this" is a good
1532 * example. The period does not work for the debugger, since it looks like
1533 * the syntax for a structure element, and thus it gets mightily confused
1535 * We also use this to strip the PsectAttribute hack from the name before we
1536 * write a debugger record */
1544 * Kill any leading "_"
1549 * Is there a Psect Attribute to skip??
1551 if (HAS_PSECT_ATTRIBUTES (pnt
))
1556 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1559 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1567 /* Here we fix the .this -> $this conversion */
1568 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1576 /* When defining a structure, this routine is called to find the name of
1577 * the actual structure. It is assumed that str points to the equal sign
1578 * in the definition, and it moves backward until it finds the start of the
1579 * name. If it finds a 0, then it knows that this structure def is in the
1580 * outermost level, and thus symbol_name points to the symbol name.
1583 get_struct_name (str
)
1588 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1593 while ((*pnt
!= ';') && (*pnt
!= '='))
1597 while ((*pnt
< '0') || (*pnt
> '9'))
1599 while ((*pnt
>= '0') && (*pnt
<= '9'))
1604 /* search symbol list for type number dbx_type. Return a pointer to struct */
1605 static struct VMS_DBG_Symbol
*
1606 find_symbol (dbx_type
)
1609 struct VMS_DBG_Symbol
*spnt
;
1610 spnt
= VMS_Symbol_type_list
;
1611 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1613 if (spnt
->dbx_type
== dbx_type
)
1617 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1618 return 0; /*Dunno what this is*/
1619 if(spnt
->advanced
== ALIAS
)
1620 return find_symbol(spnt
->type2
);
1625 /* this routine puts info into either Local or Asuffix, depending on the sign
1626 * of size. The reason is that it is easier to build the variable descriptor
1627 * backwards, while the array descriptor is best built forwards. In the end
1628 * they get put together, if there is not a struct/union/enum along the way
1647 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1651 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1654 Apoint
= MAX_DEBUG_RECORD
- 1;
1657 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1662 /* this routine generates the array descriptor for a given array */
1664 array_suffix (spnt2
)
1665 struct VMS_DBG_Symbol
*spnt2
;
1667 struct VMS_DBG_Symbol
*spnt
;
1668 struct VMS_DBG_Symbol
*spnt1
;
1674 while (spnt
->advanced
!= ARRAY
)
1676 spnt
= find_symbol (spnt
->type2
);
1677 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1683 while (spnt1
->advanced
== ARRAY
)
1686 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1687 spnt1
= find_symbol (spnt1
->type2
);
1689 total_size
= total_size
* spnt1
->data_size
;
1690 push (spnt1
->data_size
, 2); /* element size */
1691 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1694 push (spnt1
->VMS_type
, 1); /* element type */
1695 push (DSC_K_CLASS_A
, 1); /* descriptor class */
1696 push (0, 4); /* base address */
1697 push (0, 1); /* scale factor -- not applicable */
1698 push (0, 1); /* digit count -- not applicable */
1699 push (0xc0, 1); /* flags: multiplier block & bounds present */
1700 push (rank
, 1); /* number of dimensions */
1701 push (total_size
, 4);
1702 push (0, 4); /* pointer to element [0][0]...[0] */
1704 while (spnt1
->advanced
== ARRAY
)
1706 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1707 spnt1
= find_symbol (spnt1
->type2
);
1710 while (spnt1
->advanced
== ARRAY
)
1712 push (spnt1
->index_min
, 4);
1713 push (spnt1
->index_max
, 4);
1714 spnt1
= find_symbol (spnt1
->type2
);
1718 /* this routine generates the start of a variable descriptor based upon
1719 * a struct/union/enum that has yet to be defined. We define this spot as
1720 * a new location, and save four bytes for the address. When the struct is
1721 * finally defined, then we can go back and plug in the correct address.
1724 new_forward_ref (dbx_type
)
1727 struct forward_ref
*fpnt
;
1728 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1729 fpnt
->next
= f_ref_root
;
1731 fpnt
->dbx_type
= dbx_type
;
1732 fpnt
->struc_numb
= ++structure_count
;
1733 fpnt
->resolved
= 'N';
1734 push (DST_K_TS_IND
, -1); /* indirect type specification */
1736 push (total_len
, -2);
1737 struct_number
= -fpnt
->struc_numb
;
1740 /* this routine generates the variable descriptor used to describe non-basic
1741 * variables. It calls itself recursively until it gets to the bottom of it
1742 * all, and then builds the descriptor backwards. It is easiest to do it this
1743 *way since we must periodically write length bytes, and it is easiest if we know
1744 *the value when it is time to write it.
1747 gen1 (spnt
, array_suffix_len
)
1748 struct VMS_DBG_Symbol
*spnt
;
1749 int array_suffix_len
;
1751 struct VMS_DBG_Symbol
*spnt1
;
1753 switch (spnt
->advanced
)
1756 push (DBG_S_C_VOID
, -1);
1758 push (total_len
, -2);
1762 if (array_suffix_len
== 0)
1764 push (spnt
->VMS_type
, -1);
1765 push (DBG_S_C_BASIC
, -1);
1767 push (total_len
, -2);
1771 push (DST_K_VFLAGS_DSC
, -1);
1772 push (DST_K_TS_DSC
, -1); /* descriptor type specification */
1778 struct_number
= spnt
->struc_numb
;
1779 if (struct_number
< 0)
1781 new_forward_ref (spnt
->dbx_type
);
1784 push (DBG_S_C_STRUCT
, -1);
1786 push (total_len
, -2);
1789 spnt1
= find_symbol (spnt
->type2
);
1792 new_forward_ref (spnt
->type2
);
1794 i
= gen1 (spnt1
, 0);
1796 { /* (*void) is a special case, do not put pointer suffix*/
1797 push (DBG_S_C_POINTER
, -1);
1799 push (total_len
, -2);
1804 while (spnt1
->advanced
== ARRAY
)
1806 spnt1
= find_symbol (spnt1
->type2
);
1809 printf ("gcc-as warning(debugger output):");
1810 printf ("Forward reference error, dbx type %d\n",
1815 /* It is too late to generate forward references, so the user gets a message.
1816 * This should only happen on a compiler error */
1817 i
= gen1 (spnt1
, 1);
1819 array_suffix (spnt
);
1820 array_suffix_len
= Apoint
- i
;
1821 switch (spnt1
->advanced
)
1829 push (total_len
, -2);
1830 push (DST_K_VFLAGS_DSC
, -1);
1831 push (1, -1); /* flags: element value spec included */
1832 push (1, -1); /* one dimension */
1833 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1835 total_len
+= array_suffix_len
+ 8;
1836 push (total_len
, -2);
1840 /* This generates a suffix for a variable. If it is not a defined type yet,
1841 * then dbx_type contains the type we are expecting so we can generate a
1842 * forward reference. This calls gen1 to build most of the descriptor, and
1843 * then it puts the icing on at the end. It then dumps whatever is needed
1844 * to get a complete descriptor (i.e. struct reference, array suffix ).
1847 generate_suffix (spnt
, dbx_type
)
1848 struct VMS_DBG_Symbol
*spnt
;
1851 static CONST
char pvoid
[6] = {
1852 5, /* record.length == 5 */
1853 DST_K_TYPSPEC
, /* record.type == 1 (type specification) */
1854 0, /* name.length == 0, no name follows */
1855 1, 0, /* type.length == 1 {2 bytes, little endian} */
1856 DBG_S_C_VOID
/* type.type == 5 (pointer to unspecified) */
1860 struct VMS_DBG_Symbol
*spnt1
;
1862 Lpnt
= MAX_DEBUG_RECORD
- 1;
1867 new_forward_ref (dbx_type
);
1870 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1871 return 0; /* no suffix needed */
1874 push (0, -1); /* no name (len==0) */
1875 push (DST_K_TYPSPEC
, -1);
1877 push (total_len
, -1);
1878 /* if the variable descriptor overflows the record, output a descriptor for
1879 * a pointer to void.
1881 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1883 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1884 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1888 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1889 Local
[i
++] = Local
[++Lpnt
];
1891 /* we use this for a reference to a structure that has already been defined */
1892 if (struct_number
> 0)
1894 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1896 VMS_Store_Struct (struct_number
);
1898 /* we use this for a forward reference to a structure that has yet to be
1899 *defined. We store four bytes of zero to make room for the actual address once
1902 if (struct_number
< 0)
1904 struct_number
= -struct_number
;
1905 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1907 VMS_Def_Struct (struct_number
);
1908 COPY_LONG(&Local
[Lpnt
], 0L);
1910 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1915 Local
[Lpnt
++] = Asuffix
[i
++];
1917 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1921 /* "novel length" type doesn't work for simple atomic types */
1922 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
1923 #undef SETUP_BASIC_TYPES
1926 bitfield_suffix (spnt
, width
)
1927 struct VMS_DBG_Symbol
*spnt
;
1930 Local
[Lpnt
++] = 13; /* rec.len==13 */
1931 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* a type specification record */
1932 Local
[Lpnt
++] = 0; /* not named */
1933 COPY_SHORT(&Local
[Lpnt
], 9); /* typ.len==9 */
1935 Local
[Lpnt
++] = DST_K_TS_NOV_LENG
; /* This type is a "novel length"
1936 incarnation of some other type. */
1937 COPY_LONG(&Local
[Lpnt
], width
); /* size in bits == novel length */
1939 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1941 /* assert( spnt->struc_numb > 0 ); */
1942 VMS_Store_Struct (spnt
->struc_numb
); /* output 4 more bytes */
1945 /* Formally define a builtin type, so that it can serve as the target of
1946 an indirect reference. It makes bitfield_suffix() easier by avoiding
1947 the need to use a forward reference for the first occurrence of each
1948 type used in a bitfield. */
1950 setup_basic_type (spnt
)
1951 struct VMS_DBG_Symbol
*spnt
;
1953 #ifdef SETUP_BASIC_TYPES
1954 /* This would be very useful if "novel length" fields actually worked
1955 with basic types like they do with enumerated types. However,
1956 they do not, so this isn't worth doing just so that you can use
1957 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
1959 #ifndef SETUP_SYNONYM_TYPES
1960 /* This determines whether compatible things like `int' and `long int'
1961 ought to have distinct type records rather than sharing one. */
1962 struct VMS_DBG_Symbol
*spnt2
;
1964 /* first check whether this type has already been seen by another name */
1965 for (spnt2
= VMS_Symbol_type_list
; spnt2
; spnt2
= spnt2
->next
)
1966 if (spnt2
!= spnt
&& spnt2
->VMS_type
== spnt
->VMS_type
)
1968 spnt
->struc_numb
= spnt2
->struc_numb
;
1973 /* `structure number' doesn't really mean `structure'; it means an index
1974 into a linker maintained set of saved locations which can be referenced
1976 spnt
->struc_numb
= ++structure_count
;
1977 VMS_Def_Struct (spnt
->struc_numb
); /* remember where this type lives */
1978 /* define the simple scalar type */
1979 Local
[Lpnt
++] = 6 + strlen (symbol_name
) + 2; /* rec.len */
1980 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* rec.typ==type specification */
1981 Local
[Lpnt
++] = strlen (symbol_name
) + 2;
1982 Local
[Lpnt
++] = '_'; /* prefix name with "__" */
1983 Local
[Lpnt
++] = '_';
1984 for (p
= symbol_name
; *p
; p
++)
1985 Local
[Lpnt
++] = *p
== ' ' ? '_' : *p
;
1986 COPY_SHORT(&Local
[Lpnt
], 2); /* typ.len==2 */
1988 Local
[Lpnt
++] = DST_K_TS_ATOM
; /* typ.kind is simple type */
1989 Local
[Lpnt
++] = spnt
->VMS_type
; /* typ.type */
1990 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1992 #endif /* SETUP_BASIC_TYPES */
1995 /* This routine generates a symbol definition for a C symbol for the debugger.
1996 * It takes a psect and offset for global symbols; if psect < 0, then this is
1997 * a local variable and the offset is relative to FP. In this case it can
1998 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2001 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2002 struct VMS_DBG_Symbol
*spnt
;
2013 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
2014 len
= strlen(Name_pnt
);
2016 { /* this is a local variable, referenced to SP */
2017 Local
[i
++] = 7 + len
;
2018 Local
[i
++] = spnt
->VMS_type
;
2019 Local
[i
++] = (Offset
> 0) ? DBG_C_FUNCTION_PARAM
: DBG_C_LOCAL_SYM
;
2020 COPY_LONG (&Local
[i
], Offset
);
2025 Local
[i
++] = 7 + len
;
2026 Local
[i
++] = spnt
->VMS_type
;
2027 Local
[i
++] = DST_K_VALKIND_ADDR
;
2028 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2030 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2033 while (*Name_pnt
!= '\0')
2034 Local
[i
++] = *Name_pnt
++;
2035 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2036 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2037 generate_suffix (spnt
, 0);
2041 /* This routine parses the stabs entries in order to make the definition
2042 * for the debugger of local symbols and function parameters
2045 VMS_local_stab_Parse (sp
)
2051 struct VMS_DBG_Symbol
*spnt
;
2052 struct VMS_Symbol
*vsp
;
2055 str
= S_GET_NAME (sp
);
2056 pnt
= (char *) strchr (str
, ':');
2057 if (pnt
== (char *) NULL
)
2058 return; /* no colon present */
2059 pnt1
= pnt
++; /* save this for later, and skip colon */
2061 return 0; /* ignore static constants */
2062 /* there is one little catch that we must be aware of. Sometimes function
2063 * parameters are optimized into registers, and the compiler, in its infiite
2064 * wisdom outputs stabs records for *both*. In general we want to use the
2065 * register if it is present, so we must search the rest of the symbols for
2066 * this function to see if this parameter is assigned to a register.
2074 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2076 if (!S_IS_DEBUG (sp1
))
2078 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2080 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2081 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2083 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2085 str1
= S_GET_NAME (sp1
); /* and get the name */
2087 while (*pnt2
!= ':')
2094 if ((*str1
!= ':') || (*pnt2
!= ':'))
2096 return; /* they are the same! lets skip this one */
2098 /* first find the dbx symbol type from list, and then find VMS type */
2099 pnt
++; /* skip p in case no register */
2102 pnt
= cvt_integer (pnt
, &dbx_type
);
2103 spnt
= find_symbol (dbx_type
);
2105 return 0; /*Dunno what this is*/
2107 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2108 *pnt1
= ':'; /* and restore the string */
2112 /* This routine parses a stabs entry to find the information required to define
2113 * a variable. It is used for global and static variables.
2114 * Basically we need to know the address of the symbol. With older versions
2115 * of the compiler, const symbols are
2116 * treated differently, in that if they are global they are written into the
2117 * text psect. The global symbol entry for such a const is actually written
2118 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2119 * of psects, we must search the entry points as well. static consts are even
2120 * harder, since they are never assigned a memory address. The compiler passes
2121 * a stab to tell us the value, but I am not sure what to do with it.
2125 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2128 int type1
, type2
, Text_Psect
;
2134 struct VMS_DBG_Symbol
*spnt
;
2135 struct VMS_Symbol
*vsp
;
2138 str
= S_GET_NAME (sp
);
2139 pnt
= (char *) strchr (str
, ':');
2140 if (pnt
== (char *) NULL
)
2141 return; /* no colon present */
2142 pnt1
= pnt
; /* save this for later*/
2144 if (*pnt
== expected_type
)
2146 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2147 spnt
= find_symbol (dbx_type
);
2148 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2149 return 0; /*Dunno what this is*/
2150 /* now we need to search the symbol table to find the psect and offset for
2155 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2157 pnt
= S_GET_NAME (vsp
->Symbol
);
2158 if (pnt
!= (char *) NULL
)
2160 /* make sure name is the same, and make sure correct symbol type */
2161 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2162 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2163 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2167 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2169 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2170 *pnt1
= ':'; /* and restore the string */
2173 /* the symbol was not in the symbol list, but it may be an "entry point"
2174 if it was a constant */
2175 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2178 * Dispatch on STAB type
2180 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2182 pnt
= S_GET_NAME (sp1
);
2185 if (strcmp (pnt
, str
) == 0)
2187 if (!gave_compiler_message
&& expected_type
== 'G')
2189 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2190 printf ("global constant(s) in the text psect. These will not be available to\n");
2191 printf ("other modules, since this is not the correct way to handle this. You\n");
2192 printf ("have two options: 1) get a patched compiler that does not put global\n");
2193 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2194 printf ("definitions of global variables in your source module(s). Don't say\n");
2195 printf ("I didn't warn you!");
2196 gave_compiler_message
= 1;
2198 VMS_DBG_record (spnt
,
2203 *S_GET_NAME (sp1
) = 'L';
2204 /* fool assembler to not output this
2205 * as a routine in the TBT */
2210 *pnt1
= ':'; /* and restore the string */
2215 VMS_GSYM_Parse (sp
, Text_Psect
)
2218 { /* Global variables */
2219 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2224 VMS_LCSYM_Parse (sp
, Text_Psect
)
2227 { /* Static symbols - uninitialized */
2228 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2232 VMS_STSYM_Parse (sp
, Text_Psect
)
2235 { /* Static symbols - initialized */
2236 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2240 /* for register symbols, we must figure out what range of addresses within the
2241 * psect are valid. We will use the brackets in the stab directives to give us
2242 * guidance as to the PC range that this variable is in scope. I am still not
2243 * completely comfortable with this but as I learn more, I seem to get a better
2244 * handle on what is going on.
2248 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2249 symbolS
*sp
, *Current_Routine
;
2256 struct VMS_DBG_Symbol
*spnt
;
2261 int Min_Offset
= -1; /* min PC of validity */
2262 int Max_Offset
= 0; /* max PC of validity */
2265 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2268 * Dispatch on STAB type
2270 switch (S_GET_RAW_TYPE (symbolP
))
2274 Min_Offset
= S_GET_VALUE (symbolP
);
2279 S_GET_VALUE (symbolP
) - 1;
2282 if ((Min_Offset
!= -1) && (bcnt
== 0))
2284 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2286 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2287 if (*pnt
== 'F' || *pnt
== 'f') break;
2290 /* check to see that the addresses were defined. If not, then there were no
2291 * brackets in the function, and we must try to search for the next function
2292 * Since functions can be in any order, we should search all of the symbol list
2293 * to find the correct ending address. */
2294 if (Min_Offset
== -1)
2296 int Max_Source_Offset
;
2298 Min_Offset
= S_GET_VALUE (sp
);
2299 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2302 * Dispatch on STAB type
2304 This_Offset
= S_GET_VALUE (symbolP
);
2305 switch (S_GET_RAW_TYPE (symbolP
))
2307 case N_TEXT
| N_EXT
:
2308 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2309 Max_Offset
= This_Offset
;
2312 if (This_Offset
> Max_Source_Offset
)
2313 Max_Source_Offset
= This_Offset
;
2316 /* if this is the last routine, then we use the PC of the last source line
2317 * as a marker of the max PC for which this reg is valid */
2318 if (Max_Offset
== 0x7fffffff)
2319 Max_Offset
= Max_Source_Offset
;
2322 str
= S_GET_NAME (sp
);
2323 pnt
= (char *) strchr (str
, ':');
2324 if (pnt
== (char *) NULL
)
2325 return; /* no colon present */
2326 pnt1
= pnt
; /* save this for later*/
2330 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2331 spnt
= find_symbol (dbx_type
);
2333 return 0; /*Dunno what this is yet*/
2335 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2337 Local
[i
++] = 25 + len
;
2338 Local
[i
++] = spnt
->VMS_type
;
2339 Local
[i
++] = DST_K_VFLAGS_TVS
; /* trailing value specified */
2340 COPY_LONG(&Local
[i
], 1 + len
); /* relative offset, beyond name */
2342 Local
[i
++] = len
; /* name length (ascic prefix) */
2343 while (*pnt
!= '\0')
2344 Local
[i
++] = *pnt
++;
2345 Local
[i
++] = DST_K_VS_FOLLOWS
; /* value specification follows */
2346 COPY_SHORT(&Local
[i
], 15); /* length of rest of record */
2348 Local
[i
++] = DST_K_VS_ALLOC_SPLIT
; /* split lifetime */
2349 Local
[i
++] = 1; /* one binding follows */
2350 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2352 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2353 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2354 Local
[i
++] = DST_K_VALKIND_REG
; /* nested value spec */
2355 COPY_LONG(&Local
[i
], S_GET_VALUE (sp
));
2357 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2359 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2360 generate_suffix (spnt
, 0);
2363 /* this function examines a structure definition, checking all of the elements
2364 * to make sure that all of them are fully defined. The only thing that we
2365 * kick out are arrays of undefined structs, since we do not know how big
2366 * they are. All others we can handle with a normal forward reference.
2369 forward_reference (pnt
)
2373 struct VMS_DBG_Symbol
*spnt
;
2374 struct VMS_DBG_Symbol
*spnt1
;
2375 pnt
= cvt_integer (pnt
+ 1, &i
);
2377 return 0; /* no forward references */
2380 pnt
= (char *) strchr (pnt
, ':');
2381 pnt
= cvt_integer (pnt
+ 1, &i
);
2382 spnt
= find_symbol (i
);
2383 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2384 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2387 spnt1
= find_symbol (spnt
->type2
);
2388 if ((spnt
->advanced
== ARRAY
) &&
2389 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2391 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2396 pnt
= cvt_integer (pnt
+ 1, &i
);
2397 pnt
= cvt_integer (pnt
+ 1, &i
);
2398 } while (*++pnt
!= ';');
2399 return 0; /* no forward refences found */
2402 /* Used to check a single element of a structure on the final pass*/
2405 final_forward_reference (spnt
)
2406 struct VMS_DBG_Symbol
*spnt
;
2408 struct VMS_DBG_Symbol
*spnt1
;
2410 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2412 spnt1
= find_symbol(spnt
->type2
);
2413 if (spnt
->advanced
== ARRAY
&& !spnt1
) return 1;
2416 return 0; /* no forward refences found */
2419 /* This routine parses the stabs directives to find any definitions of dbx type
2420 * numbers. It makes a note of all of them, creating a structure element
2421 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2422 * debugger that describes the struct/union/enum, so that further references
2423 * to these data types will be by number
2424 * We have to process pointers right away, since there can be references
2425 * to them later in the same stabs directive. We cannot have forward
2426 * references to pointers, (but we can have a forward reference to a pointer to
2427 * a structure/enum/union) and this is why we process them immediately.
2428 * After we process the pointer, then we search for defs that are nested even
2430 * 8/15/92: We have to process arrays right away too, because there can
2431 * be multiple references to identical array types in one structure
2432 * definition, and only the first one has the definition. (We tend to
2433 * parse from the back going forward.
2436 VMS_typedef_parse (str
)
2444 struct forward_ref
*fpnt
;
2445 int i1
, i2
, i3
, len
;
2446 int convert_integer
;
2447 struct VMS_DBG_Symbol
*spnt
;
2448 struct VMS_DBG_Symbol
*spnt1
;
2450 /* check for any nested def's */
2451 pnt
= (char *) strchr (str
+ 1, '=');
2452 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2453 && (str
[1] != 'a' || str
[2] != 'r'))
2454 if (VMS_typedef_parse (pnt
) == 1)
2456 /* now find dbx_type of entry */
2459 { /* check for static constants */
2460 *str
= '\0'; /* for now we ignore them */
2463 while ((*pnt
<= '9') && (*pnt
>= '0'))
2465 pnt
++; /* and get back to the number */
2466 cvt_integer (pnt
, &i1
);
2467 spnt
= find_symbol (i1
);
2468 /* first we see if this has been defined already, due to a forward reference*/
2471 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2472 spnt
->next
= VMS_Symbol_type_list
;
2473 VMS_Symbol_type_list
= spnt
;
2474 spnt
->dbx_type
= i1
; /* and save the type */
2475 spnt
->type2
= spnt
->VMS_type
= spnt
->data_size
= 0;
2476 spnt
->index_min
= spnt
->index_max
= spnt
->struc_numb
= 0;
2478 /* for structs and unions, do a partial parse, otherwise we sometimes get
2479 * circular definitions that are impossible to resolve. We read enough info
2480 * so that any reference to this type has enough info to be resolved
2482 pnt
= str
+ 1; /* point to character past equal sign */
2483 if ((*pnt
== 'u') || (*pnt
== 's'))
2486 if ((*pnt
<= '9') && (*pnt
>= '0'))
2488 if (type_check ("void"))
2489 { /* this is the void symbol */
2491 spnt
->advanced
= VOID
;
2494 if (type_check ("unknown type"))
2497 spnt
->advanced
= UNKNOWN
;
2500 pnt1
= cvt_integer(pnt
,&i1
);
2501 if(i1
!= spnt
->dbx_type
)
2503 spnt
->advanced
= ALIAS
;
2508 printf ("gcc-as warning(debugger output):");
2509 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2510 return 1; /* do not know what this is */
2512 /* now define this module*/
2513 pnt
= str
+ 1; /* point to character past equal sign */
2517 spnt
->advanced
= BASIC
;
2518 if (type_check ("int"))
2520 spnt
->VMS_type
= DBG_S_C_SLINT
;
2521 spnt
->data_size
= 4;
2523 else if (type_check ("long int"))
2525 spnt
->VMS_type
= DBG_S_C_SLINT
;
2526 spnt
->data_size
= 4;
2528 else if (type_check ("unsigned int"))
2530 spnt
->VMS_type
= DBG_S_C_ULINT
;
2531 spnt
->data_size
= 4;
2533 else if (type_check ("long unsigned int"))
2535 spnt
->VMS_type
= DBG_S_C_ULINT
;
2536 spnt
->data_size
= 4;
2538 else if (type_check ("short int"))
2540 spnt
->VMS_type
= DBG_S_C_SSINT
;
2541 spnt
->data_size
= 2;
2543 else if (type_check ("short unsigned int"))
2545 spnt
->VMS_type
= DBG_S_C_USINT
;
2546 spnt
->data_size
= 2;
2548 else if (type_check ("char"))
2550 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2551 spnt
->data_size
= 1;
2553 else if (type_check ("signed char"))
2555 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2556 spnt
->data_size
= 1;
2558 else if (type_check ("unsigned char"))
2560 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2561 spnt
->data_size
= 1;
2563 else if (type_check ("float"))
2565 spnt
->VMS_type
= DBG_S_C_REAL4
;
2566 spnt
->data_size
= 4;
2568 else if (type_check ("double"))
2570 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2571 spnt
->data_size
= 8;
2573 else if (type_check ("long double"))
2575 /* same as double, at least for now */
2576 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2577 spnt
->data_size
= 8;
2579 else if (type_check ("long long int"))
2581 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2582 spnt
->data_size
= 8;
2584 else if (type_check ("long long unsigned int"))
2586 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2587 spnt
->data_size
= 8;
2589 else if (type_check ("complex float"))
2591 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2592 spnt
->data_size
= 2 * 4;
2594 else if (type_check ("complex double"))
2596 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2597 spnt
->data_size
= 2 * 8;
2599 else if (type_check ("complex long double"))
2601 /* same as complex double, at least for now */
2602 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2603 spnt
->data_size
= 2 * 8;
2608 * Shouldn't get here, but if we do, something
2609 * more substantial ought to be done...
2612 spnt
->data_size
= 0;
2614 if (spnt
->VMS_type
!= 0)
2615 setup_basic_type(spnt
);
2616 pnt1
= (char *) strchr (str
, ';') + 1;
2620 spnt
->advanced
= (*pnt
== 's') ? STRUCT
: UNION
;
2621 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2622 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2623 if (!final_pass
&& forward_reference(pnt
))
2625 spnt
->struc_numb
= -1;
2628 spnt
->struc_numb
= ++structure_count
;
2630 pnt
= get_struct_name (str
);
2631 VMS_Def_Struct (spnt
->struc_numb
);
2633 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2634 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2636 fpnt
->resolved
= 'Y';
2637 VMS_Set_Struct (fpnt
->struc_numb
);
2638 VMS_Store_Struct (spnt
->struc_numb
);
2642 VMS_Set_Struct (spnt
->struc_numb
);
2644 Local
[i
++] = 11 + strlen (pnt
);
2645 Local
[i
++] = DBG_S_C_STRUCT_START
;
2646 Local
[i
++] = DST_K_VFLAGS_NOVAL
; /* structure definition only */
2647 COPY_LONG(&Local
[i
], 0L); /* hence value is unused */
2649 Local
[i
++] = strlen (pnt
);
2651 while (*pnt2
!= '\0')
2652 Local
[i
++] = *pnt2
++;
2653 i2
= spnt
->data_size
* 8; /* number of bits */
2654 COPY_LONG(&Local
[i
], i2
);
2656 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2658 if (pnt
!= symbol_name
)
2660 pnt
+= strlen (pnt
);
2662 } /* replace colon for later */
2663 while (*++pnt1
!= ';')
2665 pnt
= (char *) strchr (pnt1
, ':');
2668 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2669 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2670 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2671 spnt1
= find_symbol (dtype
);
2672 len
= strlen (pnt2
);
2673 if (spnt1
&& (spnt1
->advanced
== BASIC
|| spnt1
->advanced
== ENUM
)
2674 && ((i3
!= spnt1
->data_size
* 8) || (i2
% 8 != 0)))
2676 if (USE_BITSTRING_DESCRIPTOR (spnt1
))
2678 /* This uses a type descriptor, which doesn't work if
2679 the enclosing structure has been placed in a register.
2680 Also, enum bitfields degenerate to simple integers. */
2681 int unsigned_type
= (spnt1
->VMS_type
== DBG_S_C_ULINT
2682 || spnt1
->VMS_type
== DBG_S_C_USINT
2683 || spnt1
->VMS_type
== DBG_S_C_UCHAR
2684 || spnt1
->VMS_type
== DBG_S_C_UQUAD
2685 || spnt1
->advanced
== ENUM
); /* (approximate) */
2688 push (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2689 push (DST_K_VFLAGS_DSC
, 1); /* specified by descriptor */
2690 push (1 + len
, 4); /* relative offset to descriptor */
2691 push (len
, 1); /* length byte (ascic prefix) */
2692 while (*pnt2
!= '\0') /* name bytes */
2694 push (i3
, 2); /* dsc length == size of bitfield */
2695 /* dsc type == un?signed bitfield */
2696 push (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2697 push (DSC_K_CLASS_UBS
, 1); /* dsc class == unaligned bitstring */
2698 push (0x00, 4); /* dsc pointer == zeroes */
2699 push (i2
, 4); /* start position */
2700 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2705 /* Use a "novel length" type specification, which works
2706 right for register structures and for enum bitfields
2707 but results in larger object modules. */
2708 Local
[i
++] = 7 + len
;
2709 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
; /* type spec follows */
2710 Local
[i
++] = DBG_S_C_STRUCT_ITEM
; /* value is a bit offset */
2711 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2713 Local
[i
++] = strlen (pnt2
);
2714 while (*pnt2
!= '\0')
2715 Local
[i
++] = *pnt2
++;
2716 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2718 bitfield_suffix (spnt1
, i3
);
2722 { /* not a bitfield */
2723 /* check if this is a forward reference */
2724 if(final_pass
&& final_forward_reference(spnt1
))
2726 printf("gcc-as warning(debugger output):");
2727 printf("structure element `%s' has undefined type\n",pnt2
);
2730 Local
[i
++] = 7 + len
;
2731 Local
[i
++] = spnt1
? spnt1
->VMS_type
: DBG_S_C_ADVANCED_TYPE
;
2732 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2733 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2735 Local
[i
++] = strlen (pnt2
);
2736 while (*pnt2
!= '\0')
2737 Local
[i
++] = *pnt2
++;
2738 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2741 generate_suffix (spnt1
, dtype
);
2742 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2743 generate_suffix (spnt1
, 0);
2747 Local
[i
++] = 0x01; /* length byte */
2748 Local
[i
++] = DBG_S_C_STRUCT_END
;
2749 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2753 spnt
->advanced
= ENUM
;
2754 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2755 spnt
->struc_numb
= ++structure_count
;
2756 spnt
->data_size
= 4;
2757 VMS_Def_Struct (spnt
->struc_numb
);
2759 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2760 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2762 fpnt
->resolved
= 'Y';
2763 VMS_Set_Struct (fpnt
->struc_numb
);
2764 VMS_Store_Struct (spnt
->struc_numb
);
2768 VMS_Set_Struct (spnt
->struc_numb
);
2770 len
= strlen (symbol_name
);
2771 Local
[i
++] = 3 + len
;
2772 Local
[i
++] = DBG_S_C_ENUM_START
;
2773 Local
[i
++] = 4 * 8; /* enum values are 32 bits */
2776 while (*pnt2
!= '\0')
2777 Local
[i
++] = *pnt2
++;
2778 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2780 while (*++pnt
!= ';')
2782 pnt1
= (char *) strchr (pnt
, ':');
2784 pnt1
= cvt_integer (pnt1
, &i1
);
2786 Local
[i
++] = 7 + len
;
2787 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2788 Local
[i
++] = DST_K_VALKIND_LITERAL
;
2789 COPY_LONG (&Local
[i
], i1
);
2793 while (*pnt
!= '\0')
2794 Local
[i
++] = *pnt
++;
2795 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2797 pnt
= pnt1
; /* Skip final semicolon */
2799 Local
[i
++] = 0x01; /* len byte */
2800 Local
[i
++] = DBG_S_C_ENUM_END
;
2801 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2806 spnt
->advanced
= ARRAY
;
2807 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2808 pnt
= (char *) strchr (pnt
, ';');
2809 if (pnt
== (char *) NULL
)
2811 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2812 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2813 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2814 pnt
=(char*)strchr(str
+1,'=');
2815 if((pnt
!= (char*) NULL
))
2816 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2819 spnt
->advanced
= FUNCTION
;
2820 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2821 /* this masquerades as a basic type*/
2822 spnt
->data_size
= 4;
2823 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2826 spnt
->advanced
= POINTER
;
2827 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2828 spnt
->data_size
= 4;
2829 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2830 pnt
= (char *) strchr (str
+ 1, '=');
2831 if ((pnt
!= (char *) NULL
))
2832 if (VMS_typedef_parse (pnt
) == 1)
2836 spnt
->advanced
= UNKNOWN
;
2838 printf ("gcc-as warning(debugger output):");
2839 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2840 return 1; /* unable to decipher */
2842 /* this removes the evidence of the definition so that the outer levels of
2843 parsing do not have to worry about it */
2845 while (*pnt1
!= '\0')
2853 * This is the root routine that parses the stabs entries for definitions.
2854 * it calls VMS_typedef_parse, which can in turn call itself.
2855 * We need to be careful, since sometimes there are forward references to
2856 * other symbol types, and these cannot be resolved until we have completed
2859 * Also check and see if we are using continuation stabs, if we are, then
2860 * paste together the entire contents of the stab before we pass it to
2861 * VMS_typedef_parse.
2870 char *parse_buffer
= 0;
2872 int incomplete
, i
, pass
, incom1
;
2873 struct VMS_DBG_Symbol
*spnt
;
2874 struct VMS_Symbol
*vsp
;
2875 struct forward_ref
*fpnt
;
2882 incom1
= incomplete
;
2884 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2887 * Deal with STAB symbols
2889 if (S_IS_DEBUG (sp
))
2892 * Dispatch on STAB type
2894 switch (S_GET_RAW_TYPE (sp
))
2902 case N_FUN
: /*sometimes these contain typedefs*/
2903 str
= S_GET_NAME (sp
);
2905 pnt
= str
+ strlen(str
) -1;
2906 if (*pnt
== '?') /* Continuation stab. */
2912 tlen
+= strlen(str
) - 1;
2913 spnext
= symbol_next (spnext
);
2914 str
= S_GET_NAME (spnext
);
2915 pnt
= str
+ strlen(str
) - 1;
2916 } while (*pnt
== '?');
2917 tlen
+= strlen(str
);
2918 parse_buffer
= (char *) xmalloc (tlen
+ 1);
2919 strcpy(parse_buffer
, S_GET_NAME (sp
));
2920 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2924 spnext
= symbol_next (spnext
);
2925 str
= S_GET_NAME (spnext
);
2926 strcat (pnt2
, S_GET_NAME (spnext
));
2927 pnt2
+= strlen(str
) - 1;
2928 *str
= '\0'; /* Erase this string */
2929 if (*pnt2
!= '?') break;
2935 pnt
= (char *) strchr (str
, ':');
2936 if (pnt
!= (char *) NULL
)
2940 pnt2
= (char *) strchr (pnt1
, '=');
2941 if (pnt2
!= (char *) NULL
)
2942 incomplete
+= VMS_typedef_parse (pnt2
);
2944 /* At this point the parse buffer should just contain name:nn.
2945 If it does not, then we are in real trouble. Anyway,
2946 this is always shorter than the original line. */
2947 strcpy(S_GET_NAME (sp
), parse_buffer
);
2948 free (parse_buffer
);
2951 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2958 /* Make one last pass, if needed, and define whatever we can that is left */
2959 if(final_pass
== 0 && incomplete
== incom1
)
2962 incom1
++; /* Force one last pass through */
2964 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2965 /* repeat until all refs resolved if possible */
2966 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2967 if (incomplete
!= 0)
2969 printf ("gcc-as warning(debugger output):");
2970 printf ("Unable to resolve %d circular references.\n", incomplete
);
2974 while (fpnt
!= (struct forward_ref
*) NULL
)
2976 if (fpnt
->resolved
!= 'Y')
2978 if (find_symbol (fpnt
->dbx_type
) !=
2979 (struct VMS_DBG_Symbol
*) NULL
)
2981 printf ("gcc-as warning(debugger output):");
2982 printf ("Forward reference error, dbx type %d\n",
2987 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2988 pnt2
= (char *) strchr (&fixit
[1], '=');
2989 VMS_typedef_parse (pnt2
);
2996 Define_Local_Symbols (s1
, s2
)
3000 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
3002 if (symbolP1
== (symbolS
*) NULL
)
3004 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3006 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3007 if (*pnt
== 'F' || *pnt
== 'f') break;
3010 * Deal with STAB symbols
3012 if (S_IS_DEBUG (symbolP1
))
3015 * Dispatch on STAB type
3017 switch (S_GET_RAW_TYPE (symbolP1
))
3021 VMS_local_stab_Parse (symbolP1
);
3024 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
3032 /* This function crawls the symbol chain searching for local symbols that need
3033 * to be described to the debugger. When we enter a new scope with a "{", it
3034 * creates a new "block", which helps the debugger keep track of which scope
3035 * we are currently in.
3039 Define_Routine (symbolP
, Level
)
3049 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
3051 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3053 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3054 if (*pnt
== 'F' || *pnt
== 'f') break;
3057 * Deal with STAB symbols
3059 if (S_IS_DEBUG (symbolP1
))
3062 * Dispatch on STAB type
3064 switch (S_GET_RAW_TYPE (symbolP1
))
3069 sprintf (str
, "$%d", rcount
++);
3070 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3072 Offset
= S_GET_VALUE (symbolP1
);
3073 Define_Local_Symbols (sstart
, symbolP1
);
3075 Define_Routine (symbolP1
, Level
+ 1);
3077 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3086 /* we end up here if there were no brackets in this function. Define
3088 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3094 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3096 symbolS
*Curr_Routine
;
3099 Current_Routine
= Curr_Routine
;
3100 Text_Psect
= Txt_Psect
;
3101 Define_Routine (symbolP
, 0);
3108 #include <sys/types.h>
3111 /* Manufacure a VMS like time on a unix based system. */
3112 get_VMS_time_on_unix (Now
)
3118 pnt
= ctime (&timeb
);
3124 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3127 #endif /* not VMS */
3129 * Write the MHD (Module Header) records
3132 Write_VMS_MHD_Records ()
3134 register char *cp
, *cp1
;
3141 char Module_Name
[256];
3145 * We are writing a module header record
3147 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3149 * ***************************
3150 * *MAIN MODULE HEADER RECORD*
3151 * ***************************
3153 * Store record type and header type
3155 PUT_CHAR (OBJ_S_C_HDR
);
3156 PUT_CHAR (MHD_S_C_MHD
);
3158 * Structure level is 0
3160 PUT_CHAR (OBJ_S_C_STRLVL
);
3162 * Maximum record size is size of the object record buffer
3164 PUT_SHORT (sizeof (Object_Record_Buffer
));
3166 * Get module name (the FILENAME part of the object file)
3172 if ((*cp
== ']') || (*cp
== '>') ||
3173 (*cp
== ':') || (*cp
== '/'))
3179 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3183 * Limit it to 31 characters and store in the object record
3185 while (--cp1
>= Module_Name
)
3188 if (strlen (Module_Name
) > 31)
3190 if (flag_hash_long_names
)
3191 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3192 Module_Name
[31] = 0;
3194 PUT_COUNTED_STRING (Module_Name
);
3196 * Module Version is "V1.0"
3198 PUT_COUNTED_STRING ("V1.0");
3200 * Creation time is "now" (17 chars of time string)
3203 get_VMS_time_on_unix (&Now
[0]);
3205 Descriptor
.Size
= 17;
3206 Descriptor
.Ptr
= Now
;
3207 sys$
asctim (0, &Descriptor
, 0, 0);
3209 for (i
= 0; i
< 17; i
++)
3212 * Patch time is "never" (17 zeros)
3214 for (i
= 0; i
< 17; i
++)
3219 Flush_VMS_Object_Record_Buffer ();
3221 * *************************
3222 * *LANGUAGE PROCESSOR NAME*
3223 * *************************
3225 * Store record type and header type
3227 PUT_CHAR (OBJ_S_C_HDR
);
3228 PUT_CHAR (MHD_S_C_LNM
);
3230 * Store language processor name and version
3231 * (not a counted string!)
3233 * This is normally supplied by the gcc driver for the command line
3234 * which invokes gas. If absent, we fall back to gas's version.
3236 cp
= compiler_version_string
;
3249 Flush_VMS_Object_Record_Buffer ();
3254 * Write the EOM (End Of Module) record
3257 Write_VMS_EOM_Record (Psect
, Offset
)
3262 * We are writing an end-of-module record
3264 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3268 PUT_CHAR (OBJ_S_C_EOM
);
3270 * Store the error severity (0)
3274 * Store the entry point, if it exists
3279 * Store the entry point Psect
3283 * Store the entry point Psect offset
3290 Flush_VMS_Object_Record_Buffer ();
3294 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3300 register unsigned char *p
= ptr
;
3301 register unsigned char *end
= p
+ strlen (ptr
);
3302 register unsigned char c
;
3303 register int hash
= 0;
3308 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3314 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3317 VMS_Case_Hack_Symbol (In
, Out
)
3327 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3329 int Case_Hack_Bits
= 0;
3331 static char Hex_Table
[16] =
3332 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3335 * Kill any leading "_"
3337 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3340 new_name
= Out
; /* save this for later*/
3342 #if barfoo /* Dead code */
3343 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3347 /* We may need to truncate the symbol, save the hash for later*/
3348 if (strlen (In
) > 23)
3349 result
= hash_string (In
);
3351 * Is there a Psect Attribute to skip??
3353 if (HAS_PSECT_ATTRIBUTES (In
))
3358 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3361 if ((In
[0] == '$') && (In
[1] == '$'))
3371 /* if (strlen(In) > 31 && flag_hash_long_names)
3372 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3374 * Do the case conversion
3376 i
= 23; /* Maximum of 23 chars */
3377 while (*In
&& (--i
>= 0))
3379 Case_Hack_Bits
<<= 1;
3382 if ((destructor
== 1) && (i
== 21))
3384 switch (vms_name_mapping
)
3389 Case_Hack_Bits
|= 1;
3391 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3394 case 3: *Out
++ = *In
++;
3400 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3406 * If we saw a dollar sign, we don't do case hacking
3408 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3412 * If we have more than 23 characters and everything is lowercase
3413 * we can insert the full 31 characters
3418 * We have more than 23 characters
3419 * If we must add the case hack, then we have truncated the str
3423 if (Case_Hack_Bits
== 0)
3426 * And so far they are all lower case:
3427 * Check up to 8 more characters
3428 * and ensure that they are lowercase
3430 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3431 if (isupper(In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3437 if ((i
== 8) || (In
[i
] == 0))
3440 * They are: Copy up to 31 characters
3441 * to the output string
3444 while ((--i
>= 0) && (*In
))
3445 switch (vms_name_mapping
){
3446 case 0: *Out
++ = islower(*In
) ?
3450 case 3: *Out
++ = *In
++;
3452 case 2: *Out
++ = isupper(*In
) ?
3461 * If there were any uppercase characters in the name we
3462 * take on the case hacking string
3465 /* Old behavior for regular GNU-C compiler */
3466 if (!flag_hash_long_names
)
3468 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3473 for (i
= 0; i
< 6; i
++)
3475 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3476 Case_Hack_Bits
>>= 4;
3482 Out
= pnt
; /*Cut back to 23 characters maximum */
3484 for (i
= 0; i
< 7; i
++)
3486 init
= result
& 0x01f;
3488 *Out
++ = '0' + init
;
3490 *Out
++ = 'A' + init
- 10;
3491 result
= result
>> 5;
3499 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3500 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3505 * Scan a symbol name for a psect attribute specification
3507 #define GLOBALSYMBOL_BIT 0x10000
3508 #define GLOBALVALUE_BIT 0x20000
3512 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3514 int *Attribute_Pointer
;
3525 {"PIC", GPS_S_M_PIC
},
3526 {"LIB", GPS_S_M_LIB
},
3527 {"OVR", GPS_S_M_OVR
},
3528 {"REL", GPS_S_M_REL
},
3529 {"GBL", GPS_S_M_GBL
},
3530 {"SHR", GPS_S_M_SHR
},
3531 {"EXE", GPS_S_M_EXE
},
3533 {"WRT", GPS_S_M_WRT
},
3534 {"VEC", GPS_S_M_VEC
},
3535 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3536 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3546 * Check for a PSECT attribute list
3548 if (!HAS_PSECT_ATTRIBUTES (Name
))
3549 return; /* If not, return */
3551 * Skip the attribute list indicator
3553 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3555 * Process the attributes ("_" separated, "$" terminated)
3557 while (*Name
!= '$')
3560 * Assume not negating
3566 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3569 * We are negating (and skip the NO)
3575 * Find the token delimiter
3578 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3581 * Look for the token in the attribute list
3583 for (i
= 0; Attributes
[i
].Name
; i
++)
3586 * If the strings match, set/clear the attr.
3588 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3594 *Attribute_Pointer
&=
3595 ~Attributes
[i
].Value
;
3597 *Attribute_Pointer
|=
3598 Attributes
[i
].Value
;
3606 * Now skip the attribute
3616 * Define a global symbol
3619 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3627 * We are writing a GSD record
3629 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3631 * If the buffer is empty we must insert the GSD record type
3633 if (Object_Record_Offset
== 0)
3634 PUT_CHAR (OBJ_S_C_GSD
);
3636 * We are writing a Global symbol definition subrecord
3638 if (Psect_Number
<= 255)
3640 PUT_CHAR (GSD_S_C_SYM
);
3644 PUT_CHAR (GSD_S_C_SYMW
);
3647 * Data type is undefined
3651 * Switch on Definition/Reference
3653 if ((Defined
& 1) != 0)
3657 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3658 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3660 if ((Defined
& 2) == 0)
3662 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3666 PUT_SHORT (GSY_S_M_DEF
);
3671 if (Psect_Number
<= 255)
3673 PUT_CHAR (Psect_Number
);
3677 PUT_SHORT (Psect_Number
);
3682 PUT_LONG (Psect_Offset
);
3688 * Flags = "RELOCATABLE" for regular symbol,
3689 * = "" for globalvalue (Defined & 2 == 1)
3691 if ((Defined
& 2) == 0)
3693 PUT_SHORT (GSY_S_M_REL
);
3701 * Finally, the global symbol name
3703 VMS_Case_Hack_Symbol (Name
, Local
);
3704 PUT_COUNTED_STRING (Local
);
3706 * Flush the buffer if it is more than 75% full
3708 if (Object_Record_Offset
>
3709 (sizeof (Object_Record_Buffer
) * 3 / 4))
3710 Flush_VMS_Object_Record_Buffer ();
3718 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3722 struct VMS_Symbol
*vsp
;
3725 int Psect_Attributes
;
3728 * Generate the appropriate PSECT flags given the PSECT type
3730 if (strcmp (Type
, "COMMON") == 0)
3733 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3735 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3736 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3738 else if (strcmp (Type
, "CONST") == 0)
3741 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3743 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3744 GPS_S_M_SHR
| GPS_S_M_RD
);
3746 else if (strcmp (Type
, "DATA") == 0)
3749 * The Data psects are PIC,REL,RD,WRT
3752 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3754 else if (strcmp (Type
, "TEXT") == 0)
3757 * The Text psects are PIC,REL,SHR,EXE,RD
3760 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3761 GPS_S_M_EXE
| GPS_S_M_RD
);
3766 * Error: Unknown psect type
3768 error ("Unknown VMS psect type");
3771 * Modify the psect attributes according to any attribute string
3773 if (HAS_PSECT_ATTRIBUTES (Name
))
3774 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3776 * Check for globalref/def/val.
3778 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3781 * globalvalue symbols were generated before. This code
3782 * prevents unsightly psect buildup, and makes sure that
3783 * fixup references are emitted correctly.
3785 vsp
->Psect_Index
= -1; /* to catch errors */
3786 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3787 return 1; /* decrement psect counter */
3790 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3792 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3794 case N_UNDF
| N_EXT
:
3795 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3796 vsp
->Psect_Offset
, 0);
3797 vsp
->Psect_Index
= -1;
3798 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3799 return 1; /* return and indicate no psect */
3800 case N_DATA
| N_EXT
:
3801 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3802 vsp
->Psect_Offset
, 1);
3803 /* In this case we still generate the psect */
3807 char Error_Line
[256];
3808 sprintf (Error_Line
,
3809 "Globalsymbol attribute for symbol %s was unexpected.\n",
3817 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3819 * We are writing a GSD record
3821 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3823 * If the buffer is empty we must insert the GSD record type
3825 if (Object_Record_Offset
== 0)
3826 PUT_CHAR (OBJ_S_C_GSD
);
3828 * We are writing a PSECT definition subrecord
3830 PUT_CHAR (GSD_S_C_PSC
);
3832 * Psects are always LONGWORD aligned
3836 * Specify the psect attributes
3838 PUT_SHORT (Psect_Attributes
);
3840 * Specify the allocation
3844 * Finally, the psect name
3846 VMS_Case_Hack_Symbol (Name
, Local
);
3847 PUT_COUNTED_STRING (Local
);
3849 * Flush the buffer if it is more than 75% full
3851 if (Object_Record_Offset
>
3852 (sizeof (Object_Record_Buffer
) * 3 / 4))
3853 Flush_VMS_Object_Record_Buffer ();
3859 * Given the pointer to a symbol we calculate how big the data at the
3860 * symbol is. We do this by looking for the next symbol (local or
3861 * global) which will indicate the start of another datum.
3864 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3865 register struct symbol
*sp
;
3868 struct symbol
*sp1
, *Next_Symbol
;
3869 /* Cache values to avoid extra lookups. */
3870 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
;
3873 * Find the next symbol
3874 * it delimits this datum
3877 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3880 * The data type must match
3882 if (S_GET_TYPE (sp1
) != N_DATA
)
3885 sp1_val
= S_GET_VALUE (sp1
);
3888 * The symbol must be AFTER this symbol
3890 if (sp1_val
<= sp_val
)
3893 * We ignore THIS symbol
3898 * If there is already a candidate selected for the
3899 * next symbol, see if we are a better candidate
3904 * We are a better candidate if we are "closer"
3907 if (sp1_val
> next_val
)
3911 * Make this the candidate
3917 * Calculate its size
3919 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
3923 * Check symbol names for the Psect hack with a globalvalue, and then
3924 * generate globalvalues for those that have it.
3927 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3932 register symbolS
*sp
;
3933 char *stripped_name
, *Name
;
3935 int Psect_Attributes
;
3939 * Scan the symbol table for globalvalues, and emit def/ref when
3940 * required. These will be caught again later and converted to
3943 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3946 * See if this is something we want to look at.
3948 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3949 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3952 * See if this has globalvalue specification.
3954 Name
= S_GET_NAME (sp
);
3956 if (!HAS_PSECT_ATTRIBUTES (Name
))
3959 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
3960 strcpy (stripped_name
, Name
);
3961 Psect_Attributes
= 0;
3962 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3964 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3966 switch (S_GET_RAW_TYPE (sp
))
3968 case N_UNDF
| N_EXT
:
3969 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3971 case N_DATA
| N_EXT
:
3972 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3974 error ("Invalid data type for globalvalue");
3975 globalvalue
= md_chars_to_number (Data_Segment
+
3976 S_GET_VALUE (sp
) - text_siz
, Size
);
3977 /* Three times for good luck. The linker seems to get confused
3978 if there are fewer than three */
3979 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3980 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3981 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3984 printf (" Invalid globalvalue of %s\n", stripped_name
);
3988 free (stripped_name
); /* clean up */
3995 * Define a procedure entry pt/mask
3998 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
4007 * We are writing a GSD record
4009 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
4011 * If the buffer is empty we must insert the GSD record type
4013 if (Object_Record_Offset
== 0)
4014 PUT_CHAR (OBJ_S_C_GSD
);
4016 * We are writing a Procedure Entry Pt/Mask subrecord
4018 if (Psect_Number
<= 255)
4020 PUT_CHAR (GSD_S_C_EPM
);
4024 PUT_CHAR (GSD_S_C_EPMW
);
4027 * Data type is undefined
4031 * Flags = "RELOCATABLE" and "DEFINED"
4033 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4037 if (Psect_Number
<= 255)
4039 PUT_CHAR (Psect_Number
);
4043 PUT_SHORT (Psect_Number
);
4048 PUT_LONG (Psect_Offset
);
4052 PUT_SHORT (Entry_Mask
);
4054 * Finally, the global symbol name
4056 VMS_Case_Hack_Symbol (Name
, Local
);
4057 PUT_COUNTED_STRING (Local
);
4059 * Flush the buffer if it is more than 75% full
4061 if (Object_Record_Offset
>
4062 (sizeof (Object_Record_Buffer
) * 3 / 4))
4063 Flush_VMS_Object_Record_Buffer ();
4068 * Set the current location counter to a particular Psect and Offset
4071 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4077 * We are writing a "Record_Type" record
4079 Set_VMS_Object_File_Record (Record_Type
);
4081 * If the buffer is empty we must insert the record type
4083 if (Object_Record_Offset
== 0)
4084 PUT_CHAR (Record_Type
);
4086 * Stack the Psect base + Longword Offset
4088 if (Psect_Index
< 255)
4090 PUT_CHAR (TIR_S_C_STA_PL
);
4091 PUT_CHAR (Psect_Index
);
4095 PUT_CHAR (TIR_S_C_STA_WPL
);
4096 PUT_SHORT (Psect_Index
);
4100 * Set relocation base
4102 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4104 * Flush the buffer if it is more than 75% full
4106 if (Object_Record_Offset
>
4107 (sizeof (Object_Record_Buffer
) * 3 / 4))
4108 Flush_VMS_Object_Record_Buffer ();
4113 * Store repeated immediate data in current Psect
4116 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4118 register char *Pointer
;
4124 * Ignore zero bytes/words/longwords
4126 if ((Size
== sizeof (char)) && (*Pointer
== 0))
4128 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
4130 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
4133 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4134 * then we do it manually
4138 while (--Repeat_Count
>= 0)
4139 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4143 * We are writing a "Record_Type" record
4145 Set_VMS_Object_File_Record (Record_Type
);
4147 * If the buffer is empty we must insert record type
4149 if (Object_Record_Offset
== 0)
4150 PUT_CHAR (Record_Type
);
4152 * Stack the repeat count
4154 PUT_CHAR (TIR_S_C_STA_LW
);
4155 PUT_LONG (Repeat_Count
);
4157 * And now the command and its data
4159 PUT_CHAR (TIR_S_C_STO_RIVB
);
4162 PUT_CHAR (*Pointer
++);
4164 * Flush the buffer if it is more than 75% full
4166 if (Object_Record_Offset
>
4167 (sizeof (Object_Record_Buffer
) * 3 / 4))
4168 Flush_VMS_Object_Record_Buffer ();
4173 * Store a Position Independent Reference
4176 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4177 Psect
, Psect_Offset
, Record_Type
)
4178 struct symbol
*Symbol
;
4185 register struct VMS_Symbol
*vsp
=
4186 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4190 * We are writing a "Record_Type" record
4192 Set_VMS_Object_File_Record (Record_Type
);
4194 * If the buffer is empty we must insert record type
4196 if (Object_Record_Offset
== 0)
4197 PUT_CHAR (Record_Type
);
4199 * Set to the appropriate offset in the Psect
4204 * For a Code reference we need to fix the operand
4205 * specifier as well (so back up 1 byte)
4207 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4212 * For a Data reference we just store HERE
4214 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4217 * Make sure we are still generating a "Record Type" record
4219 if (Object_Record_Offset
== 0)
4220 PUT_CHAR (Record_Type
);
4222 * Dispatch on symbol type (so we can stack its value)
4224 switch (S_GET_RAW_TYPE (Symbol
))
4229 #ifdef NOT_VAX_11_C_COMPATIBLE
4230 case N_UNDF
| N_EXT
:
4231 case N_DATA
| N_EXT
:
4232 #endif /* NOT_VAX_11_C_COMPATIBLE */
4234 case N_TEXT
| N_EXT
:
4236 * Get the symbol name (case hacked)
4238 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4240 * Stack the global symbol value
4242 PUT_CHAR (TIR_S_C_STA_GBL
);
4243 PUT_COUNTED_STRING (Local
);
4247 * Stack the longword offset
4249 PUT_CHAR (TIR_S_C_STA_LW
);
4252 * Add the two, leaving the result on the stack
4254 PUT_CHAR (TIR_S_C_OPR_ADD
);
4258 * Uninitialized local data
4262 * Stack the Psect (+offset)
4264 if (vsp
->Psect_Index
< 255)
4266 PUT_CHAR (TIR_S_C_STA_PL
);
4267 PUT_CHAR (vsp
->Psect_Index
);
4271 PUT_CHAR (TIR_S_C_STA_WPL
);
4272 PUT_SHORT (vsp
->Psect_Index
);
4274 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4281 * Stack the Psect (+offset)
4283 if (vsp
->Psect_Index
< 255)
4285 PUT_CHAR (TIR_S_C_STA_PL
);
4286 PUT_CHAR (vsp
->Psect_Index
);
4290 PUT_CHAR (TIR_S_C_STA_WPL
);
4291 PUT_SHORT (vsp
->Psect_Index
);
4293 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4296 * Initialized local or global data
4299 #ifndef NOT_VAX_11_C_COMPATIBLE
4300 case N_UNDF
| N_EXT
:
4301 case N_DATA
| N_EXT
:
4302 #endif /* NOT_VAX_11_C_COMPATIBLE */
4304 * Stack the Psect (+offset)
4306 if (vsp
->Psect_Index
< 255)
4308 PUT_CHAR (TIR_S_C_STA_PL
);
4309 PUT_CHAR (vsp
->Psect_Index
);
4313 PUT_CHAR (TIR_S_C_STA_WPL
);
4314 PUT_SHORT (vsp
->Psect_Index
);
4316 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4320 * Store either a code or data reference
4322 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4324 * Flush the buffer if it is more than 75% full
4326 if (Object_Record_Offset
>
4327 (sizeof (Object_Record_Buffer
) * 3 / 4))
4328 Flush_VMS_Object_Record_Buffer ();
4333 * Check in the text area for an indirect pc-relative reference
4334 * and fix it up with addressing mode 0xff [PC indirect]
4336 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4337 * PIC CODE GENERATING FIXUP ROUTINE.
4340 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4343 register fragS
*fragP
;
4344 struct frag
*text_frag_root
;
4347 * The addressing mode byte is 1 byte before the address
4351 * Is it in THIS frag??
4353 if ((Offset
< fragP
->fr_address
) ||
4354 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4357 * We need to search for the fragment containing this
4360 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4362 if ((Offset
>= fragP
->fr_address
) &&
4363 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4367 * If we couldn't find the frag, things are BAD!!
4370 error ("Couldn't find fixup fragment when checking for indirect reference");
4373 * Check for indirect PC relative addressing mode
4375 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4377 static char Address_Mode
= 0xff;
4380 * Yes: Store the indirect mode back into the image
4381 * to fix up the damage done by STO_PICR
4383 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4384 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4389 * If the procedure "main()" exists we have to add the instruction
4390 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4392 VMS_Check_For_Main ()
4394 register symbolS
*symbolP
;
4395 #ifdef HACK_DEC_C_STARTUP /* JF */
4396 register struct frchain
*frchainP
;
4397 register fragS
*fragP
;
4398 register fragS
**prev_fragPP
;
4399 register struct fix
*fixP
;
4400 register fragS
*New_Frag
;
4402 #endif /* HACK_DEC_C_STARTUP */
4404 symbolP
= (struct symbol
*) symbol_find ("_main");
4405 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4406 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4408 #ifdef HACK_DEC_C_STARTUP
4409 if (!flag_hash_long_names
)
4413 * Remember the entry point symbol
4415 Entry_Point_Symbol
= symbolP
;
4416 #ifdef HACK_DEC_C_STARTUP
4421 * Scan all the fragment chains for the one with "_main"
4422 * (Actually we know the fragment from the symbol, but we need
4423 * the previous fragment so we can change its pointer)
4425 frchainP
= frchain_root
;
4429 * Scan all the fragments in this chain, remembering
4430 * the "previous fragment"
4432 prev_fragPP
= &frchainP
->frch_root
;
4433 fragP
= frchainP
->frch_root
;
4434 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4437 * Is this the fragment?
4439 if (fragP
== symbolP
->sy_frag
)
4442 * Yes: Modify the fragment by replacing
4443 * it with a new fragment.
4445 New_Frag
= (fragS
*)
4446 xmalloc (sizeof (*New_Frag
) +
4451 * The fragments are the same except
4452 * that the "fixed" area is larger
4455 New_Frag
->fr_fix
+= 6;
4457 * Copy the literal data opening a hole
4458 * 2 bytes after "_main" (i.e. just after
4459 * the entry mask). Into which we place
4460 * the JSB instruction.
4462 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4463 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4464 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4465 New_Frag
->fr_literal
[3] = 0xef;
4466 New_Frag
->fr_literal
[4] = 0;
4467 New_Frag
->fr_literal
[5] = 0;
4468 New_Frag
->fr_literal
[6] = 0;
4469 New_Frag
->fr_literal
[7] = 0;
4470 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4471 New_Frag
->fr_literal
[i
+ 6] =
4472 fragP
->fr_literal
[i
];
4474 * Now replace the old fragment with the
4475 * newly generated one.
4477 *prev_fragPP
= New_Frag
;
4479 * Remember the entry point symbol
4481 Entry_Point_Symbol
= symbolP
;
4483 * Scan the text area fixup structures
4484 * as offsets in the fragment may have
4487 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4490 * Look for references to this
4493 if (fixP
->fx_frag
== fragP
)
4496 * Change the fragment
4499 fixP
->fx_frag
= New_Frag
;
4501 * If the offset is after
4502 * the entry mask we need
4503 * to account for the JSB
4504 * instruction we just
4507 if (fixP
->fx_where
>= 2)
4508 fixP
->fx_where
+= 6;
4512 * Scan the symbols as offsets in the
4513 * fragment may have changed
4515 for (symbolP
= symbol_rootP
;
4517 symbolP
= symbol_next (symbolP
))
4520 * Look for references to this
4523 if (symbolP
->sy_frag
== fragP
)
4526 * Change the fragment
4529 symbolP
->sy_frag
= New_Frag
;
4531 * If the offset is after
4532 * the entry mask we need
4533 * to account for the JSB
4534 * instruction we just
4537 if (S_GET_VALUE (symbolP
) >= 2)
4538 S_SET_VALUE (symbolP
,
4539 S_GET_VALUE (symbolP
) + 6);
4543 * Make a symbol reference to
4544 * "_c$main_args" so we can get
4545 * its address inserted into the
4548 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4549 S_SET_NAME (symbolP
, "_C$MAIN_ARGS");
4550 S_SET_TYPE (symbolP
, N_UNDF
);
4551 S_SET_OTHER (symbolP
, 0);
4552 S_SET_DESC (symbolP
, 0);
4553 S_SET_VALUE (symbolP
, 0);
4554 symbolP
->sy_name_offset
= 0;
4555 symbolP
->sy_number
= 0;
4556 symbolP
->sy_frag
= New_Frag
;
4557 symbolP
->sy_resolved
= 0;
4558 symbolP
->sy_resolving
= 0;
4559 /* this actually inserts at the beginning of the list */
4560 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4562 symbol_rootP
= symbolP
;
4564 * Generate a text fixup structure
4565 * to get "_c$main_args" stored into the
4568 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4569 fixP
->fx_frag
= New_Frag
;
4571 fixP
->fx_addsy
= symbolP
;
4573 fixP
->fx_offset
= 0;
4574 fixP
->fx_size
= sizeof (long);
4576 fixP
->fx_next
= text_fix_root
;
4577 text_fix_root
= fixP
;
4579 * Now make sure we exit from the loop
4585 * Try the next fragment
4587 prev_fragPP
= &fragP
->fr_next
;
4588 fragP
= fragP
->fr_next
;
4591 * Try the next fragment chain
4594 frchainP
= frchainP
->frch_next
;
4597 #endif /* HACK_DEC_C_STARTUP */
4602 * Write a VAX/VMS object file (everything else has been done!)
4604 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4609 struct frag
*text_frag_root
;
4610 struct frag
*data_frag_root
;
4612 register fragS
*fragP
;
4613 register symbolS
*symbolP
;
4614 register symbolS
*sp
;
4615 register struct fix
*fixP
;
4616 register struct VMS_Symbol
*vsp
;
4618 int Local_Initialized_Data_Size
= 0;
4620 int Psect_Number
= 0; /* Psect Index Number */
4621 int Text_Psect
= -1; /* Text Psect Index */
4622 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4623 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4626 * Create the VMS object file
4628 Create_VMS_Object_File ();
4630 * Write the module header records
4632 Write_VMS_MHD_Records ();
4635 * Store the Data segment:
4637 * Since this is REALLY hard to do any other way,
4638 * we actually manufacture the data segment and
4639 * the store the appropriate values out of it.
4640 * We need to generate this early, so that globalvalues
4641 * can be properly emitted.
4646 * Allocate the data segment
4648 Data_Segment
= (char *) xmalloc (data_siz
);
4650 * Run through the data fragments, filling in the segment
4652 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4654 register long int count
;
4655 register char *fill_literal
;
4656 register long int fill_size
;
4659 i
= fragP
->fr_address
- text_siz
;
4661 memcpy (Data_Segment
+ i
,
4666 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4667 fill_size
= fragP
->fr_var
;
4668 for (count
= fragP
->fr_offset
; count
; count
--)
4671 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4679 * Generate the VMS object file records
4680 * 1st GSD then TIR records
4683 /******* Global Symbol Dictionary *******/
4685 * Emit globalvalues now. We must do this before the text psect
4686 * is defined, or we will get linker warnings about multiply defined
4687 * symbols. All of the globalvalues "reference" psect 0, although
4688 * it really does not have anything to do with it.
4690 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4692 * Define the Text Psect
4694 Text_Psect
= Psect_Number
++;
4695 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4697 * Define the BSS Psect
4701 Bss_Psect
= Psect_Number
++;
4702 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4704 #ifndef gxx_bug_fixed
4706 * The g++ compiler does not write out external references to vtables
4707 * correctly. Check for this and holler if we see it happening.
4708 * If that compiler bug is ever fixed we can remove this.
4710 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4713 * Dispatch on symbol type
4715 switch (S_GET_RAW_TYPE (sp
)) {
4721 * Make a GSD global symbol reference
4724 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4726 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4727 S_SET_OTHER (sp
, 1);
4728 /* Is this warning still needed? It sounds like it describes
4729 a compiler bug. Does it? If not, let's dump it. */
4730 as_warn("g++ wrote an extern reference to %s as a routine.",
4732 as_warn("I will fix it, but I hope that it was not really a routine");
4739 #endif /* gxx_bug_fixed */
4741 * Now scan the symbols and emit the appropriate GSD records
4743 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4746 * Dispatch on symbol type
4748 switch (S_GET_RAW_TYPE (sp
))
4751 * Global uninitialized data
4753 case N_UNDF
| N_EXT
:
4755 * Make a VMS data symbol entry
4757 vsp
= (struct VMS_Symbol
*)
4758 xmalloc (sizeof (*vsp
));
4760 vsp
->Size
= S_GET_VALUE (sp
);
4761 vsp
->Psect_Index
= Psect_Number
++;
4762 vsp
->Psect_Offset
= 0;
4763 vsp
->Next
= VMS_Symbols
;
4765 sp
->sy_number
= (int) vsp
;
4767 * Make the psect for this data
4769 Globalref
= VMS_Psect_Spec (
4772 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
4777 /* See if this is an external vtable. We want to help the linker find
4778 these things in libraries, so we make a symbol reference. This
4779 is not compatible with VAX-C usage for variables, but since vtables are
4780 only used internally by g++, we can get away with this hack. */
4782 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4783 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4788 #ifdef NOT_VAX_11_C_COMPATIBLE
4790 * Place a global symbol at the
4791 * beginning of the Psect
4793 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4797 #endif /* NOT_VAX_11_C_COMPATIBLE */
4800 * Local uninitialized data
4804 * Make a VMS data symbol entry
4806 vsp
= (struct VMS_Symbol
*)
4807 xmalloc (sizeof (*vsp
));
4810 vsp
->Psect_Index
= Bss_Psect
;
4813 bss_address_frag
.fr_address
;
4814 vsp
->Next
= VMS_Symbols
;
4816 sp
->sy_number
= (int) vsp
;
4819 * Global initialized data
4821 case N_DATA
| N_EXT
:
4823 * Make a VMS data symbol entry
4825 vsp
= (struct VMS_Symbol
*)
4826 xmalloc (sizeof (*vsp
));
4828 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4829 text_siz
+ data_siz
);
4830 vsp
->Psect_Index
= Psect_Number
++;
4831 vsp
->Psect_Offset
= 0;
4832 vsp
->Next
= VMS_Symbols
;
4834 sp
->sy_number
= (int) vsp
;
4838 Globalref
= VMS_Psect_Spec (
4841 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
4846 /* See if this is an external vtable. We want to help the linker find
4847 these things in libraries, so we make a symbol definition. This
4848 is not compatible with VAX-C usage for variables, but since vtables are
4849 only used internally by g++, we can get away with this hack. */
4851 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4852 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4857 #ifdef NOT_VAX_11_C_COMPATIBLE
4859 * Place a global symbol at the
4860 * beginning of the Psect
4862 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4866 #endif /* NOT_VAX_11_C_COMPATIBLE */
4869 * Local initialized data
4873 * Make a VMS data symbol entry
4875 vsp
= (struct VMS_Symbol
*)
4876 xmalloc (sizeof (*vsp
));
4879 VMS_Initialized_Data_Size (sp
,
4880 text_siz
+ data_siz
);
4881 vsp
->Psect_Index
= Data_Psect
;
4883 Local_Initialized_Data_Size
;
4884 Local_Initialized_Data_Size
+= vsp
->Size
;
4885 vsp
->Next
= VMS_Symbols
;
4887 sp
->sy_number
= (int) vsp
;
4890 * Global Text definition
4892 case N_TEXT
| N_EXT
:
4894 unsigned short Entry_Mask
;
4897 * Get the entry mask
4899 fragP
= sp
->sy_frag
;
4901 /* If first frag doesn't contain the data, what do we do?
4902 If it's possibly smaller than two bytes, that would
4903 imply that the entry mask is not stored where we're
4906 If you can find a test case that triggers this, report
4907 it (and tell me what the entry mask field ought to be),
4908 and I'll try to fix it. KR */
4909 /* First frag might be empty if we're generating listings.
4910 So skip empty rs_fill frags. */
4911 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
4912 fragP
= fragP
->fr_next
;
4914 if (fragP
->fr_fix
< 2)
4917 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4918 ((fragP
->fr_literal
[1] & 0xff)
4921 * Define the Procedure entry pt.
4923 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4930 * Local Text definition
4934 * Make a VMS data symbol entry
4936 if (Text_Psect
!= -1)
4938 vsp
= (struct VMS_Symbol
*)
4939 xmalloc (sizeof (*vsp
));
4942 vsp
->Psect_Index
= Text_Psect
;
4943 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4944 vsp
->Next
= VMS_Symbols
;
4946 sp
->sy_number
= (int) vsp
;
4954 * Make a GSD global symbol reference
4957 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4967 * Ignore STAB symbols
4968 * Including .stabs emitted by g++
4970 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4975 if (S_GET_TYPE (sp
) != 22)
4976 printf (" ERROR, unknown type (%d)\n",
4982 * Define the Data Psect
4984 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4989 Data_Psect
= Psect_Number
++;
4990 VMS_Psect_Spec ("$data",
4991 Local_Initialized_Data_Size
,
4994 * Scan the VMS symbols and fill in the data psect
4996 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4999 * Only look for undefined psects
5001 if (vsp
->Psect_Index
< 0)
5004 * And only initialized data
5006 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
5007 vsp
->Psect_Index
= Data_Psect
;
5012 /******* Text Information and Relocation Records *******/
5014 * Write the text segment data
5019 * Scan the text fragments
5021 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
5024 * Stop if we get to the data fragments
5026 if (fragP
== data_frag_root
)
5029 * Ignore fragments with no data
5031 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5034 * Go the the appropriate offset in the
5037 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5039 * Store the "fixed" part
5042 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5046 * Store the "variable" part
5048 if (fragP
->fr_var
&& fragP
->fr_offset
)
5049 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5056 * Now we go through the text segment fixups and
5057 * generate TIR records to fix up addresses within
5060 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5063 * We DO handle the case of "Symbol - Symbol" as
5064 * long as it is in the same segment.
5066 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5071 * They need to be in the same segment
5073 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5074 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5075 error ("Fixup data addsy and subsy didn't have the same type");
5077 * And they need to be in one that we
5078 * can check the psect on
5080 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5081 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5082 error ("Fixup data addsy and subsy didn't have an appropriate type");
5084 * This had better not be PC relative!
5087 error ("Fixup data was erroneously \"pcrel\"");
5089 * Subtract their values to get the
5092 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5093 S_GET_VALUE (fixP
->fx_subsy
);
5095 * Now generate the fixup object records
5096 * Set the psect and store the data
5098 VMS_Set_Psect (Text_Psect
,
5100 fixP
->fx_frag
->fr_address
,
5102 VMS_Store_Immediate_Data (&i
,
5111 * Size will HAVE to be "long"
5113 if (fixP
->fx_size
!= sizeof (long))
5114 error ("Fixup datum was not a longword");
5116 * Symbol must be "added" (if it is ever
5118 * fix this assumption)
5120 if (fixP
->fx_addsy
== 0)
5121 error ("Fixup datum was not \"fixP->fx_addsy\"");
5123 * Store the symbol value in a PIC fashion
5125 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5130 fixP
->fx_frag
->fr_address
,
5133 * Check for indirect address reference,
5134 * which has to be fixed up (as the linker
5135 * will screw it up with TIR_S_C_STO_PICR).
5138 VMS_Fix_Indirect_Reference (Text_Psect
,
5140 fixP
->fx_frag
->fr_address
,
5146 * Store the Data segment:
5148 * Since this is REALLY hard to do any other way,
5149 * we actually manufacture the data segment and
5150 * the store the appropriate values out of it.
5151 * The segment was manufactured before, now we just
5152 * dump it into the appropriate psects.
5158 * Now we can run through all the data symbols
5159 * and store the data
5161 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5164 * Ignore anything other than data symbols
5166 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5169 * Set the Psect + Offset
5171 VMS_Set_Psect (vsp
->Psect_Index
,
5177 VMS_Store_Immediate_Data (Data_Segment
+
5178 S_GET_VALUE (vsp
->Symbol
) -
5184 * Now we go through the data segment fixups and
5185 * generate TIR records to fix up addresses within
5188 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5191 * Find the symbol for the containing datum
5193 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5196 * Only bother with Data symbols
5199 if (S_GET_TYPE (sp
) != N_DATA
)
5202 * Ignore symbol if After fixup
5204 if (S_GET_VALUE (sp
) >
5206 fixP
->fx_frag
->fr_address
))
5209 * See if the datum is here
5211 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5213 fixP
->fx_frag
->fr_address
))
5216 * We DO handle the case of "Symbol - Symbol" as
5217 * long as it is in the same segment.
5219 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5224 * They need to be in the same segment
5226 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5227 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5228 error ("Fixup data addsy and subsy didn't have the same type");
5230 * And they need to be in one that we
5231 * can check the psect on
5233 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5234 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5235 error ("Fixup data addsy and subsy didn't have an appropriate type");
5237 * This had better not be PC relative!
5240 error ("Fixup data was erroneously \"pcrel\"");
5242 * Subtract their values to get the
5245 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5246 S_GET_VALUE (fixP
->fx_subsy
);
5248 * Now generate the fixup object records
5249 * Set the psect and store the data
5251 VMS_Set_Psect (vsp
->Psect_Index
,
5252 fixP
->fx_frag
->fr_address
+
5254 S_GET_VALUE (vsp
->Symbol
) +
5257 VMS_Store_Immediate_Data (&i
,
5266 * Size will HAVE to be "long"
5268 if (fixP
->fx_size
!= sizeof (long))
5269 error ("Fixup datum was not a longword");
5271 * Symbol must be "added" (if it is ever
5273 * fix this assumption)
5275 if (fixP
->fx_addsy
== 0)
5276 error ("Fixup datum was not \"fixP->fx_addsy\"");
5278 * Store the symbol value in a PIC fashion
5280 VMS_Store_PIC_Symbol_Reference (
5285 fixP
->fx_frag
->fr_address
+
5287 S_GET_VALUE (vsp
->Symbol
) +
5300 * Write the Traceback Begin Module record
5302 VMS_TBT_Module_Begin ();
5304 * Scan the symbols and write out the routines
5305 * (this makes the assumption that symbols are in
5306 * order of ascending text segment offset)
5309 struct symbol
*Current_Routine
= 0;
5310 int Current_Line_Number
= 0;
5311 int Current_Offset
= -1;
5312 struct input_file
*Current_File
;
5314 /* Output debugging info for global variables and static variables that are not
5315 * specific to one routine. We also need to examine all stabs directives, to
5316 * find the definitions to all of the advanced data types, and this is done by
5317 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5318 * the object file, since there can be forward references in the stabs
5319 * directives. When through with parsing, the text of the stabs directive
5320 * is altered, with the definitions removed, so that later passes will see
5321 * directives as they would be written if the type were already defined.
5323 * We also look for files and include files, and make a list of them. We
5324 * examine the source file numbers to establish the actual lines that code was
5325 * generated from, and then generate offsets.
5328 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5331 * Deal with STAB symbols
5333 if (S_IS_DEBUG (symbolP
))
5336 * Dispatch on STAB type
5338 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5341 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5342 Current_File
->max_line
= S_GET_DESC (symbolP
);
5343 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5344 Current_File
->min_line
= S_GET_DESC (symbolP
);
5347 Current_File
= find_file (symbolP
);
5348 Current_File
->flag
= 1;
5349 Current_File
->min_line
= 1;
5352 Current_File
= find_file (symbolP
);
5355 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5358 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5360 case N_FUN
: /* For static constant symbols */
5362 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5368 /* now we take a quick sweep through the files and assign offsets
5369 to each one. This will essentially be the starting line number to the
5370 debugger for each file. Output the info for the debugger to specify the
5371 files, and then tell it how many lines to use */
5373 int File_Number
= 0;
5374 int Debugger_Offset
= 0;
5376 Current_File
= file_root
;
5377 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5379 if (Current_File
== (struct input_file
*) NULL
)
5381 if (Current_File
->max_line
== 0)
5383 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5386 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5389 /* show a few extra lines at the start of the region selected */
5390 if (Current_File
->min_line
> 2)
5391 Current_File
->min_line
-= 2;
5392 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5393 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5394 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5395 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5398 Current_File
->file_number
= ++File_Number
;
5399 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5400 Current_File
->file_number
);
5401 if (!file_available
)
5403 Current_File
->file_number
= 0;
5408 VMS_TBT_Source_Lines (Current_File
->file_number
,
5409 Current_File
->min_line
,
5410 Current_File
->max_line
- Current_File
->min_line
+ 1);
5413 Current_File
= (struct input_file
*) NULL
;
5415 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5418 * Deal with text symbols
5420 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5423 * Ignore symbols starting with "L",
5424 * as they are local symbols
5426 if (*S_GET_NAME (symbolP
) == 'L')
5429 * If there is a routine start defined,
5432 if (Current_Routine
)
5437 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5440 * Check for & skip dummy labels like "gcc_compiled.".
5441 * They're identified by the IN_DEFAULT_SECTION flag.
5443 if ((S_GET_OTHER (symbolP
) & IN_DEFAULT_SECTION
) != 0 &&
5444 (S_GET_VALUE (symbolP
) == 0))
5447 * Store the routine begin traceback info
5449 if (Text_Psect
!= -1)
5451 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5452 Current_Routine
= symbolP
;
5454 /* Output local symbols, i.e. all symbols that are associated with a specific
5455 * routine. We output them now so the debugger recognizes them as local to
5462 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5464 if (!S_IS_DEBUG (symbolP1
))
5466 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5468 pnt
= S_GET_NAME (symbolP
);
5469 pnt1
= S_GET_NAME (symbolP1
);
5472 while (*pnt
++ == *pnt1
++)
5475 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5476 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5479 if (symbolP1
!= (symbolS
*) NULL
)
5480 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5481 } /* local symbol block */
5488 * Deal with STAB symbols
5490 if (S_IS_DEBUG (symbolP
))
5493 * Dispatch on STAB type
5495 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5501 /* Offset the line into the correct portion
5503 if (Current_File
->file_number
== 0)
5505 /* Sometimes the same offset gets several source
5506 * lines assigned to it.
5507 * We should be selective about which lines
5508 * we allow, we should prefer lines that are
5509 * in the main source file when debugging
5510 * inline functions. */
5511 if ((Current_File
->file_number
!= 1) &&
5512 S_GET_VALUE (symbolP
) ==
5515 /* calculate actual debugger source line */
5516 S_GET_DESC (symbolP
)
5517 += Current_File
->offset
;
5519 * If this is the 1st N_SLINE, setup
5520 * PC/Line correlation. Otherwise
5521 * do the delta PC/Line. If the offset
5522 * for the line number is not +ve we need
5523 * to do another PC/Line correlation
5526 if (Current_Offset
== -1)
5528 VMS_TBT_Line_PC_Correlation (
5529 S_GET_DESC (symbolP
),
5530 S_GET_VALUE (symbolP
),
5536 if ((S_GET_DESC (symbolP
) -
5537 Current_Line_Number
) <= 0)
5540 * Line delta is not +ve, we
5541 * need to close the line and
5542 * start a new PC/Line
5545 VMS_TBT_Line_PC_Correlation (0,
5546 S_GET_VALUE (symbolP
) -
5550 VMS_TBT_Line_PC_Correlation (
5551 S_GET_DESC (symbolP
),
5552 S_GET_VALUE (symbolP
),
5559 * Line delta is +ve, all is well
5561 VMS_TBT_Line_PC_Correlation (
5562 S_GET_DESC (symbolP
) -
5563 Current_Line_Number
,
5564 S_GET_VALUE (symbolP
) -
5571 * Update the current line/PC
5573 Current_Line_Number
= S_GET_DESC (symbolP
);
5574 Current_Offset
= S_GET_VALUE (symbolP
);
5584 * Remember that we had a source file
5585 * and emit the source file debugger
5589 find_file (symbolP
);
5591 /* We need to make sure that we are really in the actual source file when
5592 * we compute the maximum line number. Otherwise the debugger gets really
5596 find_file (symbolP
);
5602 * If there is a routine start defined,
5603 * terminate it (and the line numbers)
5605 if (Current_Routine
)
5608 * Terminate the line numbers
5610 VMS_TBT_Line_PC_Correlation (0,
5611 text_siz
- S_GET_VALUE (Current_Routine
),
5615 * Terminate the routine
5617 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5621 * Write the Traceback End Module TBT record
5623 VMS_TBT_Module_End ();
5626 * Write the End Of Module record
5628 if (Entry_Point_Symbol
== 0)
5629 Write_VMS_EOM_Record (-1, 0);
5631 Write_VMS_EOM_Record (Text_Psect
,
5632 S_GET_VALUE (Entry_Point_Symbol
));
5635 * All done, close the object file
5637 Close_VMS_Object_File ();
5640 /* end of obj-vms.c */