1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
28 /* What we do if there is a goof. */
29 #define error as_fatal
31 #ifdef 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
;
196 * Variable descriptors are used tell the debugger the data types of certain
197 * more complicated variables (basically anything involving a structure,
198 * union, enum, array or pointer). Some non-pointer variables of the
199 * basic types that the debugger knows about do not require a variable
202 * Since it is impossible to have a variable descriptor longer than 128
203 * bytes by virtue of the way that the VMS object language is set up,
204 * it makes not sense to make the arrays any longer than this, or worrying
205 * about dynamic sizing of the array.
207 * These are the arrays and counters that we use to build a variable
211 #define MAX_DEBUG_RECORD 128
212 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
213 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
214 static int Lpnt
; /* index into Local */
215 static int Apoint
; /* index into Asuffix */
216 static char overflow
; /* flag to indicate we have written too much*/
217 static int total_len
; /* used to calculate the total length of variable
218 descriptor plus array descriptor - used for len byte*/
220 /* Flag if we have told user about finding global constants in the text
222 static gave_compiler_message
= 0;
224 /* A pointer to the current routine that we are working on. */
226 static symbolS
*Current_Routine
;
228 /* The psect number for $code a.k.a. the text section. */
230 static int Text_Psect
;
234 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
236 static int VMS_Object_File_FD
; /* File Descriptor for object file */
237 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
238 static int Object_Record_Offset
;/* Offset to end of data */
239 static int Current_Object_Record_Type
; /* Type of record in above */
242 * Macros for moving data around. Must work on big-endian systems.
244 #ifdef VMS /* These are more efficient for VMS->VMS systems */
245 #define COPY_LONG(dest,val) {*(long *) dest = val; }
246 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
248 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
249 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
252 * Macros for placing data into the object record buffer
255 #define PUT_LONG(val) \
256 { md_number_to_chars(Object_Record_Buffer + \
257 Object_Record_Offset, val, 4); \
258 Object_Record_Offset += 4; }
260 #define PUT_SHORT(val) \
261 { md_number_to_chars(Object_Record_Buffer + \
262 Object_Record_Offset, val, 2); \
263 Object_Record_Offset += 2; }
265 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
267 #define PUT_COUNTED_STRING(cp) {\
268 register char *p = cp; \
269 PUT_CHAR(strlen(p)); \
270 while (*p) PUT_CHAR(*p++);}
273 * Macro for determining if a Name has psect attributes attached
276 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
277 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
279 #define HAS_PSECT_ATTRIBUTES(Name) \
280 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
281 PSECT_ATTRIBUTES_STRING, \
282 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
285 /* in: segT out: N_TYPE bits */
286 const short seg_N_TYPE
[] =
292 N_UNDF
, /* unknown */
294 N_UNDF
, /* expression */
298 N_REGISTER
, /* register */
301 const segT N_TYPE_seg
[N_TYPE
+ 2] =
302 { /* N_TYPE == 0x1E = 32-2 */
303 SEG_UNKNOWN
, /* N_UNDF == 0 */
305 SEG_ABSOLUTE
, /* N_ABS == 2 */
307 SEG_TEXT
, /* N_TEXT == 4 */
309 SEG_DATA
, /* N_DATA == 6 */
311 SEG_BSS
, /* N_BSS == 8 */
313 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
314 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
315 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
316 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
321 /* The following code defines the special types of pseudo-ops that we
332 temp
= get_absolute_expression ();
333 subseg_set (SEG_DATA
, (subsegT
) temp
);
335 demand_empty_rest_of_line ();
338 const pseudo_typeS obj_pseudo_table
[] =
340 {"const", s_const
, 0},
342 }; /* obj_pseudo_table */
345 vms_resolve_symbol_redef (sym
)
349 * If the new symbol is .comm AND it has a size of zero,
350 * we ignore it (i.e. the old symbol overrides it)
352 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)) &&
353 ((obstack_next_free (&frags
) - frag_now
->fr_literal
) == 0))
355 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
360 * If the old symbol is .comm and it has a size of zero,
361 * we override it with the new symbol value.
363 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
364 && (S_GET_VALUE(sym
) == 0))
366 as_warn ("compiler redefined zero-size common symbol `%s'",
368 sym
->sy_frag
= frag_now
;
369 S_GET_OTHER(sym
) = const_flag
;
370 S_SET_VALUE(sym
, obstack_next_free(& frags
) - frag_now
->fr_literal
);
371 /* Keep N_EXT bit. */
372 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
381 obj_read_begin_hook ()
386 obj_crawl_symbol_chain (headers
)
387 object_headers
*headers
;
391 int symbol_number
= 0;
393 { /* crawl symbol table */
394 register int symbol_number
= 0;
397 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
398 while ((symbolP
= *symbolPP
) != NULL
)
400 resolve_symbol_value (symbolP
);
402 /* OK, here is how we decide which symbols go out into the
403 brave new symtab. Symbols that do are:
405 * symbols with no name (stabd's?)
406 * symbols with debug info in their N_TYPE
408 Symbols that don't are:
409 * symbols that are registers
410 * symbols with \1 as their 3rd character (numeric labels)
411 * "local labels" as defined by S_LOCAL_NAME(name)
412 if the -L switch was passed to gas.
414 All other symbols are output. We complain if a deleted
415 symbol was marked external. */
418 if (!S_IS_REGISTER (symbolP
))
420 symbolP
->sy_name_offset
= 0;
421 symbolPP
= &(symbol_next (symbolP
));
425 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
427 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
430 } /* if this symbol should be in the output */
431 } /* for each symbol */
433 H_SET_STRING_SIZE (headers
, string_byte_count
);
434 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
435 } /* crawl symbol table */
437 } /* obj_crawl_symbol_chain() */
440 /****** VMS OBJECT FILE HACKING ROUTINES *******/
444 * Create the VMS object file
447 Create_VMS_Object_File ()
449 #if defined(eunice) || !defined(VMS)
450 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
452 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
453 "mbc=16", "deq=64", "fop=tef", "shr=nil");
458 if (VMS_Object_File_FD
< 0)
460 char Error_Line
[256];
462 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
467 * Initialize object file hacking variables
469 Object_Record_Offset
= 0;
470 Current_Object_Record_Type
= -1;
475 * Flush the object record buffer to the object file
478 Flush_VMS_Object_Record_Buffer ()
484 * If the buffer is empty, we are done
486 if (Object_Record_Offset
== 0)
489 * Write the data to the file
491 #ifndef VMS /* For cross-assembly purposes. */
492 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
493 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
495 i
= write (VMS_Object_File_FD
,
496 Object_Record_Buffer
,
497 Object_Record_Offset
);
498 if (i
!= Object_Record_Offset
)
499 error ("I/O error writing VMS object file");
500 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
502 /* pad it if needed */
504 if (Object_Record_Offset
& 1 != 0)
505 write (VMS_Object_File_FD
, &zero
, 1);
508 * The buffer is now empty
510 Object_Record_Offset
= 0;
515 * Declare a particular type of object file record
518 Set_VMS_Object_File_Record (Type
)
522 * If the type matches, we are done
524 if (Type
== Current_Object_Record_Type
)
527 * Otherwise: flush the buffer
529 Flush_VMS_Object_Record_Buffer ();
533 Current_Object_Record_Type
= Type
;
539 * Close the VMS Object file
542 Close_VMS_Object_File ()
544 short int m_one
= -1;
545 /* @@ This should not be here!! The same would presumably be needed
546 if we were writing vax-bsd a.out files on a vms system. Put it
548 #ifndef VMS /* For cross-assembly purposes. */
549 /* Write a 0xffff into the file, which means "End of File" */
550 write (VMS_Object_File_FD
, &m_one
, 2);
552 close (VMS_Object_File_FD
);
557 * Store immediate data in current Psect
560 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
568 * We are writing a "Record_Type" record
570 Set_VMS_Object_File_Record (Record_Type
);
572 * We can only store 128 bytes at a time
577 * Store a maximum of 128 bytes
579 i
= (Size
> 128) ? 128 : Size
;
582 * If we cannot accommodate this record, flush the
585 if ((Object_Record_Offset
+ i
+ 1) >=
586 sizeof (Object_Record_Buffer
))
587 Flush_VMS_Object_Record_Buffer ();
589 * If the buffer is empty we must insert record type
591 if (Object_Record_Offset
== 0)
592 PUT_CHAR (Record_Type
);
596 PUT_CHAR (-i
& 0xff);
601 PUT_CHAR (*Pointer
++);
603 * Flush the buffer if it is more than 75% full
605 if (Object_Record_Offset
>
606 (sizeof (Object_Record_Buffer
) * 3 / 4))
607 Flush_VMS_Object_Record_Buffer ();
612 * Make a data reference
615 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
622 * We are writing a "Record_Type" record
624 Set_VMS_Object_File_Record (Record_Type
);
626 * If the buffer is empty we must insert the record type
628 if (Object_Record_Offset
== 0)
629 PUT_CHAR (Record_Type
);
631 * Stack the Psect base + Longword Offset
635 if (Psect_Index
> 127)
637 PUT_CHAR (TIR_S_C_STA_WPL
);
638 PUT_SHORT (Psect_Index
);
643 PUT_CHAR (TIR_S_C_STA_PL
);
644 PUT_CHAR (Psect_Index
);
652 PUT_CHAR (TIR_S_C_STA_WPL
);
653 PUT_SHORT (Psect_Index
);
656 else if (Offset
> 127)
658 PUT_CHAR (TIR_S_C_STA_WPW
);
659 PUT_SHORT (Psect_Index
);
664 PUT_CHAR (TIR_S_C_STA_WPB
);
665 PUT_SHORT (Psect_Index
);
670 * Set relocation base
672 PUT_CHAR (TIR_S_C_STO_PIDR
);
674 * Flush the buffer if it is more than 75% full
676 if (Object_Record_Offset
>
677 (sizeof (Object_Record_Buffer
) * 3 / 4))
678 Flush_VMS_Object_Record_Buffer ();
682 * Make a debugger reference to a struct, union or enum.
685 VMS_Store_Struct (Struct_Index
)
689 * We are writing a "OBJ_S_C_DBG" record
691 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
693 * If the buffer is empty we must insert the record type
695 if (Object_Record_Offset
== 0)
696 PUT_CHAR (OBJ_S_C_DBG
);
697 PUT_CHAR (TIR_S_C_STA_UW
);
698 PUT_SHORT (Struct_Index
);
699 PUT_CHAR (TIR_S_C_CTL_STKDL
);
700 PUT_CHAR (TIR_S_C_STO_L
);
702 * Flush the buffer if it is more than 75% full
704 if (Object_Record_Offset
>
705 (sizeof (Object_Record_Buffer
) * 3 / 4))
706 Flush_VMS_Object_Record_Buffer ();
710 * Make a debugger reference to partially define a struct, union or enum.
713 VMS_Def_Struct (Struct_Index
)
717 * We are writing a "OBJ_S_C_DBG" record
719 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
721 * If the buffer is empty we must insert the record type
723 if (Object_Record_Offset
== 0)
724 PUT_CHAR (OBJ_S_C_DBG
);
725 PUT_CHAR (TIR_S_C_STA_UW
);
726 PUT_SHORT (Struct_Index
);
727 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
729 * Flush the buffer if it is more than 75% full
731 if (Object_Record_Offset
>
732 (sizeof (Object_Record_Buffer
) * 3 / 4))
733 Flush_VMS_Object_Record_Buffer ();
737 VMS_Set_Struct (Struct_Index
)
739 { /* see previous functions for comments */
740 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
741 if (Object_Record_Offset
== 0)
742 PUT_CHAR (OBJ_S_C_DBG
);
743 PUT_CHAR (TIR_S_C_STA_UW
);
744 PUT_SHORT (Struct_Index
);
745 PUT_CHAR (TIR_S_C_CTL_STLOC
);
746 if (Object_Record_Offset
>
747 (sizeof (Object_Record_Buffer
) * 3 / 4))
748 Flush_VMS_Object_Record_Buffer ();
752 * Write the Traceback Module Begin record
755 VMS_TBT_Module_Begin ()
757 register char *cp
, *cp1
;
759 char Module_Name
[256];
763 * Get module name (the FILENAME part of the object file)
769 if ((*cp
== ']') || (*cp
== '>') ||
770 (*cp
== ':') || (*cp
== '/'))
776 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
780 * Limit it to 31 characters
782 while (--cp1
>= Module_Name
)
785 if (strlen (Module_Name
) > 31)
787 if (flag_hash_long_names
)
788 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
792 * Arrange to store the data locally (leave room for size byte)
798 *cp
++ = DST_S_C_MODBEG
;
804 * Language type == "C"
806 COPY_LONG (cp
, DST_S_C_C
);
809 * Store the module name
811 *cp
++ = strlen (Module_Name
);
816 * Now we can store the record size
821 * Put it into the object record
823 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
828 * Write the Traceback Module End record
831 VMS_TBT_Module_End ()
839 Local
[1] = DST_S_C_MODEND
;
841 * Put it into the object record
843 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
848 * Write the Traceback Routine Begin record
851 VMS_TBT_Routine_Begin (symbolP
, Psect
)
852 struct symbol
*symbolP
;
855 register char *cp
, *cp1
;
862 * Strip the leading "_" from the name
864 Name
= S_GET_NAME (symbolP
);
868 * Get the text psect offset
870 Offset
= S_GET_VALUE (symbolP
);
872 * Calculate the record size
874 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
882 Local
[1] = DST_S_C_RTNBEG
;
888 * Store the data so far
890 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
892 * Make sure we are still generating a OBJ_S_C_TBT record
894 if (Object_Record_Offset
== 0)
895 PUT_CHAR (OBJ_S_C_TBT
);
897 * Now get the symbol address
899 PUT_CHAR (TIR_S_C_STA_WPL
);
903 * Store the data reference
905 PUT_CHAR (TIR_S_C_STO_PIDR
);
907 * Store the counted string as data
911 Size
= strlen (cp1
) + 1;
915 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
920 * Write the Traceback Routine End record
921 * We *must* search the symbol table to find the next routine, since
922 * the assember has a way of reassembling the symbol table OUT OF ORDER
923 * Thus the next routine in the symbol list is not necessarily the
924 * next one in memory. For debugging to work correctly we must know the
925 * size of the routine.
928 VMS_TBT_Routine_End (Max_Size
, sp
)
933 int Size
= 0x7fffffff;
937 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
939 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
941 if (*S_GET_NAME (symbolP
) == 'L')
943 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
944 (S_GET_VALUE (symbolP
) < Size
))
945 Size
= S_GET_VALUE (symbolP
);
946 /* check if gcc_compiled. has size of zero */
947 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
949 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
950 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
951 Size
= S_GET_VALUE (symbolP
);
955 if (Size
== 0x7fffffff)
957 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
965 Local
[1] = DST_S_C_RTNEND
;
973 COPY_LONG (&Local
[3], Size
);
977 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
981 * Write the Traceback Block End record
984 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
985 struct symbol
*symbolP
;
989 register char *cp
, *cp1
;
996 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1002 * Begin Block - We simulate with a phony routine
1004 Local
[1] = DST_S_C_BLKBEG
;
1010 * Store the data so far
1012 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1014 * Make sure we are still generating a OBJ_S_C_DBG record
1016 if (Object_Record_Offset
== 0)
1017 PUT_CHAR (OBJ_S_C_DBG
);
1019 * Now get the symbol address
1021 PUT_CHAR (TIR_S_C_STA_WPL
);
1024 * Get the text psect offset
1026 Offset
= S_GET_VALUE (symbolP
);
1029 * Store the data reference
1031 PUT_CHAR (TIR_S_C_STO_PIDR
);
1033 * Store the counted string as data
1037 Size
= strlen (cp1
) + 1;
1041 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1046 * Write the Traceback Block End record
1049 VMS_TBT_Block_End (Size
)
1055 * End block - simulate with a phony end routine
1058 Local
[1] = DST_S_C_BLKEND
;
1059 COPY_LONG (&Local
[3], Size
);
1064 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1070 * Write a Line number / PC correlation record
1073 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1083 * If not delta, set our PC/Line number correlation
1090 Local
[0] = 1 + 1 + 2 + 1 + 4;
1092 * Line Number/PC correlation
1094 Local
[1] = DST_S_C_LINE_NUM
;
1098 Local
[2] = DST_S_C_SET_LINE_NUM
;
1099 COPY_SHORT (&Local
[3], Line_Number
- 1);
1103 Local
[5] = DST_S_C_SET_ABS_PC
;
1104 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1106 * Make sure we are still generating a OBJ_S_C_TBT record
1108 if (Object_Record_Offset
== 0)
1109 PUT_CHAR (OBJ_S_C_TBT
);
1112 PUT_CHAR (TIR_S_C_STA_PL
);
1117 PUT_CHAR (TIR_S_C_STA_WPL
);
1121 PUT_CHAR (TIR_S_C_STO_PIDR
);
1123 * Do a PC offset of 0 to register the line number
1126 Local
[1] = DST_S_C_LINE_NUM
;
1127 Local
[2] = 0; /* Increment PC by 0 and register line # */
1128 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1133 * If Delta is negative, terminate the line numbers
1137 Local
[0] = 1 + 1 + 4;
1138 Local
[1] = DST_S_C_LINE_NUM
;
1139 Local
[2] = DST_S_C_TERM_L
;
1140 COPY_LONG (&Local
[3], Offset
);
1141 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1148 * Do a PC/Line delta
1151 *cp
++ = DST_S_C_LINE_NUM
;
1152 if (Line_Number
> 1)
1155 * We need to increment the line number
1157 if (Line_Number
- 1 <= 255)
1159 *cp
++ = DST_S_C_INCR_LINUM
;
1160 *cp
++ = Line_Number
- 1;
1164 *cp
++ = DST_S_C_INCR_LINUM_W
;
1165 COPY_SHORT (cp
, Line_Number
- 1);
1166 cp
+= sizeof (short);
1178 if (Offset
< 0x10000)
1180 *cp
++ = DST_S_C_DELTA_PC_W
;
1181 COPY_SHORT (cp
, Offset
);
1182 cp
+= sizeof (short);
1186 *cp
++ = DST_S_C_DELTA_PC_L
;
1187 COPY_LONG (cp
, Offset
);
1188 cp
+= sizeof (long);
1191 Local
[0] = cp
- (Local
+ 1);
1192 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1198 * Describe a source file to the debugger
1201 VMS_TBT_Source_File (Filename
, ID_Number
)
1205 register char *cp
, *cp1
;
1208 #ifndef VMS /* Used for cross-assembly */
1209 i
= strlen (Filename
);
1211 static struct FAB Fab
;
1212 static struct NAM Nam
;
1213 static struct XABDAT Date_Xab
;
1214 static struct XABFHC File_Header_Xab
;
1215 char Es_String
[255], Rs_String
[255];
1220 Fab
.fab$b_bid
= FAB$C_BID
;
1221 Fab
.fab$b_bln
= sizeof (Fab
);
1222 Fab
.fab$l_nam
= (&Nam
);
1223 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1225 * Setup the Nam block so we can find out the FULL name
1226 * of the source file.
1228 Nam
.nam$b_bid
= NAM$C_BID
;
1229 Nam
.nam$b_bln
= sizeof (Nam
);
1230 Nam
.nam$l_rsa
= Rs_String
;
1231 Nam
.nam$b_rss
= sizeof (Rs_String
);
1232 Nam
.nam$l_esa
= Es_String
;
1233 Nam
.nam$b_ess
= sizeof (Es_String
);
1235 * Setup the Date and File Header Xabs
1237 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1238 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1239 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1240 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1241 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1243 * Get the file information
1245 Fab
.fab$l_fna
= Filename
;
1246 Fab
.fab$b_fns
= strlen (Filename
);
1247 Status
= sys$
open (&Fab
);
1250 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1256 * Calculate the size of the resultant string
1263 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1265 * Source declaration
1267 Local
[1] = DST_S_C_SOURCE
;
1269 * Make formfeeds count as source records
1271 Local
[2] = DST_S_C_SRC_FORMFEED
;
1273 * Declare source file
1275 Local
[3] = DST_S_C_SRC_DECLFILE
;
1276 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1285 COPY_SHORT (cp
, ID_Number
);
1286 cp
+= sizeof (short);
1289 * Creation Date. Unknown, so we fill with zeroes.
1292 cp
+= sizeof (long);
1294 cp
+= sizeof (long);
1299 cp
+= sizeof (long);
1304 cp
+= sizeof (short);
1314 #else /* Use this code when assembling for VMS on a VMS system */
1318 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1319 cp
+= sizeof (long);
1320 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1321 cp
+= sizeof (long);
1325 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1326 cp
+= sizeof (long);
1330 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1331 cp
+= sizeof (short);
1335 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1345 * Library module name (none)
1351 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1357 * Give the number of source lines to the debugger
1360 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1362 int Starting_Line_Number
;
1363 int Number_Of_Lines
;
1371 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1373 * Source declaration
1375 Local
[1] = DST_S_C_SOURCE
;
1380 *cp
++ = DST_S_C_SRC_SETFILE
;
1384 COPY_SHORT (cp
, ID_Number
);
1385 cp
+= sizeof (short);
1389 *cp
++ = DST_S_C_SRC_SETREC_L
;
1390 COPY_LONG (cp
, Starting_Line_Number
);
1391 cp
+= sizeof (long);
1395 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1396 COPY_SHORT (cp
, Number_Of_Lines
);
1397 cp
+= sizeof (short);
1401 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1407 /* This routine locates a file in the list of files. If an entry does not
1408 * exist, one is created. For include files, a new entry is always created
1409 * such that inline functions can be properly debugged. */
1410 static struct input_file
*
1414 struct input_file
*same_file
;
1415 struct input_file
*fpnt
;
1416 same_file
= (struct input_file
*) NULL
;
1417 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1419 if (fpnt
== (struct input_file
*) NULL
)
1421 if (fpnt
->spnt
== sp
)
1424 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1426 if (fpnt
== (struct input_file
*) NULL
)
1428 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1430 if (fpnt
->flag
== 1)
1436 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1437 if (file_root
== (struct input_file
*) NULL
)
1441 struct input_file
*fpnt1
;
1442 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1445 fpnt
->next
= (struct input_file
*) NULL
;
1446 fpnt
->name
= S_GET_NAME (sp
);
1447 fpnt
->min_line
= 0x7fffffff;
1451 fpnt
->file_number
= 0;
1453 fpnt
->same_file_fpnt
= same_file
;
1458 * The following functions and definitions are used to generate object records
1459 * that will describe program variables to the VMS debugger.
1461 * This file contains many of the routines needed to output debugging info into
1462 * the object file that the VMS debugger needs to understand symbols. These
1463 * routines are called very late in the assembly process, and thus we can be
1464 * fairly lax about changing things, since the GSD and the TIR sections have
1465 * already been output.
1469 /* This routine converts a number string into an integer, and stops when it
1470 * sees an invalid character the return value is the address of the character
1471 * just past the last character read. No error is generated.
1474 cvt_integer (str
, rtn
)
1479 neg
= *str
== '-' ? ++str
, -1 : 1;
1480 ival
= 0; /* first get the number of the type for dbx */
1481 while ((*str
<= '9') && (*str
>= '0'))
1482 ival
= 10 * ival
+ *str
++ - '0';
1487 /* this routine fixes the names that are generated by C++, ".this" is a good
1488 * example. The period does not work for the debugger, since it looks like
1489 * the syntax for a structure element, and thus it gets mightily confused
1491 * We also use this to strip the PsectAttribute hack from the name before we
1492 * write a debugger record */
1500 * Kill any leading "_"
1505 * Is there a Psect Attribute to skip??
1507 if (HAS_PSECT_ATTRIBUTES (pnt
))
1512 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1515 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1523 /* Here we fix the .this -> $this conversion */
1524 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1532 /* When defining a structure, this routine is called to find the name of
1533 * the actual structure. It is assumed that str points to the equal sign
1534 * in the definition, and it moves backward until it finds the start of the
1535 * name. If it finds a 0, then it knows that this structure def is in the
1536 * outermost level, and thus symbol_name points to the symbol name.
1539 get_struct_name (str
)
1544 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1549 while ((*pnt
!= ';') && (*pnt
!= '='))
1553 while ((*pnt
< '0') || (*pnt
> '9'))
1555 while ((*pnt
>= '0') && (*pnt
<= '9'))
1560 /* search symbol list for type number dbx_type. Return a pointer to struct */
1561 static struct VMS_DBG_Symbol
*
1562 find_symbol (dbx_type
)
1565 struct VMS_DBG_Symbol
*spnt
;
1566 spnt
= VMS_Symbol_type_list
;
1567 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1569 if (spnt
->dbx_type
== dbx_type
)
1573 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1574 return 0; /*Dunno what this is*/
1575 if(spnt
->advanced
== ALIAS
)
1576 return find_symbol(spnt
->type2
);
1581 /* this routine puts info into either Local or Asuffix, depending on the sign
1582 * of size. The reason is that it is easier to build the variable descriptor
1583 * backwards, while the array descriptor is best built forwards. In the end
1584 * they get put together, if there is not a struct/union/enum along the way
1603 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1607 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1610 Apoint
= MAX_DEBUG_RECORD
- 1;
1613 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1618 /* this routine generates the array descriptor for a given array */
1620 array_suffix (spnt2
)
1621 struct VMS_DBG_Symbol
*spnt2
;
1623 struct VMS_DBG_Symbol
*spnt
;
1624 struct VMS_DBG_Symbol
*spnt1
;
1630 while (spnt
->advanced
!= ARRAY
)
1632 spnt
= find_symbol (spnt
->type2
);
1633 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1639 while (spnt1
->advanced
== ARRAY
)
1642 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1643 spnt1
= find_symbol (spnt1
->type2
);
1645 total_size
= total_size
* spnt1
->data_size
;
1646 push (spnt1
->data_size
, 2);
1647 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1650 push (spnt1
->VMS_type
, 1);
1652 for (i
= 0; i
< 6; i
++)
1656 push (total_size
, 4);
1659 while (spnt1
->advanced
== ARRAY
)
1661 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1662 spnt1
= find_symbol (spnt1
->type2
);
1665 while (spnt1
->advanced
== ARRAY
)
1667 push (spnt1
->index_min
, 4);
1668 push (spnt1
->index_max
, 4);
1669 spnt1
= find_symbol (spnt1
->type2
);
1673 /* this routine generates the start of a variable descriptor based upon
1674 * a struct/union/enum that has yet to be defined. We define this spot as
1675 * a new location, and save four bytes for the address. When the struct is
1676 * finally defined, then we can go back and plug in the correct address
1679 new_forward_ref (dbx_type
)
1682 struct forward_ref
*fpnt
;
1683 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1684 fpnt
->next
= f_ref_root
;
1686 fpnt
->dbx_type
= dbx_type
;
1687 fpnt
->struc_numb
= ++structure_count
;
1688 fpnt
->resolved
= 'N';
1691 push (total_len
, -2);
1692 struct_number
= -fpnt
->struc_numb
;
1695 /* this routine generates the variable descriptor used to describe non-basic
1696 * variables. It calls itself recursively until it gets to the bottom of it
1697 * all, and then builds the descriptor backwards. It is easiest to do it this
1698 *way since we must periodically write length bytes, and it is easiest if we know
1699 *the value when it is time to write it.
1702 gen1 (spnt
, array_suffix_len
)
1703 struct VMS_DBG_Symbol
*spnt
;
1704 int array_suffix_len
;
1706 struct VMS_DBG_Symbol
*spnt1
;
1708 switch (spnt
->advanced
)
1711 push (DBG_S_C_VOID
, -1);
1713 push (total_len
, -2);
1717 if (array_suffix_len
== 0)
1719 push (spnt
->VMS_type
, -1);
1720 push (DBG_S_C_BASIC
, -1);
1722 push (total_len
, -2);
1732 struct_number
= spnt
->struc_numb
;
1733 if (struct_number
< 0)
1735 new_forward_ref (spnt
->dbx_type
);
1738 push (DBG_S_C_STRUCT
, -1);
1740 push (total_len
, -2);
1743 spnt1
= find_symbol (spnt
->type2
);
1745 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1746 new_forward_ref (spnt
->type2
);
1748 i
= gen1 (spnt1
, 0);
1750 { /* (*void) is a special case, do not put pointer suffix*/
1751 push (DBG_S_C_POINTER
, -1);
1753 push (total_len
, -2);
1758 while (spnt1
->advanced
== ARRAY
)
1760 spnt1
= find_symbol (spnt1
->type2
);
1761 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1763 printf ("gcc-as warning(debugger output):");
1764 printf ("Forward reference error, dbx type %d\n",
1769 /* It is too late to generate forward references, so the user gets a message.
1770 * This should only happen on a compiler error */
1771 i
= gen1 (spnt1
, 1);
1773 array_suffix (spnt
);
1774 array_suffix_len
= Apoint
- i
;
1775 switch (spnt1
->advanced
)
1783 push (total_len
, -2);
1786 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1788 total_len
+= array_suffix_len
+ 8;
1789 push (total_len
, -2);
1793 /* This generates a suffix for a variable. If it is not a defined type yet,
1794 * then dbx_type contains the type we are expecting so we can generate a
1795 * forward reference. This calls gen1 to build most of the descriptor, and
1796 * then it puts the icing on at the end. It then dumps whatever is needed
1797 * to get a complete descriptor (i.e. struct reference, array suffix ).
1800 generate_suffix (spnt
, dbx_type
)
1801 struct VMS_DBG_Symbol
*spnt
;
1806 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1807 struct VMS_DBG_Symbol
*spnt1
;
1809 Lpnt
= MAX_DEBUG_RECORD
- 1;
1813 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1814 new_forward_ref (dbx_type
);
1817 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1818 return 0; /* no suffix needed */
1823 push (total_len
, -1);
1824 /* if the variable descriptor overflows the record, output a descriptor for
1825 * a pointer to void.
1827 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1829 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1830 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1834 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1835 Local
[i
++] = Local
[++Lpnt
];
1837 /* we use this for a reference to a structure that has already been defined */
1838 if (struct_number
> 0)
1840 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1842 VMS_Store_Struct (struct_number
);
1844 /* we use this for a forward reference to a structure that has yet to be
1845 *defined. We store four bytes of zero to make room for the actual address once
1848 if (struct_number
< 0)
1850 struct_number
= -struct_number
;
1851 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1853 VMS_Def_Struct (struct_number
);
1854 for (i
= 0; i
< 4; i
++)
1856 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1861 Local
[Lpnt
++] = Asuffix
[i
++];
1863 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1867 /* This routine generates a symbol definition for a C sybmol for the debugger.
1868 * It takes a psect and offset for global symbols - if psect < 0, then this is
1869 * a local variable and the offset is relative to FP. In this case it can
1870 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1873 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1874 struct VMS_DBG_Symbol
*spnt
;
1884 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
1886 { /* this is a local variable, referenced to SP */
1887 maxlen
= 7 + strlen (Name_pnt
);
1888 Local
[i
++] = maxlen
;
1889 Local
[i
++] = spnt
->VMS_type
;
1891 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
1893 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
1894 COPY_LONG (&Local
[i
], Offset
);
1899 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
1900 Local
[i
++] = 7 + strlen (Name_pnt
);
1901 Local
[i
++] = spnt
->VMS_type
;
1903 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1905 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
1907 Local
[i
++] = strlen (Name_pnt
);
1908 while (*Name_pnt
!= '\0')
1909 Local
[i
++] = *Name_pnt
++;
1910 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1911 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1912 generate_suffix (spnt
, 0);
1916 /* This routine parses the stabs entries in order to make the definition
1917 * for the debugger of local symbols and function parameters
1920 VMS_local_stab_Parse (sp
)
1926 struct VMS_DBG_Symbol
*spnt
;
1927 struct VMS_Symbol
*vsp
;
1931 str
= S_GET_NAME (sp
);
1932 pnt
= (char *) strchr (str
, ':');
1933 if (pnt
== (char *) NULL
)
1934 return; /* no colon present */
1935 pnt1
= pnt
++; /* save this for later, and skip colon */
1937 return 0; /* ignore static constants */
1938 /* there is one little catch that we must be aware of. Sometimes function
1939 * parameters are optimized into registers, and the compiler, in its infiite
1940 * wisdom outputs stabs records for *both*. In general we want to use the
1941 * register if it is present, so we must search the rest of the symbols for
1942 * this function to see if this parameter is assigned to a register.
1950 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
1952 if (!S_IS_DEBUG (sp1
))
1954 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
1956 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
1957 if (*pnt3
== 'F' || *pnt3
== 'f') break;
1959 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
1961 str1
= S_GET_NAME (sp1
); /* and get the name */
1963 while (*pnt2
!= ':')
1970 if ((*str1
!= ':') || (*pnt2
!= ':'))
1972 return; /* they are the same! lets skip this one */
1974 /* first find the dbx symbol type from list, and then find VMS type */
1975 pnt
++; /* skip p in case no register */
1978 pnt
= cvt_integer (pnt
, &dbx_type
);
1979 spnt
= find_symbol (dbx_type
);
1980 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1981 return 0; /*Dunno what this is*/
1983 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
1984 *pnt1
= ':'; /* and restore the string */
1988 /* This routine parses a stabs entry to find the information required to define
1989 * a variable. It is used for global and static variables.
1990 * Basically we need to know the address of the symbol. With older versions
1991 * of the compiler, const symbols are
1992 * treated differently, in that if they are global they are written into the
1993 * text psect. The global symbol entry for such a const is actually written
1994 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
1995 * of psects, we must search the entry points as well. static consts are even
1996 * harder, since they are never assigned a memory address. The compiler passes
1997 * a stab to tell us the value, but I am not sure what to do with it.
2001 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2004 int type1
, type2
, Text_Psect
;
2010 struct VMS_DBG_Symbol
*spnt
;
2011 struct VMS_Symbol
*vsp
;
2015 str
= S_GET_NAME (sp
);
2016 pnt
= (char *) strchr (str
, ':');
2017 if (pnt
== (char *) NULL
)
2018 return; /* no colon present */
2019 pnt1
= pnt
; /* save this for later*/
2021 if (*pnt
== expected_type
)
2023 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2024 spnt
= find_symbol (dbx_type
);
2025 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2026 return 0; /*Dunno what this is*/
2027 /* now we need to search the symbol table to find the psect and offset for
2032 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2034 pnt
= S_GET_NAME (vsp
->Symbol
);
2035 if (pnt
!= (char *) NULL
)
2037 /* make sure name is the same, and make sure correct symbol type */
2038 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2039 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2040 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2044 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2046 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2047 *pnt1
= ':'; /* and restore the string */
2050 /* the symbol was not in the symbol list, but it may be an "entry point"
2051 if it was a constant */
2052 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2055 * Dispatch on STAB type
2057 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2059 pnt
= S_GET_NAME (sp1
);
2062 if (strcmp (pnt
, str
) == 0)
2064 if (!gave_compiler_message
&& expected_type
== 'G')
2066 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2067 printf ("global constant(s) in the text psect. These will not be available to\n");
2068 printf ("other modules, since this is not the correct way to handle this. You\n");
2069 printf ("have two options: 1) get a patched compiler that does not put global\n");
2070 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2071 printf ("definitions of global variables in your source module(s). Don't say\n");
2072 printf ("I didn't warn you!");
2073 gave_compiler_message
= 1;
2075 VMS_DBG_record (spnt
,
2080 *S_GET_NAME (sp1
) = 'L';
2081 /* fool assembler to not output this
2082 * as a routine in the TBT */
2087 *pnt1
= ':'; /* and restore the string */
2092 VMS_GSYM_Parse (sp
, Text_Psect
)
2095 { /* Global variables */
2096 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2101 VMS_LCSYM_Parse (sp
, Text_Psect
)
2104 { /* Static symbols - uninitialized */
2105 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2109 VMS_STSYM_Parse (sp
, Text_Psect
)
2112 { /* Static symbols - initialized */
2113 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2117 /* for register symbols, we must figure out what range of addresses within the
2118 * psect are valid. We will use the brackets in the stab directives to give us
2119 * guidance as to the PC range that this variable is in scope. I am still not
2120 * completely comfortable with this but as I learn more, I seem to get a better
2121 * handle on what is going on.
2125 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2126 symbolS
*sp
, *Current_Routine
;
2133 struct VMS_DBG_Symbol
*spnt
;
2138 int Min_Offset
= -1; /* min PC of validity */
2139 int Max_Offset
= 0; /* max PC of validity */
2141 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2144 * Dispatch on STAB type
2146 switch (S_GET_RAW_TYPE (symbolP
))
2150 Min_Offset
= S_GET_VALUE (symbolP
);
2155 S_GET_VALUE (symbolP
) - 1;
2158 if ((Min_Offset
!= -1) && (bcnt
== 0))
2160 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2162 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2163 if (*pnt
== 'F' || *pnt
== 'f') break;
2166 /* check to see that the addresses were defined. If not, then there were no
2167 * brackets in the function, and we must try to search for the next function
2168 * Since functions can be in any order, we should search all of the symbol list
2169 * to find the correct ending address. */
2170 if (Min_Offset
== -1)
2172 int Max_Source_Offset
;
2174 Min_Offset
= S_GET_VALUE (sp
);
2175 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2178 * Dispatch on STAB type
2180 This_Offset
= S_GET_VALUE (symbolP
);
2181 switch (S_GET_RAW_TYPE (symbolP
))
2183 case N_TEXT
| N_EXT
:
2184 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2185 Max_Offset
= This_Offset
;
2188 if (This_Offset
> Max_Source_Offset
)
2189 Max_Source_Offset
= This_Offset
;
2192 /* if this is the last routine, then we use the PC of the last source line
2193 * as a marker of the max PC for which this reg is valid */
2194 if (Max_Offset
== 0x7fffffff)
2195 Max_Offset
= Max_Source_Offset
;
2198 str
= S_GET_NAME (sp
);
2199 pnt
= (char *) strchr (str
, ':');
2200 if (pnt
== (char *) NULL
)
2201 return; /* no colon present */
2202 pnt1
= pnt
; /* save this for later*/
2206 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2207 spnt
= find_symbol (dbx_type
);
2208 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2209 return 0; /*Dunno what this is yet*/
2211 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2212 maxlen
= 25 + strlen (pnt
);
2213 Local
[i
++] = maxlen
;
2214 Local
[i
++] = spnt
->VMS_type
;
2216 Local
[i
++] = strlen (pnt
) + 1;
2220 Local
[i
++] = strlen (pnt
);
2221 while (*pnt
!= '\0')
2222 Local
[i
++] = *pnt
++;
2228 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2230 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2231 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2233 Local
[i
++] = S_GET_VALUE (sp
);
2237 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2239 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2240 generate_suffix (spnt
, 0);
2243 /* this function examines a structure definition, checking all of the elements
2244 * to make sure that all of them are fully defined. The only thing that we
2245 * kick out are arrays of undefined structs, since we do not know how big
2246 * they are. All others we can handle with a normal forward reference.
2249 forward_reference (pnt
)
2253 struct VMS_DBG_Symbol
*spnt
;
2254 struct VMS_DBG_Symbol
*spnt1
;
2255 pnt
= cvt_integer (pnt
+ 1, &i
);
2257 return 0; /* no forward references */
2260 pnt
= (char *) strchr (pnt
, ':');
2261 pnt
= cvt_integer (pnt
+ 1, &i
);
2262 spnt
= find_symbol (i
);
2263 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2264 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2267 spnt1
= find_symbol (spnt
->type2
);
2268 if ((spnt
->advanced
== ARRAY
) &&
2269 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2271 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2276 pnt
= cvt_integer (pnt
+ 1, &i
);
2277 pnt
= cvt_integer (pnt
+ 1, &i
);
2278 } while (*++pnt
!= ';');
2279 return 0; /* no forward refences found */
2282 /* Used to check a single element of a structure on the final pass*/
2285 final_forward_reference (spnt
)
2286 struct VMS_DBG_Symbol
* spnt
;
2288 struct VMS_DBG_Symbol
* spnt1
;
2289 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2290 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2291 spnt1
= find_symbol(spnt
->type2
);
2292 if((spnt
->advanced
== ARRAY
) &&
2293 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2294 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2298 return 0; /* no forward refences found */
2301 /* This routine parses the stabs directives to find any definitions of dbx type
2302 * numbers. It makes a note of all of them, creating a structure element
2303 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2304 * debugger that describes the struct/union/enum, so that further references
2305 * to these data types will be by number
2306 * We have to process pointers right away, since there can be references
2307 * to them later in the same stabs directive. We cannot have forward
2308 * references to pointers, (but we can have a forward reference to a pointer to
2309 * a structure/enum/union) and this is why we process them immediately.
2310 * After we process the pointer, then we search for defs that are nested even
2312 * 8/15/92: We have to process arrays right away too, because there can
2313 * be multiple references to identical array types in one structure
2314 * definition, and only the first one has the definition. (We tend to
2315 * parse from the back going forward.
2318 VMS_typedef_parse (str
)
2326 struct forward_ref
*fpnt
;
2328 int convert_integer
;
2329 struct VMS_DBG_Symbol
*spnt
;
2330 struct VMS_DBG_Symbol
*spnt1
;
2331 /* check for any nested def's */
2332 pnt
= (char *) strchr (str
+ 1, '=');
2333 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2334 && (str
[1] != 'a' || str
[2] != 'r'))
2335 if (VMS_typedef_parse (pnt
) == 1)
2337 /* now find dbx_type of entry */
2340 { /* check for static constants */
2341 *str
= '\0'; /* for now we ignore them */
2344 while ((*pnt
<= '9') && (*pnt
>= '0'))
2346 pnt
++; /* and get back to the number */
2347 cvt_integer (pnt
, &i1
);
2348 spnt
= find_symbol (i1
);
2349 /* first we see if this has been defined already, due to a forward reference*/
2350 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2352 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2353 spnt
->next
= VMS_Symbol_type_list
;
2354 VMS_Symbol_type_list
= spnt
;
2355 spnt
->dbx_type
= i1
; /* and save the type */
2357 /* for structs and unions, do a partial parse, otherwise we sometimes get
2358 * circular definitions that are impossible to resolve. We read enough info
2359 * so that any reference to this type has enough info to be resolved
2361 pnt
= str
+ 1; /* point to character past equal sign */
2362 if ((*pnt
== 'u') || (*pnt
== 's'))
2365 if ((*pnt
<= '9') && (*pnt
>= '0'))
2367 if (type_check ("void"))
2368 { /* this is the void symbol */
2370 spnt
->advanced
= VOID
;
2373 if (type_check ("unknown type"))
2374 { /* this is the void symbol */
2376 spnt
->advanced
= UNKNOWN
;
2379 pnt1
= cvt_integer(pnt
,&i1
);
2380 if(i1
!= spnt
->dbx_type
)
2382 spnt
->advanced
= ALIAS
;
2387 printf ("gcc-as warning(debugger output):");
2388 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2389 return 1; /* do not know what this is */
2391 /* now define this module*/
2392 pnt
= str
+ 1; /* point to character past equal sign */
2396 spnt
->advanced
= BASIC
;
2397 if (type_check ("int"))
2399 spnt
->VMS_type
= DBG_S_C_SLINT
;
2400 spnt
->data_size
= 4;
2402 else if (type_check ("long int"))
2404 spnt
->VMS_type
= DBG_S_C_SLINT
;
2405 spnt
->data_size
= 4;
2407 else if (type_check ("unsigned int"))
2409 spnt
->VMS_type
= DBG_S_C_ULINT
;
2410 spnt
->data_size
= 4;
2412 else if (type_check ("long unsigned int"))
2414 spnt
->VMS_type
= DBG_S_C_ULINT
;
2415 spnt
->data_size
= 4;
2417 else if (type_check ("short int"))
2419 spnt
->VMS_type
= DBG_S_C_SSINT
;
2420 spnt
->data_size
= 2;
2422 else if (type_check ("short unsigned int"))
2424 spnt
->VMS_type
= DBG_S_C_USINT
;
2425 spnt
->data_size
= 2;
2427 else if (type_check ("char"))
2429 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2430 spnt
->data_size
= 1;
2432 else if (type_check ("signed char"))
2434 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2435 spnt
->data_size
= 1;
2437 else if (type_check ("unsigned char"))
2439 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2440 spnt
->data_size
= 1;
2442 else if (type_check ("float"))
2444 spnt
->VMS_type
= DBG_S_C_REAL4
;
2445 spnt
->data_size
= 4;
2447 else if (type_check ("double"))
2449 /* caveat: this assumes D_float, and is not correct for G_float */
2450 spnt
->VMS_type
= DBG_S_C_REAL8
;
2451 spnt
->data_size
= 8;
2453 else if (type_check ("long double"))
2455 /* same as double, at least for now */
2456 spnt
->VMS_type
= DBG_S_C_REAL8
;
2457 spnt
->data_size
= 8;
2459 else if (type_check ("long long int"))
2461 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2462 spnt
->data_size
= 8;
2464 else if (type_check ("long long unsigned int"))
2466 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2467 spnt
->data_size
= 8;
2469 else if (type_check ("complex float"))
2471 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2472 spnt
->data_size
= 2 * 4;
2474 else if (type_check ("complex double"))
2476 /* caveat: this assumes D_float, and is not correct for G_float */
2477 spnt
->VMS_type
= DBG_S_C_COMPLX8
;
2478 spnt
->data_size
= 2 * 8;
2480 else if (type_check ("complex long double"))
2482 /* same as complex double, at least for now */
2483 spnt
->VMS_type
= DBG_S_C_COMPLX8
;
2484 spnt
->data_size
= 2 * 8;
2489 * Shouldn't get here, but if we do, something
2490 * more substantial ought to be done...
2493 spnt
->data_size
= 0;
2495 pnt1
= (char *) strchr (str
, ';') + 1;
2500 spnt
->advanced
= STRUCT
;
2502 spnt
->advanced
= UNION
;
2503 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2504 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2505 if (!final_pass
&& forward_reference(pnt
))
2507 spnt
->struc_numb
= -1;
2510 spnt
->struc_numb
= ++structure_count
;
2512 pnt
= get_struct_name (str
);
2513 VMS_Def_Struct (spnt
->struc_numb
);
2515 while (fpnt
!= (struct forward_ref
*) NULL
)
2517 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2519 fpnt
->resolved
= 'Y';
2520 VMS_Set_Struct (fpnt
->struc_numb
);
2521 VMS_Store_Struct (spnt
->struc_numb
);
2525 VMS_Set_Struct (spnt
->struc_numb
);
2527 Local
[i
++] = 11 + strlen (pnt
);
2528 Local
[i
++] = DBG_S_C_STRUCT_START
;
2530 for (i1
= 0; i1
< 4; i1
++)
2532 Local
[i
++] = strlen (pnt
);
2534 while (*pnt2
!= '\0')
2535 Local
[i
++] = *pnt2
++;
2536 i2
= spnt
->data_size
* 8; /* number of bits */
2537 COPY_LONG(&Local
[i
], i2
);
2539 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2541 if (pnt
!= symbol_name
)
2543 pnt
+= strlen (pnt
);
2545 } /* replace colon for later */
2546 while (*++pnt1
!= ';')
2548 pnt
= (char *) strchr (pnt1
, ':');
2551 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2552 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2553 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2554 if ((dtype
== 1) && (i3
!= 32))
2557 push (19 + strlen (pnt2
), 1);
2559 push (1 + strlen (pnt2
), 4);
2560 push (strlen (pnt2
), 1);
2561 while (*pnt2
!= '\0')
2563 push (i3
, 2); /* size of bitfield */
2566 push (i2
, 4); /* start position */
2567 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2572 Local
[i
++] = 7 + strlen (pnt2
);
2573 spnt1
= find_symbol (dtype
);
2574 /* check if this is a forward reference */
2575 if(final_pass
&& final_forward_reference(spnt1
))
2577 printf("gcc-as warning(debugger output):");
2578 printf("structure element %s has undefined type\n",pnt2
);
2582 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2583 Local
[i
++] = spnt1
->VMS_type
;
2585 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2586 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2587 COPY_LONG (&Local
[i
], i2
);
2589 Local
[i
++] = strlen (pnt2
);
2590 while (*pnt2
!= '\0')
2591 Local
[i
++] = *pnt2
++;
2592 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2594 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2595 generate_suffix (spnt1
, dtype
);
2596 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2597 generate_suffix (spnt1
, 0);
2601 Local
[i
++] = 0x01; /* length byte */
2602 Local
[i
++] = DBG_S_C_STRUCT_END
;
2603 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2607 spnt
->advanced
= ENUM
;
2608 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2609 spnt
->struc_numb
= ++structure_count
;
2610 spnt
->data_size
= 4;
2611 VMS_Def_Struct (spnt
->struc_numb
);
2613 while (fpnt
!= (struct forward_ref
*) NULL
)
2615 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2617 fpnt
->resolved
= 'Y';
2618 VMS_Set_Struct (fpnt
->struc_numb
);
2619 VMS_Store_Struct (spnt
->struc_numb
);
2623 VMS_Set_Struct (spnt
->struc_numb
);
2625 Local
[i
++] = 3 + strlen (symbol_name
);
2626 Local
[i
++] = DBG_S_C_ENUM_START
;
2628 Local
[i
++] = strlen (symbol_name
);
2630 while (*pnt2
!= '\0')
2631 Local
[i
++] = *pnt2
++;
2632 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2634 while (*++pnt
!= ';')
2636 pnt1
= (char *) strchr (pnt
, ':');
2638 pnt1
= cvt_integer (pnt1
, &i1
);
2639 Local
[i
++] = 7 + strlen (pnt
);
2640 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2642 COPY_LONG (&Local
[i
], i1
);
2644 Local
[i
++] = strlen (pnt
);
2646 while (*pnt
!= '\0')
2647 Local
[i
++] = *pnt
++;
2648 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2650 pnt
= pnt1
; /* Skip final semicolon */
2652 Local
[i
++] = 0x01; /* len byte */
2653 Local
[i
++] = DBG_S_C_ENUM_END
;
2654 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2659 spnt
->advanced
= ARRAY
;
2660 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2661 pnt
= (char *) strchr (pnt
, ';');
2662 if (pnt
== (char *) NULL
)
2664 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2665 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2666 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2667 pnt
=(char*)strchr(str
+1,'=');
2668 if((pnt
!= (char*) NULL
))
2669 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2672 spnt
->advanced
= FUNCTION
;
2673 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2674 /* this masquerades as a basic type*/
2675 spnt
->data_size
= 4;
2676 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2679 spnt
->advanced
= POINTER
;
2680 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2681 spnt
->data_size
= 4;
2682 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2683 pnt
= (char *) strchr (str
+ 1, '=');
2684 if ((pnt
!= (char *) NULL
))
2685 if (VMS_typedef_parse (pnt
) == 1)
2689 spnt
->advanced
= UNKNOWN
;
2691 printf ("gcc-as warning(debugger output):");
2692 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2693 return 1; /* unable to decipher */
2695 /* this removes the evidence of the definition so that the outer levels of
2696 parsing do not have to worry about it */
2698 while (*pnt1
!= '\0')
2706 * This is the root routine that parses the stabs entries for definitions.
2707 * it calls VMS_typedef_parse, which can in turn call itself.
2708 * We need to be careful, since sometimes there are forward references to
2709 * other symbol types, and these cannot be resolved until we have completed
2712 * Also check and see if we are using continuation stabs, if we are, then
2713 * paste together the entire contents of the stab before we pass it to
2714 * VMS_typedef_parse.
2723 char *parse_buffer
= 0;
2725 int incomplete
, i
, pass
, incom1
;
2726 struct VMS_DBG_Symbol
*spnt
;
2727 struct VMS_Symbol
*vsp
;
2728 struct forward_ref
*fpnt
;
2735 incom1
= incomplete
;
2737 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2740 * Deal with STAB symbols
2742 if (S_IS_DEBUG (sp
))
2745 * Dispatch on STAB type
2747 switch (S_GET_RAW_TYPE (sp
))
2755 case N_FUN
: /*sometimes these contain typedefs*/
2756 str
= S_GET_NAME (sp
);
2758 pnt
= str
+ strlen(str
) -1;
2759 if (*pnt
== '?') /* Continuation stab. */
2765 tlen
+= strlen(str
) - 1;
2766 spnext
= symbol_next (spnext
);
2767 str
= S_GET_NAME (spnext
);
2768 pnt
= str
+ strlen(str
) - 1;
2769 } while (*pnt
== '?');
2770 tlen
+= strlen(str
);
2771 parse_buffer
= (char *) xmalloc (tlen
+ 1);
2772 strcpy(parse_buffer
, S_GET_NAME (sp
));
2773 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2777 spnext
= symbol_next (spnext
);
2778 str
= S_GET_NAME (spnext
);
2779 strcat (pnt2
, S_GET_NAME (spnext
));
2780 pnt2
+= strlen(str
) - 1;
2781 *str
= '\0'; /* Erase this string */
2782 if (*pnt2
!= '?') break;
2788 pnt
= (char *) strchr (str
, ':');
2789 if (pnt
!= (char *) NULL
)
2793 pnt2
= (char *) strchr (pnt1
, '=');
2794 if (pnt2
!= (char *) NULL
)
2795 incomplete
+= VMS_typedef_parse (pnt2
);
2797 /* At this point the parse buffer should just contain name:nn.
2798 If it does not, then we are in real trouble. Anyway,
2799 this is always shorter than the original line. */
2800 strcpy(S_GET_NAME (sp
), parse_buffer
);
2801 free (parse_buffer
);
2804 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2811 /* Make one last pass, if needed, and define whatever we can that is left */
2812 if(final_pass
== 0 && incomplete
== incom1
)
2815 incom1
++; /* Force one last pass through */
2817 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2818 /* repeat until all refs resolved if possible */
2819 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2820 if (incomplete
!= 0)
2822 printf ("gcc-as warning(debugger output):");
2823 printf ("Unable to resolve %d circular references.\n", incomplete
);
2827 while (fpnt
!= (struct forward_ref
*) NULL
)
2829 if (fpnt
->resolved
!= 'Y')
2831 if (find_symbol (fpnt
->dbx_type
) !=
2832 (struct VMS_DBG_Symbol
*) NULL
)
2834 printf ("gcc-as warning(debugger output):");
2835 printf ("Forward reference error, dbx type %d\n",
2840 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2841 pnt2
= (char *) strchr (&fixit
[1], '=');
2842 VMS_typedef_parse (pnt2
);
2849 Define_Local_Symbols (s1
, s2
)
2853 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2855 if (symbolP1
== (symbolS
*) NULL
)
2857 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2859 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2860 if (*pnt
== 'F' || *pnt
== 'f') break;
2863 * Deal with STAB symbols
2865 if (S_IS_DEBUG (symbolP1
))
2868 * Dispatch on STAB type
2870 switch (S_GET_RAW_TYPE (symbolP1
))
2874 VMS_local_stab_Parse (symbolP1
);
2877 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
2885 /* This function crawls the symbol chain searching for local symbols that need
2886 * to be described to the debugger. When we enter a new scope with a "{", it
2887 * creates a new "block", which helps the debugger keep track of which scope
2888 * we are currently in.
2892 Define_Routine (symbolP
, Level
)
2902 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
2904 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2906 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2907 if (*pnt
== 'F' || *pnt
== 'f') break;
2910 * Deal with STAB symbols
2912 if (S_IS_DEBUG (symbolP1
))
2915 * Dispatch on STAB type
2917 switch (S_GET_RAW_TYPE (symbolP1
))
2922 sprintf (str
, "$%d", rcount
++);
2923 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
2925 Offset
= S_GET_VALUE (symbolP1
);
2926 Define_Local_Symbols (sstart
, symbolP1
);
2928 Define_Routine (symbolP1
, Level
+ 1);
2930 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
2939 /* we end up here if there were no brackets in this function. Define
2941 Define_Local_Symbols (sstart
, (symbolS
*) 0);
2947 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
2949 symbolS
*Curr_Routine
;
2952 Current_Routine
= Curr_Routine
;
2953 Text_Psect
= Txt_Psect
;
2954 Define_Routine (symbolP
, 0);
2961 #include <sys/types.h>
2964 /* Manufacure a VMS like time on a unix based system. */
2965 get_VMS_time_on_unix (Now
)
2971 pnt
= ctime (&timeb
);
2977 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
2980 #endif /* not VMS */
2982 * Write the MHD (Module Header) records
2985 Write_VMS_MHD_Records ()
2987 register char *cp
, *cp1
;
2994 char Module_Name
[256];
2998 * We are writing a module header record
3000 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3002 * ***************************
3003 * *MAIN MODULE HEADER RECORD*
3004 * ***************************
3006 * Store record type and header type
3008 PUT_CHAR (OBJ_S_C_HDR
);
3009 PUT_CHAR (MHD_S_C_MHD
);
3011 * Structure level is 0
3013 PUT_CHAR (OBJ_S_C_STRLVL
);
3015 * Maximum record size is size of the object record buffer
3017 PUT_SHORT (sizeof (Object_Record_Buffer
));
3019 * Get module name (the FILENAME part of the object file)
3025 if ((*cp
== ']') || (*cp
== '>') ||
3026 (*cp
== ':') || (*cp
== '/'))
3032 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3036 * Limit it to 31 characters and store in the object record
3038 while (--cp1
>= Module_Name
)
3041 if (strlen (Module_Name
) > 31)
3043 if (flag_hash_long_names
)
3044 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3045 Module_Name
[31] = 0;
3047 PUT_COUNTED_STRING (Module_Name
);
3049 * Module Version is "V1.0"
3051 PUT_COUNTED_STRING ("V1.0");
3053 * Creation time is "now" (17 chars of time string)
3056 get_VMS_time_on_unix (&Now
[0]);
3058 Descriptor
.Size
= 17;
3059 Descriptor
.Ptr
= Now
;
3060 sys$
asctim (0, &Descriptor
, 0, 0);
3062 for (i
= 0; i
< 17; i
++)
3065 * Patch time is "never" (17 zeros)
3067 for (i
= 0; i
< 17; i
++)
3072 Flush_VMS_Object_Record_Buffer ();
3074 * *************************
3075 * *LANGUAGE PROCESSOR NAME*
3076 * *************************
3078 * Store record type and header type
3080 PUT_CHAR (OBJ_S_C_HDR
);
3081 PUT_CHAR (MHD_S_C_LNM
);
3083 * Store language processor name and version
3084 * (not a counted string!)
3086 * This is normally supplied by the gcc driver for the command line
3087 * which invokes gas. If absent, we fall back to gas's version.
3089 cp
= compiler_version_string
;
3102 Flush_VMS_Object_Record_Buffer ();
3107 * Write the EOM (End Of Module) record
3110 Write_VMS_EOM_Record (Psect
, Offset
)
3115 * We are writing an end-of-module record
3117 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3121 PUT_CHAR (OBJ_S_C_EOM
);
3123 * Store the error severity (0)
3127 * Store the entry point, if it exists
3132 * Store the entry point Psect
3136 * Store the entry point Psect offset
3143 Flush_VMS_Object_Record_Buffer ();
3147 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3153 register unsigned char *p
= ptr
;
3154 register unsigned char *end
= p
+ strlen (ptr
);
3155 register unsigned char c
;
3156 register int hash
= 0;
3161 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3167 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3170 VMS_Case_Hack_Symbol (In
, Out
)
3180 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3182 int Case_Hack_Bits
= 0;
3184 static char Hex_Table
[16] =
3185 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3188 * Kill any leading "_"
3190 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3193 new_name
= Out
; /* save this for later*/
3195 #if barfoo /* Dead code */
3196 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3200 /* We may need to truncate the symbol, save the hash for later*/
3201 if (strlen (In
) > 23)
3202 result
= hash_string (In
);
3204 * Is there a Psect Attribute to skip??
3206 if (HAS_PSECT_ATTRIBUTES (In
))
3211 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3214 if ((In
[0] == '$') && (In
[1] == '$'))
3224 /* if (strlen(In) > 31 && flag_hash_long_names)
3225 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3227 * Do the case conversion
3229 i
= 23; /* Maximum of 23 chars */
3230 while (*In
&& (--i
>= 0))
3232 Case_Hack_Bits
<<= 1;
3235 if ((destructor
== 1) && (i
== 21))
3237 switch (vms_name_mapping
)
3242 Case_Hack_Bits
|= 1;
3244 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3247 case 3: *Out
++ = *In
++;
3253 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3259 * If we saw a dollar sign, we don't do case hacking
3261 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3265 * If we have more than 23 characters and everything is lowercase
3266 * we can insert the full 31 characters
3271 * We have more than 23 characters
3272 * If we must add the case hack, then we have truncated the str
3276 if (Case_Hack_Bits
== 0)
3279 * And so far they are all lower case:
3280 * Check up to 8 more characters
3281 * and ensure that they are lowercase
3283 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3284 if (isupper(In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3290 if ((i
== 8) || (In
[i
] == 0))
3293 * They are: Copy up to 31 characters
3294 * to the output string
3297 while ((--i
>= 0) && (*In
))
3298 switch (vms_name_mapping
){
3299 case 0: *Out
++ = islower(*In
) ?
3303 case 3: *Out
++ = *In
++;
3305 case 2: *Out
++ = isupper(*In
) ?
3314 * If there were any uppercase characters in the name we
3315 * take on the case hacking string
3318 /* Old behavior for regular GNU-C compiler */
3319 if (!flag_hash_long_names
)
3321 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3326 for (i
= 0; i
< 6; i
++)
3328 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3329 Case_Hack_Bits
>>= 4;
3335 Out
= pnt
; /*Cut back to 23 characters maximum */
3337 for (i
= 0; i
< 7; i
++)
3339 init
= result
& 0x01f;
3341 *Out
++ = '0' + init
;
3343 *Out
++ = 'A' + init
- 10;
3344 result
= result
>> 5;
3352 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3353 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3358 * Scan a symbol name for a psect attribute specification
3360 #define GLOBALSYMBOL_BIT 0x10000
3361 #define GLOBALVALUE_BIT 0x20000
3365 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3367 int *Attribute_Pointer
;
3378 {"PIC", GPS_S_M_PIC
},
3379 {"LIB", GPS_S_M_LIB
},
3380 {"OVR", GPS_S_M_OVR
},
3381 {"REL", GPS_S_M_REL
},
3382 {"GBL", GPS_S_M_GBL
},
3383 {"SHR", GPS_S_M_SHR
},
3384 {"EXE", GPS_S_M_EXE
},
3386 {"WRT", GPS_S_M_WRT
},
3387 {"VEC", GPS_S_M_VEC
},
3388 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3389 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3399 * Check for a PSECT attribute list
3401 if (!HAS_PSECT_ATTRIBUTES (Name
))
3402 return; /* If not, return */
3404 * Skip the attribute list indicator
3406 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3408 * Process the attributes ("_" separated, "$" terminated)
3410 while (*Name
!= '$')
3413 * Assume not negating
3419 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3422 * We are negating (and skip the NO)
3428 * Find the token delimiter
3431 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3434 * Look for the token in the attribute list
3436 for (i
= 0; Attributes
[i
].Name
; i
++)
3439 * If the strings match, set/clear the attr.
3441 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3447 *Attribute_Pointer
&=
3448 ~Attributes
[i
].Value
;
3450 *Attribute_Pointer
|=
3451 Attributes
[i
].Value
;
3459 * Now skip the attribute
3469 * Define a global symbol
3472 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3480 * We are writing a GSD record
3482 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3484 * If the buffer is empty we must insert the GSD record type
3486 if (Object_Record_Offset
== 0)
3487 PUT_CHAR (OBJ_S_C_GSD
);
3489 * We are writing a Global symbol definition subrecord
3491 if (Psect_Number
<= 255)
3493 PUT_CHAR (GSD_S_C_SYM
);
3497 PUT_CHAR (GSD_S_C_SYMW
);
3500 * Data type is undefined
3504 * Switch on Definition/Reference
3506 if ((Defined
& 1) != 0)
3510 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3511 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3513 if ((Defined
& 2) == 0)
3515 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3519 PUT_SHORT (GSY_S_M_DEF
);
3524 if (Psect_Number
<= 255)
3526 PUT_CHAR (Psect_Number
);
3530 PUT_SHORT (Psect_Number
);
3535 PUT_LONG (Psect_Offset
);
3541 * Flags = "RELOCATABLE" for regular symbol,
3542 * = "" for globalvalue (Defined & 2 == 1)
3544 if ((Defined
& 2) == 0)
3546 PUT_SHORT (GSY_S_M_REL
);
3554 * Finally, the global symbol name
3556 VMS_Case_Hack_Symbol (Name
, Local
);
3557 PUT_COUNTED_STRING (Local
);
3559 * Flush the buffer if it is more than 75% full
3561 if (Object_Record_Offset
>
3562 (sizeof (Object_Record_Buffer
) * 3 / 4))
3563 Flush_VMS_Object_Record_Buffer ();
3571 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3575 struct VMS_Symbol
*vsp
;
3578 int Psect_Attributes
;
3581 * Generate the appropriate PSECT flags given the PSECT type
3583 if (strcmp (Type
, "COMMON") == 0)
3586 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3588 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3589 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3591 else if (strcmp (Type
, "CONST") == 0)
3594 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3596 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3597 GPS_S_M_SHR
| GPS_S_M_RD
);
3599 else if (strcmp (Type
, "DATA") == 0)
3602 * The Data psects are PIC,REL,RD,WRT
3605 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3607 else if (strcmp (Type
, "TEXT") == 0)
3610 * The Text psects are PIC,REL,SHR,EXE,RD
3613 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3614 GPS_S_M_EXE
| GPS_S_M_RD
);
3619 * Error: Unknown psect type
3621 error ("Unknown VMS psect type");
3624 * Modify the psect attributes according to any attribute string
3626 if (HAS_PSECT_ATTRIBUTES (Name
))
3627 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3629 * Check for globalref/def/val.
3631 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3634 * globalvalue symbols were generated before. This code
3635 * prevents unsightly psect buildup, and makes sure that
3636 * fixup references are emitted correctly.
3638 vsp
->Psect_Index
= -1; /* to catch errors */
3639 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3640 return 1; /* decrement psect counter */
3643 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3645 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3647 case N_UNDF
| N_EXT
:
3648 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3649 vsp
->Psect_Offset
, 0);
3650 vsp
->Psect_Index
= -1;
3651 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3652 return 1; /* return and indicate no psect */
3653 case N_DATA
| N_EXT
:
3654 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3655 vsp
->Psect_Offset
, 1);
3656 /* In this case we still generate the psect */
3660 char Error_Line
[256];
3661 sprintf (Error_Line
,
3662 "Globalsymbol attribute for symbol %s was unexpected.\n",
3670 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3672 * We are writing a GSD record
3674 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3676 * If the buffer is empty we must insert the GSD record type
3678 if (Object_Record_Offset
== 0)
3679 PUT_CHAR (OBJ_S_C_GSD
);
3681 * We are writing a PSECT definition subrecord
3683 PUT_CHAR (GSD_S_C_PSC
);
3685 * Psects are always LONGWORD aligned
3689 * Specify the psect attributes
3691 PUT_SHORT (Psect_Attributes
);
3693 * Specify the allocation
3697 * Finally, the psect name
3699 VMS_Case_Hack_Symbol (Name
, Local
);
3700 PUT_COUNTED_STRING (Local
);
3702 * Flush the buffer if it is more than 75% full
3704 if (Object_Record_Offset
>
3705 (sizeof (Object_Record_Buffer
) * 3 / 4))
3706 Flush_VMS_Object_Record_Buffer ();
3712 * Given the pointer to a symbol we calculate how big the data at the
3713 * symbol is. We do this by looking for the next symbol (local or
3714 * global) which will indicate the start of another datum.
3717 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3718 register struct symbol
*sp
;
3721 struct symbol
*sp1
, *Next_Symbol
;
3722 /* Cache values to avoid extra lookups. */
3723 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
;
3726 * Find the next symbol
3727 * it delimits this datum
3730 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3733 * The data type must match
3735 if (S_GET_TYPE (sp1
) != N_DATA
)
3738 sp1_val
= S_GET_VALUE (sp1
);
3741 * The symbol must be AFTER this symbol
3743 if (sp1_val
<= sp_val
)
3746 * We ignore THIS symbol
3751 * If there is already a candidate selected for the
3752 * next symbol, see if we are a better candidate
3757 * We are a better candidate if we are "closer"
3760 if (sp1_val
> next_val
)
3764 * Make this the candidate
3770 * Calculate its size
3772 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
3776 * Check symbol names for the Psect hack with a globalvalue, and then
3777 * generate globalvalues for those that have it.
3780 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3785 register symbolS
*sp
;
3786 char *stripped_name
, *Name
;
3788 int Psect_Attributes
;
3792 * Scan the symbol table for globalvalues, and emit def/ref when
3793 * required. These will be caught again later and converted to
3796 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3799 * See if this is something we want to look at.
3801 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3802 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3805 * See if this has globalvalue specification.
3807 Name
= S_GET_NAME (sp
);
3809 if (!HAS_PSECT_ATTRIBUTES (Name
))
3812 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
3813 strcpy (stripped_name
, Name
);
3814 Psect_Attributes
= 0;
3815 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3817 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3819 switch (S_GET_RAW_TYPE (sp
))
3821 case N_UNDF
| N_EXT
:
3822 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3824 case N_DATA
| N_EXT
:
3825 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3827 error ("Invalid data type for globalvalue");
3828 globalvalue
= md_chars_to_number (Data_Segment
+
3829 S_GET_VALUE (sp
) - text_siz
, Size
);
3830 /* Three times for good luck. The linker seems to get confused
3831 if there are fewer than three */
3832 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3833 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3834 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3837 printf (" Invalid globalvalue of %s\n", stripped_name
);
3841 free (stripped_name
); /* clean up */
3848 * Define a procedure entry pt/mask
3851 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3860 * We are writing a GSD record
3862 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3864 * If the buffer is empty we must insert the GSD record type
3866 if (Object_Record_Offset
== 0)
3867 PUT_CHAR (OBJ_S_C_GSD
);
3869 * We are writing a Procedure Entry Pt/Mask subrecord
3871 if (Psect_Number
<= 255)
3873 PUT_CHAR (GSD_S_C_EPM
);
3877 PUT_CHAR (GSD_S_C_EPMW
);
3880 * Data type is undefined
3884 * Flags = "RELOCATABLE" and "DEFINED"
3886 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3890 if (Psect_Number
<= 255)
3892 PUT_CHAR (Psect_Number
);
3896 PUT_SHORT (Psect_Number
);
3901 PUT_LONG (Psect_Offset
);
3905 PUT_SHORT (Entry_Mask
);
3907 * Finally, the global symbol name
3909 VMS_Case_Hack_Symbol (Name
, Local
);
3910 PUT_COUNTED_STRING (Local
);
3912 * Flush the buffer if it is more than 75% full
3914 if (Object_Record_Offset
>
3915 (sizeof (Object_Record_Buffer
) * 3 / 4))
3916 Flush_VMS_Object_Record_Buffer ();
3921 * Set the current location counter to a particular Psect and Offset
3924 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
3930 * We are writing a "Record_Type" record
3932 Set_VMS_Object_File_Record (Record_Type
);
3934 * If the buffer is empty we must insert the record type
3936 if (Object_Record_Offset
== 0)
3937 PUT_CHAR (Record_Type
);
3939 * Stack the Psect base + Longword Offset
3941 if (Psect_Index
< 255)
3943 PUT_CHAR (TIR_S_C_STA_PL
);
3944 PUT_CHAR (Psect_Index
);
3948 PUT_CHAR (TIR_S_C_STA_WPL
);
3949 PUT_SHORT (Psect_Index
);
3953 * Set relocation base
3955 PUT_CHAR (TIR_S_C_CTL_SETRB
);
3957 * Flush the buffer if it is more than 75% full
3959 if (Object_Record_Offset
>
3960 (sizeof (Object_Record_Buffer
) * 3 / 4))
3961 Flush_VMS_Object_Record_Buffer ();
3966 * Store repeated immediate data in current Psect
3969 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
3971 register char *Pointer
;
3977 * Ignore zero bytes/words/longwords
3979 if ((Size
== sizeof (char)) && (*Pointer
== 0))
3981 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
3983 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
3986 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
3987 * then we do it manually
3991 while (--Repeat_Count
>= 0)
3992 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
3996 * We are writing a "Record_Type" record
3998 Set_VMS_Object_File_Record (Record_Type
);
4000 * If the buffer is empty we must insert record type
4002 if (Object_Record_Offset
== 0)
4003 PUT_CHAR (Record_Type
);
4005 * Stack the repeat count
4007 PUT_CHAR (TIR_S_C_STA_LW
);
4008 PUT_LONG (Repeat_Count
);
4010 * And now the command and its data
4012 PUT_CHAR (TIR_S_C_STO_RIVB
);
4015 PUT_CHAR (*Pointer
++);
4017 * Flush the buffer if it is more than 75% full
4019 if (Object_Record_Offset
>
4020 (sizeof (Object_Record_Buffer
) * 3 / 4))
4021 Flush_VMS_Object_Record_Buffer ();
4026 * Store a Position Independent Reference
4029 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4030 Psect
, Psect_Offset
, Record_Type
)
4031 struct symbol
*Symbol
;
4038 register struct VMS_Symbol
*vsp
=
4039 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4043 * We are writing a "Record_Type" record
4045 Set_VMS_Object_File_Record (Record_Type
);
4047 * If the buffer is empty we must insert record type
4049 if (Object_Record_Offset
== 0)
4050 PUT_CHAR (Record_Type
);
4052 * Set to the appropriate offset in the Psect
4057 * For a Code reference we need to fix the operand
4058 * specifier as well (so back up 1 byte)
4060 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4065 * For a Data reference we just store HERE
4067 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4070 * Make sure we are still generating a "Record Type" record
4072 if (Object_Record_Offset
== 0)
4073 PUT_CHAR (Record_Type
);
4075 * Dispatch on symbol type (so we can stack its value)
4077 switch (S_GET_RAW_TYPE (Symbol
))
4082 #ifdef NOT_VAX_11_C_COMPATIBLE
4083 case N_UNDF
| N_EXT
:
4084 case N_DATA
| N_EXT
:
4085 #endif /* NOT_VAX_11_C_COMPATIBLE */
4087 case N_TEXT
| N_EXT
:
4089 * Get the symbol name (case hacked)
4091 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4093 * Stack the global symbol value
4095 PUT_CHAR (TIR_S_C_STA_GBL
);
4096 PUT_COUNTED_STRING (Local
);
4100 * Stack the longword offset
4102 PUT_CHAR (TIR_S_C_STA_LW
);
4105 * Add the two, leaving the result on the stack
4107 PUT_CHAR (TIR_S_C_OPR_ADD
);
4111 * Uninitialized local data
4115 * Stack the Psect (+offset)
4117 if (vsp
->Psect_Index
< 255)
4119 PUT_CHAR (TIR_S_C_STA_PL
);
4120 PUT_CHAR (vsp
->Psect_Index
);
4124 PUT_CHAR (TIR_S_C_STA_WPL
);
4125 PUT_SHORT (vsp
->Psect_Index
);
4127 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4134 * Stack the Psect (+offset)
4136 if (vsp
->Psect_Index
< 255)
4138 PUT_CHAR (TIR_S_C_STA_PL
);
4139 PUT_CHAR (vsp
->Psect_Index
);
4143 PUT_CHAR (TIR_S_C_STA_WPL
);
4144 PUT_SHORT (vsp
->Psect_Index
);
4146 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4149 * Initialized local or global data
4152 #ifndef NOT_VAX_11_C_COMPATIBLE
4153 case N_UNDF
| N_EXT
:
4154 case N_DATA
| N_EXT
:
4155 #endif /* NOT_VAX_11_C_COMPATIBLE */
4157 * Stack the Psect (+offset)
4159 if (vsp
->Psect_Index
< 255)
4161 PUT_CHAR (TIR_S_C_STA_PL
);
4162 PUT_CHAR (vsp
->Psect_Index
);
4166 PUT_CHAR (TIR_S_C_STA_WPL
);
4167 PUT_SHORT (vsp
->Psect_Index
);
4169 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4173 * Store either a code or data reference
4175 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4177 * Flush the buffer if it is more than 75% full
4179 if (Object_Record_Offset
>
4180 (sizeof (Object_Record_Buffer
) * 3 / 4))
4181 Flush_VMS_Object_Record_Buffer ();
4186 * Check in the text area for an indirect pc-relative reference
4187 * and fix it up with addressing mode 0xff [PC indirect]
4189 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4190 * PIC CODE GENERATING FIXUP ROUTINE.
4193 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4196 register fragS
*fragP
;
4197 struct frag
*text_frag_root
;
4200 * The addressing mode byte is 1 byte before the address
4204 * Is it in THIS frag??
4206 if ((Offset
< fragP
->fr_address
) ||
4207 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4210 * We need to search for the fragment containing this
4213 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4215 if ((Offset
>= fragP
->fr_address
) &&
4216 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4220 * If we couldn't find the frag, things are BAD!!
4223 error ("Couldn't find fixup fragment when checking for indirect reference");
4226 * Check for indirect PC relative addressing mode
4228 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4230 static char Address_Mode
= 0xff;
4233 * Yes: Store the indirect mode back into the image
4234 * to fix up the damage done by STO_PICR
4236 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4237 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4242 * If the procedure "main()" exists we have to add the instruction
4243 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4245 VMS_Check_For_Main ()
4247 register symbolS
*symbolP
;
4248 #ifdef HACK_DEC_C_STARTUP /* JF */
4249 register struct frchain
*frchainP
;
4250 register fragS
*fragP
;
4251 register fragS
**prev_fragPP
;
4252 register struct fix
*fixP
;
4253 register fragS
*New_Frag
;
4255 #endif /* HACK_DEC_C_STARTUP */
4257 symbolP
= (struct symbol
*) symbol_find ("_main");
4258 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4259 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4261 #ifdef HACK_DEC_C_STARTUP
4262 if (!flag_hash_long_names
)
4266 * Remember the entry point symbol
4268 Entry_Point_Symbol
= symbolP
;
4269 #ifdef HACK_DEC_C_STARTUP
4274 * Scan all the fragment chains for the one with "_main"
4275 * (Actually we know the fragment from the symbol, but we need
4276 * the previous fragment so we can change its pointer)
4278 frchainP
= frchain_root
;
4282 * Scan all the fragments in this chain, remembering
4283 * the "previous fragment"
4285 prev_fragPP
= &frchainP
->frch_root
;
4286 fragP
= frchainP
->frch_root
;
4287 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4290 * Is this the fragment?
4292 if (fragP
== symbolP
->sy_frag
)
4295 * Yes: Modify the fragment by replacing
4296 * it with a new fragment.
4298 New_Frag
= (fragS
*)
4299 xmalloc (sizeof (*New_Frag
) +
4304 * The fragments are the same except
4305 * that the "fixed" area is larger
4308 New_Frag
->fr_fix
+= 6;
4310 * Copy the literal data opening a hole
4311 * 2 bytes after "_main" (i.e. just after
4312 * the entry mask). Into which we place
4313 * the JSB instruction.
4315 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4316 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4317 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4318 New_Frag
->fr_literal
[3] = 0xef;
4319 New_Frag
->fr_literal
[4] = 0;
4320 New_Frag
->fr_literal
[5] = 0;
4321 New_Frag
->fr_literal
[6] = 0;
4322 New_Frag
->fr_literal
[7] = 0;
4323 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4324 New_Frag
->fr_literal
[i
+ 6] =
4325 fragP
->fr_literal
[i
];
4327 * Now replace the old fragment with the
4328 * newly generated one.
4330 *prev_fragPP
= New_Frag
;
4332 * Remember the entry point symbol
4334 Entry_Point_Symbol
= symbolP
;
4336 * Scan the text area fixup structures
4337 * as offsets in the fragment may have
4340 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4343 * Look for references to this
4346 if (fixP
->fx_frag
== fragP
)
4349 * Change the fragment
4352 fixP
->fx_frag
= New_Frag
;
4354 * If the offset is after
4355 * the entry mask we need
4356 * to account for the JSB
4357 * instruction we just
4360 if (fixP
->fx_where
>= 2)
4361 fixP
->fx_where
+= 6;
4365 * Scan the symbols as offsets in the
4366 * fragment may have changed
4368 for (symbolP
= symbol_rootP
;
4370 symbolP
= symbol_next (symbolP
))
4373 * Look for references to this
4376 if (symbolP
->sy_frag
== fragP
)
4379 * Change the fragment
4382 symbolP
->sy_frag
= New_Frag
;
4384 * If the offset is after
4385 * the entry mask we need
4386 * to account for the JSB
4387 * instruction we just
4390 if (S_GET_VALUE (symbolP
) >= 2)
4391 S_SET_VALUE (symbolP
,
4392 S_GET_VALUE (symbolP
) + 6);
4396 * Make a symbol reference to
4397 * "_c$main_args" so we can get
4398 * its address inserted into the
4401 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4402 S_GET_NAME (symbolP
) = "_c$main_args";
4403 S_SET_TYPE (symbolP
, N_UNDF
);
4404 S_GET_OTHER (symbolP
) = 0;
4405 S_GET_DESC (symbolP
) = 0;
4406 S_SET_VALUE (symbolP
, 0);
4407 symbolP
->sy_name_offset
= 0;
4408 symbolP
->sy_number
= 0;
4409 symbolP
->sy_frag
= New_Frag
;
4410 symbolP
->sy_resolved
= 0;
4411 symbolP
->sy_resolving
= 0;
4412 /* this actually inserts at the beginning of the list */
4413 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4415 symbol_rootP
= symbolP
;
4417 * Generate a text fixup structure
4418 * to get "_c$main_args" stored into the
4421 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4422 fixP
->fx_frag
= New_Frag
;
4424 fixP
->fx_addsy
= symbolP
;
4426 fixP
->fx_offset
= 0;
4427 fixP
->fx_size
= sizeof (long);
4429 fixP
->fx_next
= text_fix_root
;
4430 text_fix_root
= fixP
;
4432 * Now make sure we exit from the loop
4438 * Try the next fragment
4440 prev_fragPP
= &fragP
->fr_next
;
4441 fragP
= fragP
->fr_next
;
4444 * Try the next fragment chain
4447 frchainP
= frchainP
->frch_next
;
4450 #endif /* HACK_DEC_C_STARTUP */
4455 * Write a VAX/VMS object file (everything else has been done!)
4457 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4462 struct frag
*text_frag_root
;
4463 struct frag
*data_frag_root
;
4465 register fragS
*fragP
;
4466 register symbolS
*symbolP
;
4467 register symbolS
*sp
;
4468 register struct fix
*fixP
;
4469 register struct VMS_Symbol
*vsp
;
4471 int Local_Initialized_Data_Size
= 0;
4473 int Psect_Number
= 0; /* Psect Index Number */
4474 int Text_Psect
= -1; /* Text Psect Index */
4475 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4476 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4479 * Create the VMS object file
4481 Create_VMS_Object_File ();
4483 * Write the module header records
4485 Write_VMS_MHD_Records ();
4488 * Store the Data segment:
4490 * Since this is REALLY hard to do any other way,
4491 * we actually manufacture the data segment and
4492 * the store the appropriate values out of it.
4493 * We need to generate this early, so that globalvalues
4494 * can be properly emitted.
4499 * Allocate the data segment
4501 Data_Segment
= (char *) xmalloc (data_siz
);
4503 * Run through the data fragments, filling in the segment
4505 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4507 register long int count
;
4508 register char *fill_literal
;
4509 register long int fill_size
;
4512 i
= fragP
->fr_address
- text_siz
;
4514 memcpy (Data_Segment
+ i
,
4519 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4520 fill_size
= fragP
->fr_var
;
4521 for (count
= fragP
->fr_offset
; count
; count
--)
4524 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4532 * Generate the VMS object file records
4533 * 1st GSD then TIR records
4536 /******* Global Symbol Dictionary *******/
4538 * Emit globalvalues now. We must do this before the text psect
4539 * is defined, or we will get linker warnings about multiply defined
4540 * symbols. All of the globalvalues "reference" psect 0, although
4541 * it really does not have anything to do with it.
4543 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4545 * Define the Text Psect
4547 Text_Psect
= Psect_Number
++;
4548 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4550 * Define the BSS Psect
4554 Bss_Psect
= Psect_Number
++;
4555 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4557 #ifndef gxx_bug_fixed
4559 * The g++ compiler does not write out external references to vtables
4560 * correctly. Check for this and holler if we see it happening.
4561 * If that compiler bug is ever fixed we can remove this.
4563 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4566 * Dispatch on symbol type
4568 switch (S_GET_RAW_TYPE (sp
)) {
4574 * Make a GSD global symbol reference
4577 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4579 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4580 S_GET_OTHER (sp
) = 1;
4581 /* Is this warning still needed? It sounds like it describes
4582 a compiler bug. Does it? If not, let's dump it. */
4583 as_warn("g++ wrote an extern reference to %s as a routine.",
4585 as_warn("I will fix it, but I hope that it was not really a routine");
4592 #endif /* gxx_bug_fixed */
4594 * Now scan the symbols and emit the appropriate GSD records
4596 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4599 * Dispatch on symbol type
4601 switch (S_GET_RAW_TYPE (sp
))
4604 * Global uninitialized data
4606 case N_UNDF
| N_EXT
:
4608 * Make a VMS data symbol entry
4610 vsp
= (struct VMS_Symbol
*)
4611 xmalloc (sizeof (*vsp
));
4613 vsp
->Size
= S_GET_VALUE (sp
);
4614 vsp
->Psect_Index
= Psect_Number
++;
4615 vsp
->Psect_Offset
= 0;
4616 vsp
->Next
= VMS_Symbols
;
4618 sp
->sy_number
= (int) vsp
;
4620 * Make the psect for this data
4622 if (S_GET_OTHER (sp
))
4623 Globalref
= VMS_Psect_Spec (
4629 Globalref
= VMS_Psect_Spec (
4637 /* See if this is an external vtable. We want to help the linker find
4638 these things in libraries, so we make a symbol reference. This
4639 is not compatible with VAX-C usage for variables, but since vtables are
4640 only used internally by g++, we can get away with this hack. */
4642 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4643 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4648 #ifdef NOT_VAX_11_C_COMPATIBLE
4650 * Place a global symbol at the
4651 * beginning of the Psect
4653 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4657 #endif /* NOT_VAX_11_C_COMPATIBLE */
4660 * Local uninitialized data
4664 * Make a VMS data symbol entry
4666 vsp
= (struct VMS_Symbol
*)
4667 xmalloc (sizeof (*vsp
));
4670 vsp
->Psect_Index
= Bss_Psect
;
4673 bss_address_frag
.fr_address
;
4674 vsp
->Next
= VMS_Symbols
;
4676 sp
->sy_number
= (int) vsp
;
4679 * Global initialized data
4681 case N_DATA
| N_EXT
:
4683 * Make a VMS data symbol entry
4685 vsp
= (struct VMS_Symbol
*)
4686 xmalloc (sizeof (*vsp
));
4688 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4689 text_siz
+ data_siz
);
4690 vsp
->Psect_Index
= Psect_Number
++;
4691 vsp
->Psect_Offset
= 0;
4692 vsp
->Next
= VMS_Symbols
;
4694 sp
->sy_number
= (int) vsp
;
4698 if (S_GET_OTHER (sp
))
4699 Globalref
= VMS_Psect_Spec (
4705 Globalref
= VMS_Psect_Spec (
4713 /* See if this is an external vtable. We want to help the linker find
4714 these things in libraries, so we make a symbol definition. This
4715 is not compatible with VAX-C usage for variables, but since vtables are
4716 only used internally by g++, we can get away with this hack. */
4718 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4719 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4724 #ifdef NOT_VAX_11_C_COMPATIBLE
4726 * Place a global symbol at the
4727 * beginning of the Psect
4729 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4733 #endif /* NOT_VAX_11_C_COMPATIBLE */
4736 * Local initialized data
4740 * Make a VMS data symbol entry
4742 vsp
= (struct VMS_Symbol
*)
4743 xmalloc (sizeof (*vsp
));
4746 VMS_Initialized_Data_Size (sp
,
4747 text_siz
+ data_siz
);
4748 vsp
->Psect_Index
= Data_Psect
;
4750 Local_Initialized_Data_Size
;
4751 Local_Initialized_Data_Size
+= vsp
->Size
;
4752 vsp
->Next
= VMS_Symbols
;
4754 sp
->sy_number
= (int) vsp
;
4757 * Global Text definition
4759 case N_TEXT
| N_EXT
:
4761 unsigned short Entry_Mask
;
4764 * Get the entry mask
4766 fragP
= sp
->sy_frag
;
4768 /* If first frag doesn't contain the data, what do we do?
4769 If it's possibly smaller than two bytes, that would
4770 imply that the entry mask is not stored where we're
4773 If you can find a test case that triggers this, report
4774 it (and tell me what the entry mask field ought to be),
4775 and I'll try to fix it. KR */
4776 /* First frag might be empty if we're generating listings.
4777 So skip empty rs_fill frags. */
4778 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
4779 fragP
= fragP
->fr_next
;
4781 if (fragP
->fr_fix
< 2)
4784 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4785 ((fragP
->fr_literal
[1] & 0xff)
4788 * Define the Procedure entry pt.
4790 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4797 * Local Text definition
4801 * Make a VMS data symbol entry
4803 if (Text_Psect
!= -1)
4805 vsp
= (struct VMS_Symbol
*)
4806 xmalloc (sizeof (*vsp
));
4809 vsp
->Psect_Index
= Text_Psect
;
4810 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4811 vsp
->Next
= VMS_Symbols
;
4813 sp
->sy_number
= (int) vsp
;
4821 * Make a GSD global symbol reference
4824 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4834 * Ignore STAB symbols
4835 * Including .stabs emitted by g++
4837 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4842 if (S_GET_TYPE (sp
) != 22)
4843 printf (" ERROR, unknown type (%d)\n",
4849 * Define the Data Psect
4851 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4856 Data_Psect
= Psect_Number
++;
4857 VMS_Psect_Spec ("$data",
4858 Local_Initialized_Data_Size
,
4861 * Scan the VMS symbols and fill in the data psect
4863 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4866 * Only look for undefined psects
4868 if (vsp
->Psect_Index
< 0)
4871 * And only initialized data
4873 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4874 vsp
->Psect_Index
= Data_Psect
;
4879 /******* Text Information and Relocation Records *******/
4881 * Write the text segment data
4886 * Scan the text fragments
4888 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4891 * Stop if we get to the data fragments
4893 if (fragP
== data_frag_root
)
4896 * Ignore fragments with no data
4898 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4901 * Go the the appropriate offset in the
4904 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4906 * Store the "fixed" part
4909 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4913 * Store the "variable" part
4915 if (fragP
->fr_var
&& fragP
->fr_offset
)
4916 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4923 * Now we go through the text segment fixups and
4924 * generate TIR records to fix up addresses within
4927 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4930 * We DO handle the case of "Symbol - Symbol" as
4931 * long as it is in the same segment.
4933 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4938 * They need to be in the same segment
4940 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4941 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4942 error ("Fixup data addsy and subsy didn't have the same type");
4944 * And they need to be in one that we
4945 * can check the psect on
4947 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4948 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4949 error ("Fixup data addsy and subsy didn't have an appropriate type");
4951 * This had better not be PC relative!
4954 error ("Fixup data was erroneously \"pcrel\"");
4956 * Subtract their values to get the
4959 i
= S_GET_VALUE (fixP
->fx_addsy
) -
4960 S_GET_VALUE (fixP
->fx_subsy
);
4962 * Now generate the fixup object records
4963 * Set the psect and store the data
4965 VMS_Set_Psect (Text_Psect
,
4967 fixP
->fx_frag
->fr_address
,
4969 VMS_Store_Immediate_Data (&i
,
4978 * Size will HAVE to be "long"
4980 if (fixP
->fx_size
!= sizeof (long))
4981 error ("Fixup datum was not a longword");
4983 * Symbol must be "added" (if it is ever
4985 * fix this assumption)
4987 if (fixP
->fx_addsy
== 0)
4988 error ("Fixup datum was not \"fixP->fx_addsy\"");
4990 * Store the symbol value in a PIC fashion
4992 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4997 fixP
->fx_frag
->fr_address
,
5000 * Check for indirect address reference,
5001 * which has to be fixed up (as the linker
5002 * will screw it up with TIR_S_C_STO_PICR).
5005 VMS_Fix_Indirect_Reference (Text_Psect
,
5007 fixP
->fx_frag
->fr_address
,
5013 * Store the Data segment:
5015 * Since this is REALLY hard to do any other way,
5016 * we actually manufacture the data segment and
5017 * the store the appropriate values out of it.
5018 * The segment was manufactured before, now we just
5019 * dump it into the appropriate psects.
5025 * Now we can run through all the data symbols
5026 * and store the data
5028 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5031 * Ignore anything other than data symbols
5033 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5036 * Set the Psect + Offset
5038 VMS_Set_Psect (vsp
->Psect_Index
,
5044 VMS_Store_Immediate_Data (Data_Segment
+
5045 S_GET_VALUE (vsp
->Symbol
) -
5051 * Now we go through the data segment fixups and
5052 * generate TIR records to fix up addresses within
5055 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5058 * Find the symbol for the containing datum
5060 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5063 * Only bother with Data symbols
5066 if (S_GET_TYPE (sp
) != N_DATA
)
5069 * Ignore symbol if After fixup
5071 if (S_GET_VALUE (sp
) >
5073 fixP
->fx_frag
->fr_address
))
5076 * See if the datum is here
5078 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5080 fixP
->fx_frag
->fr_address
))
5083 * We DO handle the case of "Symbol - Symbol" as
5084 * long as it is in the same segment.
5086 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5091 * They need to be in the same segment
5093 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5094 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5095 error ("Fixup data addsy and subsy didn't have the same type");
5097 * And they need to be in one that we
5098 * can check the psect on
5100 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5101 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5102 error ("Fixup data addsy and subsy didn't have an appropriate type");
5104 * This had better not be PC relative!
5107 error ("Fixup data was erroneously \"pcrel\"");
5109 * Subtract their values to get the
5112 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5113 S_GET_VALUE (fixP
->fx_subsy
);
5115 * Now generate the fixup object records
5116 * Set the psect and store the data
5118 VMS_Set_Psect (vsp
->Psect_Index
,
5119 fixP
->fx_frag
->fr_address
+
5121 S_GET_VALUE (vsp
->Symbol
) +
5124 VMS_Store_Immediate_Data (&i
,
5133 * Size will HAVE to be "long"
5135 if (fixP
->fx_size
!= sizeof (long))
5136 error ("Fixup datum was not a longword");
5138 * Symbol must be "added" (if it is ever
5140 * fix this assumption)
5142 if (fixP
->fx_addsy
== 0)
5143 error ("Fixup datum was not \"fixP->fx_addsy\"");
5145 * Store the symbol value in a PIC fashion
5147 VMS_Store_PIC_Symbol_Reference (
5152 fixP
->fx_frag
->fr_address
+
5154 S_GET_VALUE (vsp
->Symbol
) +
5167 * Write the Traceback Begin Module record
5169 VMS_TBT_Module_Begin ();
5171 * Scan the symbols and write out the routines
5172 * (this makes the assumption that symbols are in
5173 * order of ascending text segment offset)
5176 struct symbol
*Current_Routine
= 0;
5177 int Current_Line_Number
= 0;
5178 int Current_Offset
= -1;
5179 struct input_file
*Current_File
;
5181 /* Output debugging info for global variables and static variables that are not
5182 * specific to one routine. We also need to examine all stabs directives, to
5183 * find the definitions to all of the advanced data types, and this is done by
5184 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5185 * the object file, since there can be forward references in the stabs
5186 * directives. When through with parsing, the text of the stabs directive
5187 * is altered, with the definitions removed, so that later passes will see
5188 * directives as they would be written if the type were already defined.
5190 * We also look for files and include files, and make a list of them. We
5191 * examine the source file numbers to establish the actual lines that code was
5192 * generated from, and then generate offsets.
5195 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5198 * Deal with STAB symbols
5200 if (S_IS_DEBUG (symbolP
))
5203 * Dispatch on STAB type
5205 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5208 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5209 Current_File
->max_line
= S_GET_DESC (symbolP
);
5210 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5211 Current_File
->min_line
= S_GET_DESC (symbolP
);
5214 Current_File
= find_file (symbolP
);
5215 Current_File
->flag
= 1;
5216 Current_File
->min_line
= 1;
5219 Current_File
= find_file (symbolP
);
5222 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5225 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5227 case N_FUN
: /* For static constant symbols */
5229 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5235 /* now we take a quick sweep through the files and assign offsets
5236 to each one. This will essentially be the starting line number to the
5237 debugger for each file. Output the info for the debugger to specify the
5238 files, and then tell it how many lines to use */
5240 int File_Number
= 0;
5241 int Debugger_Offset
= 0;
5243 Current_File
= file_root
;
5244 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5246 if (Current_File
== (struct input_file
*) NULL
)
5248 if (Current_File
->max_line
== 0)
5250 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5253 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5256 /* show a few extra lines at the start of the region selected */
5257 if (Current_File
->min_line
> 2)
5258 Current_File
->min_line
-= 2;
5259 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5260 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5261 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5262 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5265 Current_File
->file_number
= ++File_Number
;
5266 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5267 Current_File
->file_number
);
5268 if (!file_available
)
5270 Current_File
->file_number
= 0;
5275 VMS_TBT_Source_Lines (Current_File
->file_number
,
5276 Current_File
->min_line
,
5277 Current_File
->max_line
- Current_File
->min_line
+ 1);
5280 Current_File
= (struct input_file
*) NULL
;
5282 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5285 * Deal with text symbols
5287 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5290 * Ignore symbols starting with "L",
5291 * as they are local symbols
5293 if (*S_GET_NAME (symbolP
) == 'L')
5296 * If there is a routine start defined,
5299 if (Current_Routine
)
5304 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5307 * Store the routine begin traceback info
5309 if (Text_Psect
!= -1)
5311 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5312 Current_Routine
= symbolP
;
5314 /* Output local symbols, i.e. all symbols that are associated with a specific
5315 * routine. We output them now so the debugger recognizes them as local to
5322 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5324 if (!S_IS_DEBUG (symbolP1
))
5326 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5328 pnt
= S_GET_NAME (symbolP
);
5329 pnt1
= S_GET_NAME (symbolP1
);
5332 while (*pnt
++ == *pnt1
++)
5335 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5336 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5339 if (symbolP1
!= (symbolS
*) NULL
)
5340 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5341 } /* local symbol block */
5348 * Deal with STAB symbols
5350 if (S_IS_DEBUG (symbolP
))
5353 * Dispatch on STAB type
5355 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5361 /* Offset the line into the correct portion
5363 if (Current_File
->file_number
== 0)
5365 /* Sometimes the same offset gets several source
5366 * lines assigned to it.
5367 * We should be selective about which lines
5368 * we allow, we should prefer lines that are
5369 * in the main source file when debugging
5370 * inline functions. */
5371 if ((Current_File
->file_number
!= 1) &&
5372 S_GET_VALUE (symbolP
) ==
5375 /* calculate actual debugger source line */
5376 S_GET_DESC (symbolP
)
5377 += Current_File
->offset
;
5379 * If this is the 1st N_SLINE, setup
5380 * PC/Line correlation. Otherwise
5381 * do the delta PC/Line. If the offset
5382 * for the line number is not +ve we need
5383 * to do another PC/Line correlation
5386 if (Current_Offset
== -1)
5388 VMS_TBT_Line_PC_Correlation (
5389 S_GET_DESC (symbolP
),
5390 S_GET_VALUE (symbolP
),
5396 if ((S_GET_DESC (symbolP
) -
5397 Current_Line_Number
) <= 0)
5400 * Line delta is not +ve, we
5401 * need to close the line and
5402 * start a new PC/Line
5405 VMS_TBT_Line_PC_Correlation (0,
5406 S_GET_VALUE (symbolP
) -
5410 VMS_TBT_Line_PC_Correlation (
5411 S_GET_DESC (symbolP
),
5412 S_GET_VALUE (symbolP
),
5419 * Line delta is +ve, all is well
5421 VMS_TBT_Line_PC_Correlation (
5422 S_GET_DESC (symbolP
) -
5423 Current_Line_Number
,
5424 S_GET_VALUE (symbolP
) -
5431 * Update the current line/PC
5433 Current_Line_Number
= S_GET_DESC (symbolP
);
5434 Current_Offset
= S_GET_VALUE (symbolP
);
5444 * Remember that we had a source file
5445 * and emit the source file debugger
5449 find_file (symbolP
);
5451 /* We need to make sure that we are really in the actual source file when
5452 * we compute the maximum line number. Otherwise the debugger gets really
5456 find_file (symbolP
);
5462 * If there is a routine start defined,
5463 * terminate it (and the line numbers)
5465 if (Current_Routine
)
5468 * Terminate the line numbers
5470 VMS_TBT_Line_PC_Correlation (0,
5471 text_siz
- S_GET_VALUE (Current_Routine
),
5475 * Terminate the routine
5477 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5481 * Write the Traceback End Module TBT record
5483 VMS_TBT_Module_End ();
5486 * Write the End Of Module record
5488 if (Entry_Point_Symbol
== 0)
5489 Write_VMS_EOM_Record (-1, 0);
5491 Write_VMS_EOM_Record (Text_Psect
,
5492 S_GET_VALUE (Entry_Point_Symbol
));
5495 * All done, close the object file
5497 Close_VMS_Object_File ();
5500 /* end of obj-vms.c */