1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
28 /* What we do if there is a goof. */
29 #define error as_fatal
31 #ifdef HO_VMS /* These are of no use if we are cross assembling. */
32 #include <fab.h> /* Define File Access Block */
33 #include <nam.h> /* Define NAM Block */
34 #include <xab.h> /* Define XAB - all different types*/
37 * Version string of the compiler that produced the code we are
38 * assembling. (And this assembler, if we do not have compiler info.)
40 char *compiler_version_string
;
42 /* Flag that determines how we map names. This takes several values, and
43 * is set with the -h switch. A value of zero implies names should be
44 * upper case, and the presence of the -h switch inhibits the case hack.
45 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
46 * A value of 2 (set with -h2) implies names should be
47 * all lower case, with no case hack. A value of 3 (set with -h3) implies
48 * that case should be preserved. */
50 /* If the -+ switch is given, then the hash is appended to any name that is
51 * longer than 31 characters, irregardless of the setting of the -h switch.
54 char vms_name_mapping
= 0;
57 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
60 * We augment the "gas" symbol structure with this
64 struct VMS_Symbol
*Next
;
65 struct symbol
*Symbol
;
70 struct VMS_Symbol
*VMS_Symbols
= 0;
72 /* We need this to keep track of the various input files, so that we can
73 * give the debugger the correct source line.
78 struct input_file
*next
;
79 struct input_file
*same_file_fpnt
;
89 static struct input_file
*file_root
= (struct input_file
*) NULL
;
92 static struct input_file
*find_file
PARAMS ((symbolS
*));
95 * This enum is used to keep track of the various types of variables that
101 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
105 * This structure contains the information from the stabs directives, and the
106 * information is filled in by VMS_typedef_parse. Everything that is needed
107 * to generate the debugging record for a given symbol is present here.
108 * This could be done more efficiently, using nested struct/unions, but for now
109 * I am happy that it works.
111 struct VMS_DBG_Symbol
113 struct VMS_DBG_Symbol
*next
;
114 /* description of what this is */
115 enum advanced_type advanced
;
116 /* this record is for this type */
118 /* For advanced types this is the type referred to. I.e., the type
119 a pointer points to, or the type of object that makes up an
122 /* Use this type when generating a variable def */
124 /* used for arrays - this will be present for all */
126 /* entries, but will be meaningless for non-arrays */
128 /* Size in bytes of the data type. For an array, this is the size
129 of one element in the array */
131 /* Number of the structure/union/enum - used for ref */
135 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
;
138 * We need this structure to keep track of forward references to
139 * struct/union/enum that have not been defined yet. When they are ultimately
140 * defined, then we can go back and generate the TIR commands to make a back
146 struct forward_ref
*next
;
152 struct forward_ref
*f_ref_root
=
153 {(struct forward_ref
*) NULL
};
156 * This routine is used to compare the names of certain types to various
157 * fixed types that are known by the debugger.
159 #define type_check(x) !strcmp( symbol_name , x )
162 * This variable is used to keep track of the name of the symbol we are
163 * working on while we are parsing the stabs directives.
165 static char *symbol_name
;
167 /* We use this counter to assign numbers to all of the structures, unions
168 * and enums that we define. When we actually declare a variable to the
169 * debugger, we can simply do it by number, rather than describing the
170 * whole thing each time.
173 static structure_count
= 0;
175 /* This variable is used to indicate that we are making the last attempt to
176 parse the stabs, and that we should define as much as we can, and ignore
179 static int final_pass
;
181 /* This variable is used to keep track of the current structure number
182 * for a given variable. If this is < 0, that means that the structure
183 * has not yet been defined to the debugger. This is still cool, since
184 * the VMS object language has ways of fixing things up after the fact,
185 * so we just make a note of this, and generate fixups at the end.
187 static int struct_number
;
191 * Variable descriptors are used tell the debugger the data types of certain
192 * more complicated variables (basically anything involving a structure,
193 * union, enum, array or pointer). Some non-pointer variables of the
194 * basic types that the debugger knows about do not require a variable
197 * Since it is impossible to have a variable descriptor longer than 128
198 * bytes by virtue of the way that the VMS object language is set up,
199 * it makes not sense to make the arrays any longer than this, or worrying
200 * about dynamic sizing of the array.
202 * These are the arrays and counters that we use to build a variable
206 #define MAX_DEBUG_RECORD 128
207 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
208 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
209 static int Lpnt
; /* index into Local */
210 static int Apoint
; /* index into Asuffix */
211 static char overflow
; /* flag to indicate we have written too much*/
212 static int total_len
; /* used to calculate the total length of variable
213 descriptor plus array descriptor - used for len byte*/
215 /* Flag if we have told user about finding global constants in the text
217 static gave_compiler_message
= 0;
219 /* A pointer to the current routine that we are working on. */
221 static symbolS
*Current_Routine
;
223 /* The psect number for $code a.k.a. the text section. */
225 static int Text_Psect
;
229 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
231 static int VMS_Object_File_FD
; /* File Descriptor for object file */
232 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
233 static int Object_Record_Offset
;/* Offset to end of data */
234 static int Current_Object_Record_Type
; /* Type of record in above */
237 * Macros for moving data around. Must work on big-endian systems.
239 #ifdef HO_VMS /* These are more efficient for VMS->VMS systems */
240 #define COPY_LONG(dest,val) {*(long *) dest = val; }
241 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
243 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
244 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
247 * Macros for placing data into the object record buffer
250 #define PUT_LONG(val) \
251 { md_number_to_chars(Object_Record_Buffer + \
252 Object_Record_Offset, val, 4); \
253 Object_Record_Offset += 4; }
255 #define PUT_SHORT(val) \
256 { md_number_to_chars(Object_Record_Buffer + \
257 Object_Record_Offset, val, 2); \
258 Object_Record_Offset += 2; }
260 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
262 #define PUT_COUNTED_STRING(cp) {\
263 register char *p = cp; \
264 PUT_CHAR(strlen(p)); \
265 while (*p) PUT_CHAR(*p++);}
268 * Macro for determining if a Name has psect attributes attached
271 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
272 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
274 #define HAS_PSECT_ATTRIBUTES(Name) \
275 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
276 PSECT_ATTRIBUTES_STRING, \
277 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
280 /* in: segT out: N_TYPE bits */
281 const short seg_N_TYPE
[] =
287 N_UNDF
, /* unknown */
289 N_UNDF
, /* expression */
293 N_REGISTER
, /* register */
296 const segT N_TYPE_seg
[N_TYPE
+ 2] =
297 { /* N_TYPE == 0x1E = 32-2 */
298 SEG_UNKNOWN
, /* N_UNDF == 0 */
300 SEG_ABSOLUTE
, /* N_ABS == 2 */
302 SEG_TEXT
, /* N_TEXT == 4 */
304 SEG_DATA
, /* N_DATA == 6 */
306 SEG_BSS
, /* N_BSS == 8 */
308 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
309 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
310 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
311 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
316 /* The following code defines the special types of pseudo-ops that we
327 temp
= get_absolute_expression ();
328 subseg_set (SEG_DATA
, (subsegT
) temp
);
330 demand_empty_rest_of_line ();
333 const pseudo_typeS obj_pseudo_table
[] =
335 {"const", s_const
, 0},
337 }; /* obj_pseudo_table */
340 vms_resolve_symbol_redef (sym
)
344 * If the new symbol is .comm AND it has a size of zero,
345 * we ignore it (i.e. the old symbol overrides it)
347 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)) &&
348 ((obstack_next_free (&frags
) - frag_now
->fr_literal
) == 0))
350 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
355 * If the old symbol is .comm and it has a size of zero,
356 * we override it with the new symbol value.
358 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
359 && (S_GET_VALUE(sym
) == 0))
361 as_warn ("compiler redefined zero-size common symbol `%s'",
363 sym
->sy_frag
= frag_now
;
364 S_GET_OTHER(sym
) = const_flag
;
365 S_SET_VALUE(sym
, obstack_next_free(& frags
) - frag_now
->fr_literal
);
366 /* Keep N_EXT bit. */
367 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
376 obj_read_begin_hook ()
381 obj_crawl_symbol_chain (headers
)
382 object_headers
*headers
;
386 int symbol_number
= 0;
388 { /* crawl symbol table */
389 register int symbol_number
= 0;
392 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
393 while ((symbolP
= *symbolPP
) != NULL
)
395 resolve_symbol_value (symbolP
);
397 /* OK, here is how we decide which symbols go out into the
398 brave new symtab. Symbols that do are:
400 * symbols with no name (stabd's?)
401 * symbols with debug info in their N_TYPE
403 Symbols that don't are:
404 * symbols that are registers
405 * symbols with \1 as their 3rd character (numeric labels)
406 * "local labels" as defined by S_LOCAL_NAME(name)
407 if the -L switch was passed to gas.
409 All other symbols are output. We complain if a deleted
410 symbol was marked external. */
413 if (!S_IS_REGISTER (symbolP
))
415 symbolP
->sy_name_offset
= 0;
416 symbolPP
= &(symbol_next (symbolP
));
420 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
422 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
425 } /* if this symbol should be in the output */
426 } /* for each symbol */
428 H_SET_STRING_SIZE (headers
, string_byte_count
);
429 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
430 } /* crawl symbol table */
432 } /* obj_crawl_symbol_chain() */
435 /****** VMS OBJECT FILE HACKING ROUTINES *******/
439 * Create the VMS object file
442 Create_VMS_Object_File ()
444 #if defined(eunice) || !defined(HO_VMS)
445 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
447 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
448 "mbc=16", "deq=64", "fop=tef", "shr=nil");
453 if (VMS_Object_File_FD
< 0)
455 char Error_Line
[256];
457 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
462 * Initialize object file hacking variables
464 Object_Record_Offset
= 0;
465 Current_Object_Record_Type
= -1;
470 * Flush the object record buffer to the object file
473 Flush_VMS_Object_Record_Buffer ()
479 * If the buffer is empty, we are done
481 if (Object_Record_Offset
== 0)
484 * Write the data to the file
486 #ifndef HO_VMS /* For cross-assembly purposes. */
487 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
488 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
489 #endif /* not HO_VMS */
490 i
= write (VMS_Object_File_FD
,
491 Object_Record_Buffer
,
492 Object_Record_Offset
);
493 if (i
!= Object_Record_Offset
)
494 error ("I/O error writing VMS object file");
495 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
497 /* pad it if needed */
499 if (Object_Record_Offset
& 1 != 0)
500 write (VMS_Object_File_FD
, &zero
, 1);
501 #endif /* not HO_VMS */
503 * The buffer is now empty
505 Object_Record_Offset
= 0;
510 * Declare a particular type of object file record
513 Set_VMS_Object_File_Record (Type
)
517 * If the type matches, we are done
519 if (Type
== Current_Object_Record_Type
)
522 * Otherwise: flush the buffer
524 Flush_VMS_Object_Record_Buffer ();
528 Current_Object_Record_Type
= Type
;
534 * Close the VMS Object file
537 Close_VMS_Object_File ()
539 short int m_one
= -1;
540 /* @@ This should not be here!! The same would presumably be needed
541 if we were writing vax-bsd a.out files on a vms system. Put it
543 #ifndef HO_VMS /* For cross-assembly purposes. */
544 /* Write a 0xffff into the file, which means "End of File" */
545 write (VMS_Object_File_FD
, &m_one
, 2);
546 #endif /* not HO_VMS */
547 close (VMS_Object_File_FD
);
552 * Store immediate data in current Psect
555 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
563 * We are writing a "Record_Type" record
565 Set_VMS_Object_File_Record (Record_Type
);
567 * We can only store 128 bytes at a time
572 * Store a maximum of 128 bytes
574 i
= (Size
> 128) ? 128 : Size
;
577 * If we cannot accommodate this record, flush the
580 if ((Object_Record_Offset
+ i
+ 1) >=
581 sizeof (Object_Record_Buffer
))
582 Flush_VMS_Object_Record_Buffer ();
584 * If the buffer is empty we must insert record type
586 if (Object_Record_Offset
== 0)
587 PUT_CHAR (Record_Type
);
591 PUT_CHAR (-i
& 0xff);
596 PUT_CHAR (*Pointer
++);
598 * Flush the buffer if it is more than 75% full
600 if (Object_Record_Offset
>
601 (sizeof (Object_Record_Buffer
) * 3 / 4))
602 Flush_VMS_Object_Record_Buffer ();
607 * Make a data reference
610 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
617 * We are writing a "Record_Type" record
619 Set_VMS_Object_File_Record (Record_Type
);
621 * If the buffer is empty we must insert the record type
623 if (Object_Record_Offset
== 0)
624 PUT_CHAR (Record_Type
);
626 * Stack the Psect base + Longword Offset
630 if (Psect_Index
> 127)
632 PUT_CHAR (TIR_S_C_STA_WPL
);
633 PUT_SHORT (Psect_Index
);
638 PUT_CHAR (TIR_S_C_STA_PL
);
639 PUT_CHAR (Psect_Index
);
647 PUT_CHAR (TIR_S_C_STA_WPL
);
648 PUT_SHORT (Psect_Index
);
651 else if (Offset
> 127)
653 PUT_CHAR (TIR_S_C_STA_WPW
);
654 PUT_SHORT (Psect_Index
);
659 PUT_CHAR (TIR_S_C_STA_WPB
);
660 PUT_SHORT (Psect_Index
);
665 * Set relocation base
667 PUT_CHAR (TIR_S_C_STO_PIDR
);
669 * Flush the buffer if it is more than 75% full
671 if (Object_Record_Offset
>
672 (sizeof (Object_Record_Buffer
) * 3 / 4))
673 Flush_VMS_Object_Record_Buffer ();
677 * Make a debugger reference to a struct, union or enum.
680 VMS_Store_Struct (Struct_Index
)
684 * We are writing a "OBJ_S_C_DBG" record
686 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
688 * If the buffer is empty we must insert the record type
690 if (Object_Record_Offset
== 0)
691 PUT_CHAR (OBJ_S_C_DBG
);
692 PUT_CHAR (TIR_S_C_STA_UW
);
693 PUT_SHORT (Struct_Index
);
694 PUT_CHAR (TIR_S_C_CTL_STKDL
);
695 PUT_CHAR (TIR_S_C_STO_L
);
697 * Flush the buffer if it is more than 75% full
699 if (Object_Record_Offset
>
700 (sizeof (Object_Record_Buffer
) * 3 / 4))
701 Flush_VMS_Object_Record_Buffer ();
705 * Make a debugger reference to partially define a struct, union or enum.
708 VMS_Def_Struct (Struct_Index
)
712 * We are writing a "OBJ_S_C_DBG" record
714 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
716 * If the buffer is empty we must insert the record type
718 if (Object_Record_Offset
== 0)
719 PUT_CHAR (OBJ_S_C_DBG
);
720 PUT_CHAR (TIR_S_C_STA_UW
);
721 PUT_SHORT (Struct_Index
);
722 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
724 * Flush the buffer if it is more than 75% full
726 if (Object_Record_Offset
>
727 (sizeof (Object_Record_Buffer
) * 3 / 4))
728 Flush_VMS_Object_Record_Buffer ();
732 VMS_Set_Struct (Struct_Index
)
734 { /* see previous functions for comments */
735 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
736 if (Object_Record_Offset
== 0)
737 PUT_CHAR (OBJ_S_C_DBG
);
738 PUT_CHAR (TIR_S_C_STA_UW
);
739 PUT_SHORT (Struct_Index
);
740 PUT_CHAR (TIR_S_C_CTL_STLOC
);
741 if (Object_Record_Offset
>
742 (sizeof (Object_Record_Buffer
) * 3 / 4))
743 Flush_VMS_Object_Record_Buffer ();
747 * Write the Traceback Module Begin record
750 VMS_TBT_Module_Begin ()
752 register char *cp
, *cp1
;
754 char Module_Name
[256];
758 * Get module name (the FILENAME part of the object file)
764 if ((*cp
== ']') || (*cp
== '>') ||
765 (*cp
== ':') || (*cp
== '/'))
771 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
775 * Limit it to 31 characters
777 while (--cp1
>= Module_Name
)
780 if (strlen (Module_Name
) > 31)
783 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
787 * Arrange to store the data locally (leave room for size byte)
793 *cp
++ = DST_S_C_MODBEG
;
799 * Language type == "C"
801 COPY_LONG (cp
, DST_S_C_C
);
804 * Store the module name
806 *cp
++ = strlen (Module_Name
);
811 * Now we can store the record size
816 * Put it into the object record
818 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
823 * Write the Traceback Module End record
826 VMS_TBT_Module_End ()
834 Local
[1] = DST_S_C_MODEND
;
836 * Put it into the object record
838 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
843 * Write the Traceback Routine Begin record
846 VMS_TBT_Routine_Begin (symbolP
, Psect
)
847 struct symbol
*symbolP
;
850 register char *cp
, *cp1
;
857 * Strip the leading "_" from the name
859 Name
= S_GET_NAME (symbolP
);
863 * Get the text psect offset
865 Offset
= S_GET_VALUE (symbolP
);
867 * Calculate the record size
869 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
877 Local
[1] = DST_S_C_RTNBEG
;
883 * Store the data so far
885 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
887 * Make sure we are still generating a OBJ_S_C_TBT record
889 if (Object_Record_Offset
== 0)
890 PUT_CHAR (OBJ_S_C_TBT
);
892 * Now get the symbol address
894 PUT_CHAR (TIR_S_C_STA_WPL
);
898 * Store the data reference
900 PUT_CHAR (TIR_S_C_STO_PIDR
);
902 * Store the counted string as data
906 Size
= strlen (cp1
) + 1;
910 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
915 * Write the Traceback Routine End record
916 * We *must* search the symbol table to find the next routine, since
917 * the assember has a way of reassembling the symbol table OUT OF ORDER
918 * Thus the next routine in the symbol list is not necessarily the
919 * next one in memory. For debugging to work correctly we must know the
920 * size of the routine.
923 VMS_TBT_Routine_End (Max_Size
, sp
)
928 int Size
= 0x7fffffff;
932 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
934 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
936 if (*S_GET_NAME (symbolP
) == 'L')
938 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
939 (S_GET_VALUE (symbolP
) < Size
))
940 Size
= S_GET_VALUE (symbolP
);
941 /* check if gcc_compiled. has size of zero */
942 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
944 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
945 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
946 Size
= S_GET_VALUE (symbolP
);
950 if (Size
== 0x7fffffff)
952 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
960 Local
[1] = DST_S_C_RTNEND
;
968 COPY_LONG (&Local
[3], Size
);
972 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
976 * Write the Traceback Block End record
979 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
980 struct symbol
*symbolP
;
984 register char *cp
, *cp1
;
991 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
997 * Begin Block - We simulate with a phony routine
999 Local
[1] = DST_S_C_BLKBEG
;
1005 * Store the data so far
1007 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1009 * Make sure we are still generating a OBJ_S_C_DBG record
1011 if (Object_Record_Offset
== 0)
1012 PUT_CHAR (OBJ_S_C_DBG
);
1014 * Now get the symbol address
1016 PUT_CHAR (TIR_S_C_STA_WPL
);
1019 * Get the text psect offset
1021 Offset
= S_GET_VALUE (symbolP
);
1024 * Store the data reference
1026 PUT_CHAR (TIR_S_C_STO_PIDR
);
1028 * Store the counted string as data
1032 Size
= strlen (cp1
) + 1;
1036 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1041 * Write the Traceback Block End record
1044 VMS_TBT_Block_End (Size
)
1050 * End block - simulate with a phony end routine
1053 Local
[1] = DST_S_C_BLKEND
;
1054 COPY_LONG (&Local
[3], Size
);
1059 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1065 * Write a Line number / PC correlation record
1068 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1078 * If not delta, set our PC/Line number correlation
1085 Local
[0] = 1 + 1 + 2 + 1 + 4;
1087 * Line Number/PC correlation
1089 Local
[1] = DST_S_C_LINE_NUM
;
1093 Local
[2] = DST_S_C_SET_LINE_NUM
;
1094 COPY_SHORT (&Local
[3], Line_Number
- 1);
1098 Local
[5] = DST_S_C_SET_ABS_PC
;
1099 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1101 * Make sure we are still generating a OBJ_S_C_TBT record
1103 if (Object_Record_Offset
== 0)
1104 PUT_CHAR (OBJ_S_C_TBT
);
1107 PUT_CHAR (TIR_S_C_STA_PL
);
1112 PUT_CHAR (TIR_S_C_STA_WPL
);
1116 PUT_CHAR (TIR_S_C_STO_PIDR
);
1118 * Do a PC offset of 0 to register the line number
1121 Local
[1] = DST_S_C_LINE_NUM
;
1122 Local
[2] = 0; /* Increment PC by 0 and register line # */
1123 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1128 * If Delta is negative, terminate the line numbers
1132 Local
[0] = 1 + 1 + 4;
1133 Local
[1] = DST_S_C_LINE_NUM
;
1134 Local
[2] = DST_S_C_TERM_L
;
1135 COPY_LONG (&Local
[3], Offset
);
1136 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1143 * Do a PC/Line delta
1146 *cp
++ = DST_S_C_LINE_NUM
;
1147 if (Line_Number
> 1)
1150 * We need to increment the line number
1152 if (Line_Number
- 1 <= 255)
1154 *cp
++ = DST_S_C_INCR_LINUM
;
1155 *cp
++ = Line_Number
- 1;
1159 *cp
++ = DST_S_C_INCR_LINUM_W
;
1160 COPY_SHORT (cp
, Line_Number
- 1);
1161 cp
+= sizeof (short);
1173 if (Offset
< 0x10000)
1175 *cp
++ = DST_S_C_DELTA_PC_W
;
1176 COPY_SHORT (cp
, Offset
);
1177 cp
+= sizeof (short);
1181 *cp
++ = DST_S_C_DELTA_PC_L
;
1182 COPY_LONG (cp
, Offset
);
1183 cp
+= sizeof (long);
1186 Local
[0] = cp
- (Local
+ 1);
1187 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1193 * Describe a source file to the debugger
1196 VMS_TBT_Source_File (Filename
, ID_Number
)
1200 register char *cp
, *cp1
;
1203 #ifndef HO_VMS /* Used for cross-assembly */
1204 i
= strlen (Filename
);
1206 static struct FAB Fab
;
1207 static struct NAM Nam
;
1208 static struct XABDAT Date_Xab
;
1209 static struct XABFHC File_Header_Xab
;
1210 char Es_String
[255], Rs_String
[255];
1215 Fab
.fab$b_bid
= FAB$C_BID
;
1216 Fab
.fab$b_bln
= sizeof (Fab
);
1217 Fab
.fab$l_nam
= (&Nam
);
1218 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1220 * Setup the Nam block so we can find out the FULL name
1221 * of the source file.
1223 Nam
.nam$b_bid
= NAM$C_BID
;
1224 Nam
.nam$b_bln
= sizeof (Nam
);
1225 Nam
.nam$l_rsa
= Rs_String
;
1226 Nam
.nam$b_rss
= sizeof (Rs_String
);
1227 Nam
.nam$l_esa
= Es_String
;
1228 Nam
.nam$b_ess
= sizeof (Es_String
);
1230 * Setup the Date and File Header Xabs
1232 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1233 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1234 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1235 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1236 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1238 * Get the file information
1240 Fab
.fab$l_fna
= Filename
;
1241 Fab
.fab$b_fns
= strlen (Filename
);
1242 Status
= sys$
open (&Fab
);
1245 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1251 * Calculate the size of the resultant string
1258 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1260 * Source declaration
1262 Local
[1] = DST_S_C_SOURCE
;
1264 * Make formfeeds count as source records
1266 Local
[2] = DST_S_C_SRC_FORMFEED
;
1268 * Declare source file
1270 Local
[3] = DST_S_C_SRC_DECLFILE
;
1271 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1280 COPY_SHORT (cp
, ID_Number
);
1281 cp
+= sizeof (short);
1284 * Creation Date. Unknown, so we fill with zeroes.
1287 cp
+= sizeof (long);
1289 cp
+= sizeof (long);
1294 cp
+= sizeof (long);
1299 cp
+= sizeof (short);
1309 #else /* Use this code when assembling for VMS on a VMS system */
1313 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1314 cp
+= sizeof (long);
1315 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1316 cp
+= sizeof (long);
1320 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1321 cp
+= sizeof (long);
1325 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1326 cp
+= sizeof (short);
1330 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1340 * Library module name (none)
1346 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1352 * Give the number of source lines to the debugger
1355 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1357 int Starting_Line_Number
;
1358 int Number_Of_Lines
;
1366 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1368 * Source declaration
1370 Local
[1] = DST_S_C_SOURCE
;
1375 *cp
++ = DST_S_C_SRC_SETFILE
;
1379 COPY_SHORT (cp
, ID_Number
);
1380 cp
+= sizeof (short);
1384 *cp
++ = DST_S_C_SRC_SETREC_L
;
1385 COPY_LONG (cp
, Starting_Line_Number
);
1386 cp
+= sizeof (long);
1390 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1391 COPY_SHORT (cp
, Number_Of_Lines
);
1392 cp
+= sizeof (short);
1396 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1402 /* This routine locates a file in the list of files. If an entry does not
1403 * exist, one is created. For include files, a new entry is always created
1404 * such that inline functions can be properly debugged. */
1405 static struct input_file
*
1409 struct input_file
*same_file
;
1410 struct input_file
*fpnt
;
1411 same_file
= (struct input_file
*) NULL
;
1412 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1414 if (fpnt
== (struct input_file
*) NULL
)
1416 if (fpnt
->spnt
== sp
)
1419 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1421 if (fpnt
== (struct input_file
*) NULL
)
1423 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1425 if (fpnt
->flag
== 1)
1431 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1432 if (file_root
== (struct input_file
*) NULL
)
1436 struct input_file
*fpnt1
;
1437 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1440 fpnt
->next
= (struct input_file
*) NULL
;
1441 fpnt
->name
= S_GET_NAME (sp
);
1442 fpnt
->min_line
= 0x7fffffff;
1446 fpnt
->file_number
= 0;
1448 fpnt
->same_file_fpnt
= same_file
;
1453 * The following functions and definitions are used to generate object records
1454 * that will describe program variables to the VMS debugger.
1456 * This file contains many of the routines needed to output debugging info into
1457 * the object file that the VMS debugger needs to understand symbols. These
1458 * routines are called very late in the assembly process, and thus we can be
1459 * fairly lax about changing things, since the GSD and the TIR sections have
1460 * already been output.
1464 /* This routine converts a number string into an integer, and stops when it
1465 * sees an invalid character the return value is the address of the character
1466 * just past the last character read. No error is generated.
1469 cvt_integer (str
, rtn
)
1474 neg
= *str
== '-' ? ++str
, -1 : 1;
1475 ival
= 0; /* first get the number of the type for dbx */
1476 while ((*str
<= '9') && (*str
>= '0'))
1477 ival
= 10 * ival
+ *str
++ - '0';
1482 /* this routine fixes the names that are generated by C++, ".this" is a good
1483 * example. The period does not work for the debugger, since it looks like
1484 * the syntax for a structure element, and thus it gets mightily confused
1486 * We also use this to strip the PsectAttribute hack from the name before we
1487 * write a debugger record */
1495 * Kill any leading "_"
1500 * Is there a Psect Attribute to skip??
1502 if (HAS_PSECT_ATTRIBUTES (pnt
))
1507 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1510 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1518 /* Here we fix the .this -> $this conversion */
1519 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1527 /* When defining a structure, this routine is called to find the name of
1528 * the actual structure. It is assumed that str points to the equal sign
1529 * in the definition, and it moves backward until it finds the start of the
1530 * name. If it finds a 0, then it knows that this structure def is in the
1531 * outermost level, and thus symbol_name points to the symbol name.
1534 get_struct_name (str
)
1539 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1544 while ((*pnt
!= ';') && (*pnt
!= '='))
1548 while ((*pnt
< '0') || (*pnt
> '9'))
1550 while ((*pnt
>= '0') && (*pnt
<= '9'))
1555 /* search symbol list for type number dbx_type. Return a pointer to struct */
1556 static struct VMS_DBG_Symbol
*
1557 find_symbol (dbx_type
)
1560 struct VMS_DBG_Symbol
*spnt
;
1561 spnt
= VMS_Symbol_type_list
;
1562 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1564 if (spnt
->dbx_type
== dbx_type
)
1568 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1569 return 0; /*Dunno what this is*/
1570 if(spnt
->advanced
== ALIAS
)
1571 return find_symbol(spnt
->type2
);
1576 /* this routine puts info into either Local or Asuffix, depending on the sign
1577 * of size. The reason is that it is easier to build the variable descriptor
1578 * backwards, while the array descriptor is best built forwards. In the end
1579 * they get put together, if there is not a struct/union/enum along the way
1598 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1602 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1605 Apoint
= MAX_DEBUG_RECORD
- 1;
1608 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1613 /* this routine generates the array descriptor for a given array */
1615 array_suffix (spnt2
)
1616 struct VMS_DBG_Symbol
*spnt2
;
1618 struct VMS_DBG_Symbol
*spnt
;
1619 struct VMS_DBG_Symbol
*spnt1
;
1625 while (spnt
->advanced
!= ARRAY
)
1627 spnt
= find_symbol (spnt
->type2
);
1628 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1634 while (spnt1
->advanced
== ARRAY
)
1637 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1638 spnt1
= find_symbol (spnt1
->type2
);
1640 total_size
= total_size
* spnt1
->data_size
;
1641 push (spnt1
->data_size
, 2);
1642 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1645 push (spnt1
->VMS_type
, 1);
1647 for (i
= 0; i
< 6; i
++)
1651 push (total_size
, 4);
1654 while (spnt1
->advanced
== ARRAY
)
1656 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1657 spnt1
= find_symbol (spnt1
->type2
);
1660 while (spnt1
->advanced
== ARRAY
)
1662 push (spnt1
->index_min
, 4);
1663 push (spnt1
->index_max
, 4);
1664 spnt1
= find_symbol (spnt1
->type2
);
1668 /* this routine generates the start of a variable descriptor based upon
1669 * a struct/union/enum that has yet to be defined. We define this spot as
1670 * a new location, and save four bytes for the address. When the struct is
1671 * finally defined, then we can go back and plug in the correct address
1674 new_forward_ref (dbx_type
)
1677 struct forward_ref
*fpnt
;
1678 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1679 fpnt
->next
= f_ref_root
;
1681 fpnt
->dbx_type
= dbx_type
;
1682 fpnt
->struc_numb
= ++structure_count
;
1683 fpnt
->resolved
= 'N';
1686 push (total_len
, -2);
1687 struct_number
= -fpnt
->struc_numb
;
1690 /* this routine generates the variable descriptor used to describe non-basic
1691 * variables. It calls itself recursively until it gets to the bottom of it
1692 * all, and then builds the descriptor backwards. It is easiest to do it this
1693 *way since we must periodically write length bytes, and it is easiest if we know
1694 *the value when it is time to write it.
1697 gen1 (spnt
, array_suffix_len
)
1698 struct VMS_DBG_Symbol
*spnt
;
1699 int array_suffix_len
;
1701 struct VMS_DBG_Symbol
*spnt1
;
1703 switch (spnt
->advanced
)
1706 push (DBG_S_C_VOID
, -1);
1708 push (total_len
, -2);
1712 if (array_suffix_len
== 0)
1714 push (spnt
->VMS_type
, -1);
1715 push (DBG_S_C_BASIC
, -1);
1717 push (total_len
, -2);
1727 struct_number
= spnt
->struc_numb
;
1728 if (struct_number
< 0)
1730 new_forward_ref (spnt
->dbx_type
);
1733 push (DBG_S_C_STRUCT
, -1);
1735 push (total_len
, -2);
1738 spnt1
= find_symbol (spnt
->type2
);
1740 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1741 new_forward_ref (spnt
->type2
);
1743 i
= gen1 (spnt1
, 0);
1745 { /* (*void) is a special case, do not put pointer suffix*/
1746 push (DBG_S_C_POINTER
, -1);
1748 push (total_len
, -2);
1753 while (spnt1
->advanced
== ARRAY
)
1755 spnt1
= find_symbol (spnt1
->type2
);
1756 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1758 printf ("gcc-as warning(debugger output):");
1759 printf ("Forward reference error, dbx type %d\n",
1764 /* It is too late to generate forward references, so the user gets a message.
1765 * This should only happen on a compiler error */
1766 i
= gen1 (spnt1
, 1);
1768 array_suffix (spnt
);
1769 array_suffix_len
= Apoint
- i
;
1770 switch (spnt1
->advanced
)
1778 push (total_len
, -2);
1781 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1783 total_len
+= array_suffix_len
+ 8;
1784 push (total_len
, -2);
1788 /* This generates a suffix for a variable. If it is not a defined type yet,
1789 * then dbx_type contains the type we are expecting so we can generate a
1790 * forward reference. This calls gen1 to build most of the descriptor, and
1791 * then it puts the icing on at the end. It then dumps whatever is needed
1792 * to get a complete descriptor (i.e. struct reference, array suffix ).
1795 generate_suffix (spnt
, dbx_type
)
1796 struct VMS_DBG_Symbol
*spnt
;
1801 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1802 struct VMS_DBG_Symbol
*spnt1
;
1804 Lpnt
= MAX_DEBUG_RECORD
- 1;
1808 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1809 new_forward_ref (dbx_type
);
1812 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1813 return 0; /* no suffix needed */
1818 push (total_len
, -1);
1819 /* if the variable descriptor overflows the record, output a descriptor for
1820 * a pointer to void.
1822 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1824 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1825 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1829 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1830 Local
[i
++] = Local
[++Lpnt
];
1832 /* we use this for a reference to a structure that has already been defined */
1833 if (struct_number
> 0)
1835 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1837 VMS_Store_Struct (struct_number
);
1839 /* we use this for a forward reference to a structure that has yet to be
1840 *defined. We store four bytes of zero to make room for the actual address once
1843 if (struct_number
< 0)
1845 struct_number
= -struct_number
;
1846 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1848 VMS_Def_Struct (struct_number
);
1849 for (i
= 0; i
< 4; i
++)
1851 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1856 Local
[Lpnt
++] = Asuffix
[i
++];
1858 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1862 /* This routine generates a symbol definition for a C sybmol for the debugger.
1863 * It takes a psect and offset for global symbols - if psect < 0, then this is
1864 * a local variable and the offset is relative to FP. In this case it can
1865 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1868 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1869 struct VMS_DBG_Symbol
*spnt
;
1879 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
1881 { /* this is a local variable, referenced to SP */
1882 maxlen
= 7 + strlen (Name_pnt
);
1883 Local
[i
++] = maxlen
;
1884 Local
[i
++] = spnt
->VMS_type
;
1886 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
1888 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
1889 COPY_LONG (&Local
[i
], Offset
);
1894 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
1895 Local
[i
++] = 7 + strlen (Name_pnt
);
1896 Local
[i
++] = spnt
->VMS_type
;
1898 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1900 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
1902 Local
[i
++] = strlen (Name_pnt
);
1903 while (*Name_pnt
!= '\0')
1904 Local
[i
++] = *Name_pnt
++;
1905 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1906 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1907 generate_suffix (spnt
, 0);
1911 /* This routine parses the stabs entries in order to make the definition
1912 * for the debugger of local symbols and function parameters
1915 VMS_local_stab_Parse (sp
)
1921 struct VMS_DBG_Symbol
*spnt
;
1922 struct VMS_Symbol
*vsp
;
1926 str
= S_GET_NAME (sp
);
1927 pnt
= (char *) strchr (str
, ':');
1928 if (pnt
== (char *) NULL
)
1929 return; /* no colon present */
1930 pnt1
= pnt
++; /* save this for later, and skip colon */
1932 return 0; /* ignore static constants */
1933 /* there is one little catch that we must be aware of. Sometimes function
1934 * parameters are optimized into registers, and the compiler, in its infiite
1935 * wisdom outputs stabs records for *both*. In general we want to use the
1936 * register if it is present, so we must search the rest of the symbols for
1937 * this function to see if this parameter is assigned to a register.
1945 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
1947 if (!S_IS_DEBUG (sp1
))
1949 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
1951 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
1952 if (*pnt3
== 'F' || *pnt3
== 'f') break;
1954 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
1956 str1
= S_GET_NAME (sp1
); /* and get the name */
1958 while (*pnt2
!= ':')
1965 if ((*str1
!= ':') || (*pnt2
!= ':'))
1967 return; /* they are the same! lets skip this one */
1969 /* first find the dbx symbol type from list, and then find VMS type */
1970 pnt
++; /* skip p in case no register */
1973 pnt
= cvt_integer (pnt
, &dbx_type
);
1974 spnt
= find_symbol (dbx_type
);
1975 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1976 return 0; /*Dunno what this is*/
1978 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
1979 *pnt1
= ':'; /* and restore the string */
1983 /* This routine parses a stabs entry to find the information required to define
1984 * a variable. It is used for global and static variables.
1985 * Basically we need to know the address of the symbol. With older versions
1986 * of the compiler, const symbols are
1987 * treated differently, in that if they are global they are written into the
1988 * text psect. The global symbol entry for such a const is actually written
1989 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
1990 * of psects, we must search the entry points as well. static consts are even
1991 * harder, since they are never assigned a memory address. The compiler passes
1992 * a stab to tell us the value, but I am not sure what to do with it.
1996 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
1999 int type1
, type2
, Text_Psect
;
2005 struct VMS_DBG_Symbol
*spnt
;
2006 struct VMS_Symbol
*vsp
;
2010 str
= S_GET_NAME (sp
);
2011 pnt
= (char *) strchr (str
, ':');
2012 if (pnt
== (char *) NULL
)
2013 return; /* no colon present */
2014 pnt1
= pnt
; /* save this for later*/
2016 if (*pnt
== expected_type
)
2018 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2019 spnt
= find_symbol (dbx_type
);
2020 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2021 return 0; /*Dunno what this is*/
2022 /* now we need to search the symbol table to find the psect and offset for
2027 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2029 pnt
= S_GET_NAME (vsp
->Symbol
);
2030 if (pnt
!= (char *) NULL
)
2032 /* make sure name is the same, and make sure correct symbol type */
2033 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2034 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2035 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2039 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2041 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2042 *pnt1
= ':'; /* and restore the string */
2045 /* the symbol was not in the symbol list, but it may be an "entry point"
2046 if it was a constant */
2047 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2050 * Dispatch on STAB type
2052 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2054 pnt
= S_GET_NAME (sp1
);
2057 if (strcmp (pnt
, str
) == 0)
2059 if (!gave_compiler_message
&& expected_type
== 'G')
2061 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2062 printf ("global constant(s) in the text psect. These will not be available to\n");
2063 printf ("other modules, since this is not the correct way to handle this. You\n");
2064 printf ("have two options: 1) get a patched compiler that does not put global\n");
2065 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2066 printf ("definitions of global variables in your source module(s). Don't say\n");
2067 printf ("I didn't warn you!");
2068 gave_compiler_message
= 1;
2070 VMS_DBG_record (spnt
,
2075 *S_GET_NAME (sp1
) = 'L';
2076 /* fool assembler to not output this
2077 * as a routine in the TBT */
2082 *pnt1
= ':'; /* and restore the string */
2087 VMS_GSYM_Parse (sp
, Text_Psect
)
2090 { /* Global variables */
2091 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2096 VMS_LCSYM_Parse (sp
, Text_Psect
)
2099 { /* Static symbols - uninitialized */
2100 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2104 VMS_STSYM_Parse (sp
, Text_Psect
)
2107 { /* Static symbols - initialized */
2108 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2112 /* for register symbols, we must figure out what range of addresses within the
2113 * psect are valid. We will use the brackets in the stab directives to give us
2114 * guidance as to the PC range that this variable is in scope. I am still not
2115 * completely comfortable with this but as I learn more, I seem to get a better
2116 * handle on what is going on.
2120 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2121 symbolS
*sp
, *Current_Routine
;
2128 struct VMS_DBG_Symbol
*spnt
;
2133 int Min_Offset
= -1; /* min PC of validity */
2134 int Max_Offset
= 0; /* max PC of validity */
2136 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2139 * Dispatch on STAB type
2141 switch (S_GET_RAW_TYPE (symbolP
))
2145 Min_Offset
= S_GET_VALUE (symbolP
);
2150 S_GET_VALUE (symbolP
) - 1;
2153 if ((Min_Offset
!= -1) && (bcnt
== 0))
2155 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2157 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2158 if (*pnt
== 'F' || *pnt
== 'f') break;
2161 /* check to see that the addresses were defined. If not, then there were no
2162 * brackets in the function, and we must try to search for the next function
2163 * Since functions can be in any order, we should search all of the symbol list
2164 * to find the correct ending address. */
2165 if (Min_Offset
== -1)
2167 int Max_Source_Offset
;
2169 Min_Offset
= S_GET_VALUE (sp
);
2170 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2173 * Dispatch on STAB type
2175 This_Offset
= S_GET_VALUE (symbolP
);
2176 switch (S_GET_RAW_TYPE (symbolP
))
2178 case N_TEXT
| N_EXT
:
2179 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2180 Max_Offset
= This_Offset
;
2183 if (This_Offset
> Max_Source_Offset
)
2184 Max_Source_Offset
= This_Offset
;
2187 /* if this is the last routine, then we use the PC of the last source line
2188 * as a marker of the max PC for which this reg is valid */
2189 if (Max_Offset
== 0x7fffffff)
2190 Max_Offset
= Max_Source_Offset
;
2193 str
= S_GET_NAME (sp
);
2194 pnt
= (char *) strchr (str
, ':');
2195 if (pnt
== (char *) NULL
)
2196 return; /* no colon present */
2197 pnt1
= pnt
; /* save this for later*/
2201 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2202 spnt
= find_symbol (dbx_type
);
2203 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2204 return 0; /*Dunno what this is yet*/
2206 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2207 maxlen
= 25 + strlen (pnt
);
2208 Local
[i
++] = maxlen
;
2209 Local
[i
++] = spnt
->VMS_type
;
2211 Local
[i
++] = strlen (pnt
) + 1;
2215 Local
[i
++] = strlen (pnt
);
2216 while (*pnt
!= '\0')
2217 Local
[i
++] = *pnt
++;
2223 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2225 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2226 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2228 Local
[i
++] = S_GET_VALUE (sp
);
2232 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2234 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2235 generate_suffix (spnt
, 0);
2238 /* this function examines a structure definition, checking all of the elements
2239 * to make sure that all of them are fully defined. The only thing that we
2240 * kick out are arrays of undefined structs, since we do not know how big
2241 * they are. All others we can handle with a normal forward reference.
2244 forward_reference (pnt
)
2248 struct VMS_DBG_Symbol
*spnt
;
2249 struct VMS_DBG_Symbol
*spnt1
;
2250 pnt
= cvt_integer (pnt
+ 1, &i
);
2252 return 0; /* no forward references */
2255 pnt
= (char *) strchr (pnt
, ':');
2256 pnt
= cvt_integer (pnt
+ 1, &i
);
2257 spnt
= find_symbol (i
);
2258 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2259 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2262 spnt1
= find_symbol (spnt
->type2
);
2263 if ((spnt
->advanced
== ARRAY
) &&
2264 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2266 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2271 pnt
= cvt_integer (pnt
+ 1, &i
);
2272 pnt
= cvt_integer (pnt
+ 1, &i
);
2273 } while (*++pnt
!= ';');
2274 return 0; /* no forward refences found */
2277 /* Used to check a single element of a structure on the final pass*/
2280 final_forward_reference (spnt
)
2281 struct VMS_DBG_Symbol
* spnt
;
2283 struct VMS_DBG_Symbol
* spnt1
;
2284 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2285 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2286 spnt1
= find_symbol(spnt
->type2
);
2287 if((spnt
->advanced
== ARRAY
) &&
2288 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2289 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2293 return 0; /* no forward refences found */
2296 /* This routine parses the stabs directives to find any definitions of dbx type
2297 * numbers. It makes a note of all of them, creating a structure element
2298 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2299 * debugger that describes the struct/union/enum, so that further references
2300 * to these data types will be by number
2301 * We have to process pointers right away, since there can be references
2302 * to them later in the same stabs directive. We cannot have forward
2303 * references to pointers, (but we can have a forward reference to a pointer to
2304 * a structure/enum/union) and this is why we process them immediately.
2305 * After we process the pointer, then we search for defs that are nested even
2307 * 8/15/92: We have to process arrays right away too, because there can
2308 * be multiple references to identical array types in one structure
2309 * definition, and only the first one has the definition. (We tend to
2310 * parse from the back going forward.
2313 VMS_typedef_parse (str
)
2321 struct forward_ref
*fpnt
;
2323 int convert_integer
;
2324 struct VMS_DBG_Symbol
*spnt
;
2325 struct VMS_DBG_Symbol
*spnt1
;
2326 /* check for any nested def's */
2327 pnt
= (char *) strchr (str
+ 1, '=');
2328 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2329 && (str
[1] != 'a' || str
[2] != 'r'))
2330 if (VMS_typedef_parse (pnt
) == 1)
2332 /* now find dbx_type of entry */
2335 { /* check for static constants */
2336 *str
= '\0'; /* for now we ignore them */
2339 while ((*pnt
<= '9') && (*pnt
>= '0'))
2341 pnt
++; /* and get back to the number */
2342 cvt_integer (pnt
, &i1
);
2343 spnt
= find_symbol (i1
);
2344 /* first we see if this has been defined already, due to a forward reference*/
2345 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2347 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2348 spnt
->next
= VMS_Symbol_type_list
;
2349 VMS_Symbol_type_list
= spnt
;
2350 spnt
->dbx_type
= i1
; /* and save the type */
2352 /* for structs and unions, do a partial parse, otherwise we sometimes get
2353 * circular definitions that are impossible to resolve. We read enough info
2354 * so that any reference to this type has enough info to be resolved
2356 pnt
= str
+ 1; /* point to character past equal sign */
2357 if ((*pnt
== 'u') || (*pnt
== 's'))
2360 if ((*pnt
<= '9') && (*pnt
>= '0'))
2362 if (type_check ("void"))
2363 { /* this is the void symbol */
2365 spnt
->advanced
= VOID
;
2368 if (type_check ("unknown type"))
2369 { /* this is the void symbol */
2371 spnt
->advanced
= UNKNOWN
;
2374 pnt1
= cvt_integer(pnt
,&i1
);
2375 if(i1
!= spnt
->dbx_type
)
2377 spnt
->advanced
= ALIAS
;
2382 printf ("gcc-as warning(debugger output):");
2383 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2384 return 1; /* do not know what this is */
2386 /* now define this module*/
2387 pnt
= str
+ 1; /* point to character past equal sign */
2391 spnt
->advanced
= BASIC
;
2392 if (type_check ("int"))
2394 spnt
->VMS_type
= DBG_S_C_SLINT
;
2395 spnt
->data_size
= 4;
2397 else if (type_check ("long int"))
2399 spnt
->VMS_type
= DBG_S_C_SLINT
;
2400 spnt
->data_size
= 4;
2402 else if (type_check ("unsigned int"))
2404 spnt
->VMS_type
= DBG_S_C_ULINT
;
2405 spnt
->data_size
= 4;
2407 else if (type_check ("long unsigned int"))
2409 spnt
->VMS_type
= DBG_S_C_ULINT
;
2410 spnt
->data_size
= 4;
2412 else if (type_check ("short int"))
2414 spnt
->VMS_type
= DBG_S_C_SSINT
;
2415 spnt
->data_size
= 2;
2417 else if (type_check ("short unsigned int"))
2419 spnt
->VMS_type
= DBG_S_C_USINT
;
2420 spnt
->data_size
= 2;
2422 else if (type_check ("char"))
2424 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2425 spnt
->data_size
= 1;
2427 else if (type_check ("signed char"))
2429 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2430 spnt
->data_size
= 1;
2432 else if (type_check ("unsigned char"))
2434 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2435 spnt
->data_size
= 1;
2437 else if (type_check ("float"))
2439 spnt
->VMS_type
= DBG_S_C_REAL4
;
2440 spnt
->data_size
= 4;
2442 else if (type_check ("double"))
2444 /* caveat: this assumes D_float, and is not correct for G_float */
2445 spnt
->VMS_type
= DBG_S_C_REAL8
;
2446 spnt
->data_size
= 8;
2448 else if (type_check ("long double"))
2450 /* same as double, at least for now */
2451 spnt
->VMS_type
= DBG_S_C_REAL8
;
2452 spnt
->data_size
= 8;
2454 else if (type_check ("long long int"))
2456 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2457 spnt
->data_size
= 8;
2459 else if (type_check ("long long unsigned int"))
2461 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2462 spnt
->data_size
= 8;
2466 /* something more substantial ought to be done here */
2468 spnt
->data_size
= 0;
2470 pnt1
= (char *) strchr (str
, ';') + 1;
2475 spnt
->advanced
= STRUCT
;
2477 spnt
->advanced
= UNION
;
2478 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2479 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2480 if (!final_pass
&& forward_reference(pnt
))
2482 spnt
->struc_numb
= -1;
2485 spnt
->struc_numb
= ++structure_count
;
2487 pnt
= get_struct_name (str
);
2488 VMS_Def_Struct (spnt
->struc_numb
);
2490 while (fpnt
!= (struct forward_ref
*) NULL
)
2492 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2494 fpnt
->resolved
= 'Y';
2495 VMS_Set_Struct (fpnt
->struc_numb
);
2496 VMS_Store_Struct (spnt
->struc_numb
);
2500 VMS_Set_Struct (spnt
->struc_numb
);
2502 Local
[i
++] = 11 + strlen (pnt
);
2503 Local
[i
++] = DBG_S_C_STRUCT_START
;
2505 for (i1
= 0; i1
< 4; i1
++)
2507 Local
[i
++] = strlen (pnt
);
2509 while (*pnt2
!= '\0')
2510 Local
[i
++] = *pnt2
++;
2511 i2
= spnt
->data_size
* 8; /* number of bits */
2512 COPY_LONG(&Local
[i
], i2
);
2514 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2516 if (pnt
!= symbol_name
)
2518 pnt
+= strlen (pnt
);
2520 } /* replace colon for later */
2521 while (*++pnt1
!= ';')
2523 pnt
= (char *) strchr (pnt1
, ':');
2526 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2527 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2528 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2529 if ((dtype
== 1) && (i3
!= 32))
2532 push (19 + strlen (pnt2
), 1);
2534 push (1 + strlen (pnt2
), 4);
2535 push (strlen (pnt2
), 1);
2536 while (*pnt2
!= '\0')
2538 push (i3
, 2); /* size of bitfield */
2541 push (i2
, 4); /* start position */
2542 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2547 Local
[i
++] = 7 + strlen (pnt2
);
2548 spnt1
= find_symbol (dtype
);
2549 /* check if this is a forward reference */
2550 if(final_pass
&& final_forward_reference(spnt1
))
2552 printf("gcc-as warning(debugger output):");
2553 printf("structure element %s has undefined type\n",pnt2
);
2557 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2558 Local
[i
++] = spnt1
->VMS_type
;
2560 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2561 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2562 COPY_LONG (&Local
[i
], i2
);
2564 Local
[i
++] = strlen (pnt2
);
2565 while (*pnt2
!= '\0')
2566 Local
[i
++] = *pnt2
++;
2567 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2569 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2570 generate_suffix (spnt1
, dtype
);
2571 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2572 generate_suffix (spnt1
, 0);
2576 Local
[i
++] = 0x01; /* length byte */
2577 Local
[i
++] = DBG_S_C_STRUCT_END
;
2578 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2582 spnt
->advanced
= ENUM
;
2583 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2584 spnt
->struc_numb
= ++structure_count
;
2585 spnt
->data_size
= 4;
2586 VMS_Def_Struct (spnt
->struc_numb
);
2588 while (fpnt
!= (struct forward_ref
*) NULL
)
2590 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2592 fpnt
->resolved
= 'Y';
2593 VMS_Set_Struct (fpnt
->struc_numb
);
2594 VMS_Store_Struct (spnt
->struc_numb
);
2598 VMS_Set_Struct (spnt
->struc_numb
);
2600 Local
[i
++] = 3 + strlen (symbol_name
);
2601 Local
[i
++] = DBG_S_C_ENUM_START
;
2603 Local
[i
++] = strlen (symbol_name
);
2605 while (*pnt2
!= '\0')
2606 Local
[i
++] = *pnt2
++;
2607 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2609 while (*++pnt
!= ';')
2611 pnt1
= (char *) strchr (pnt
, ':');
2613 pnt1
= cvt_integer (pnt1
, &i1
);
2614 Local
[i
++] = 7 + strlen (pnt
);
2615 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2617 COPY_LONG (&Local
[i
], i1
);
2619 Local
[i
++] = strlen (pnt
);
2621 while (*pnt
!= '\0')
2622 Local
[i
++] = *pnt
++;
2623 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2625 pnt
= pnt1
; /* Skip final semicolon */
2627 Local
[i
++] = 0x01; /* len byte */
2628 Local
[i
++] = DBG_S_C_ENUM_END
;
2629 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2634 spnt
->advanced
= ARRAY
;
2635 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2636 pnt
= (char *) strchr (pnt
, ';');
2637 if (pnt
== (char *) NULL
)
2639 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2640 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2641 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2642 pnt
=(char*)strchr(str
+1,'=');
2643 if((pnt
!= (char*) NULL
))
2644 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2647 spnt
->advanced
= FUNCTION
;
2648 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2649 /* this masquerades as a basic type*/
2650 spnt
->data_size
= 4;
2651 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2654 spnt
->advanced
= POINTER
;
2655 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2656 spnt
->data_size
= 4;
2657 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2658 pnt
= (char *) strchr (str
+ 1, '=');
2659 if ((pnt
!= (char *) NULL
))
2660 if (VMS_typedef_parse (pnt
) == 1)
2664 spnt
->advanced
= UNKNOWN
;
2666 printf ("gcc-as warning(debugger output):");
2667 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2668 return 1; /* unable to decipher */
2670 /* this removes the evidence of the definition so that the outer levels of
2671 parsing do not have to worry about it */
2673 while (*pnt1
!= '\0')
2681 * This is the root routine that parses the stabs entries for definitions.
2682 * it calls VMS_typedef_parse, which can in turn call itself.
2683 * We need to be careful, since sometimes there are forward references to
2684 * other symbol types, and these cannot be resolved until we have completed
2687 * Also check and see if we are using continuation stabs, if we are, then
2688 * paste together the entire contents of the stab before we pass it to
2689 * VMS_typedef_parse.
2698 char *parse_buffer
= 0;
2700 int incomplete
, i
, pass
, incom1
;
2701 struct VMS_DBG_Symbol
*spnt
;
2702 struct VMS_Symbol
*vsp
;
2703 struct forward_ref
*fpnt
;
2710 incom1
= incomplete
;
2712 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2715 * Deal with STAB symbols
2717 if (S_IS_DEBUG (sp
))
2720 * Dispatch on STAB type
2722 switch (S_GET_RAW_TYPE (sp
))
2730 case N_FUN
: /*sometimes these contain typedefs*/
2731 str
= S_GET_NAME (sp
);
2733 pnt
= str
+ strlen(str
) -1;
2734 if (*pnt
== '?') /* Continuation stab. */
2740 tlen
+= strlen(str
) - 1;
2741 spnext
= symbol_next (spnext
);
2742 str
= S_GET_NAME (spnext
);
2743 pnt
= str
+ strlen(str
) - 1;
2744 } while (*pnt
== '?');
2745 tlen
+= strlen(str
);
2746 parse_buffer
= (char *) xmalloc (tlen
+ 1);
2747 strcpy(parse_buffer
, S_GET_NAME (sp
));
2748 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2752 spnext
= symbol_next (spnext
);
2753 str
= S_GET_NAME (spnext
);
2754 strcat (pnt2
, S_GET_NAME (spnext
));
2755 pnt2
+= strlen(str
) - 1;
2756 *str
= '\0'; /* Erase this string */
2757 if (*pnt2
!= '?') break;
2763 pnt
= (char *) strchr (str
, ':');
2764 if (pnt
!= (char *) NULL
)
2768 pnt2
= (char *) strchr (pnt1
, '=');
2769 if (pnt2
!= (char *) NULL
)
2770 incomplete
+= VMS_typedef_parse (pnt2
);
2772 /* At this point the parse buffer should just contain name:nn.
2773 If it does not, then we are in real trouble. Anyway,
2774 this is always shorter than the original line. */
2775 strcpy(S_GET_NAME (sp
), parse_buffer
);
2776 free (parse_buffer
);
2779 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2786 /* Make one last pass, if needed, and define whatever we can that is left */
2787 if(final_pass
== 0 && incomplete
== incom1
)
2790 incom1
++; /* Force one last pass through */
2792 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2793 /* repeat until all refs resolved if possible */
2794 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2795 if (incomplete
!= 0)
2797 printf ("gcc-as warning(debugger output):");
2798 printf ("Unable to resolve %d circular references.\n", incomplete
);
2802 while (fpnt
!= (struct forward_ref
*) NULL
)
2804 if (fpnt
->resolved
!= 'Y')
2806 if (find_symbol (fpnt
->dbx_type
) !=
2807 (struct VMS_DBG_Symbol
*) NULL
)
2809 printf ("gcc-as warning(debugger output):");
2810 printf ("Forward reference error, dbx type %d\n",
2815 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2816 pnt2
= (char *) strchr (&fixit
[1], '=');
2817 VMS_typedef_parse (pnt2
);
2824 Define_Local_Symbols (s1
, s2
)
2828 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2830 if (symbolP1
== (symbolS
*) NULL
)
2832 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2834 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2835 if (*pnt
== 'F' || *pnt
== 'f') break;
2838 * Deal with STAB symbols
2840 if (S_IS_DEBUG (symbolP1
))
2843 * Dispatch on STAB type
2845 switch (S_GET_RAW_TYPE (symbolP1
))
2849 VMS_local_stab_Parse (symbolP1
);
2852 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
2860 /* This function crawls the symbol chain searching for local symbols that need
2861 * to be described to the debugger. When we enter a new scope with a "{", it
2862 * creates a new "block", which helps the debugger keep track of which scope
2863 * we are currently in.
2867 Define_Routine (symbolP
, Level
)
2877 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
2879 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2881 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2882 if (*pnt
== 'F' || *pnt
== 'f') break;
2885 * Deal with STAB symbols
2887 if (S_IS_DEBUG (symbolP1
))
2890 * Dispatch on STAB type
2892 switch (S_GET_RAW_TYPE (symbolP1
))
2897 sprintf (str
, "$%d", rcount
++);
2898 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
2900 Offset
= S_GET_VALUE (symbolP1
);
2901 Define_Local_Symbols (sstart
, symbolP1
);
2903 Define_Routine (symbolP1
, Level
+ 1);
2905 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
2914 /* we end up here if there were no brackets in this function. Define
2916 Define_Local_Symbols (sstart
, (symbolS
*) 0);
2922 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
2924 symbolS
*Curr_Routine
;
2927 Current_Routine
= Curr_Routine
;
2928 Text_Psect
= Txt_Psect
;
2929 Define_Routine (symbolP
, 0);
2936 #include <sys/types.h>
2939 /* Manufacure a VMS like time on a unix based system. */
2940 get_VMS_time_on_unix (Now
)
2946 pnt
= ctime (&timeb
);
2952 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
2955 #endif /* not HO_VMS */
2957 * Write the MHD (Module Header) records
2960 Write_VMS_MHD_Records ()
2962 register char *cp
, *cp1
;
2969 char Module_Name
[256];
2973 * We are writing a module header record
2975 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
2977 * ***************************
2978 * *MAIN MODULE HEADER RECORD*
2979 * ***************************
2981 * Store record type and header type
2983 PUT_CHAR (OBJ_S_C_HDR
);
2984 PUT_CHAR (MHD_S_C_MHD
);
2986 * Structure level is 0
2988 PUT_CHAR (OBJ_S_C_STRLVL
);
2990 * Maximum record size is size of the object record buffer
2992 PUT_SHORT (sizeof (Object_Record_Buffer
));
2994 * Get module name (the FILENAME part of the object file)
3000 if ((*cp
== ']') || (*cp
== '>') ||
3001 (*cp
== ':') || (*cp
== '/'))
3007 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3011 * Limit it to 31 characters and store in the object record
3013 while (--cp1
>= Module_Name
)
3016 if (strlen (Module_Name
) > 31)
3019 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3020 Module_Name
[31] = 0;
3022 PUT_COUNTED_STRING (Module_Name
);
3024 * Module Version is "V1.0"
3026 PUT_COUNTED_STRING ("V1.0");
3028 * Creation time is "now" (17 chars of time string)
3031 get_VMS_time_on_unix (&Now
[0]);
3033 Descriptor
.Size
= 17;
3034 Descriptor
.Ptr
= Now
;
3035 sys$
asctim (0, &Descriptor
, 0, 0);
3037 for (i
= 0; i
< 17; i
++)
3040 * Patch time is "never" (17 zeros)
3042 for (i
= 0; i
< 17; i
++)
3047 Flush_VMS_Object_Record_Buffer ();
3049 * *************************
3050 * *LANGUAGE PROCESSOR NAME*
3051 * *************************
3053 * Store record type and header type
3055 PUT_CHAR (OBJ_S_C_HDR
);
3056 PUT_CHAR (MHD_S_C_LNM
);
3058 * Store language processor name and version
3059 * (not a counted string!)
3061 * This is normally supplied by the gcc driver for the command line
3062 * which invokes gas. If absent, we fall back to gas's version.
3064 cp
= compiler_version_string
;
3077 Flush_VMS_Object_Record_Buffer ();
3082 * Write the EOM (End Of Module) record
3085 Write_VMS_EOM_Record (Psect
, Offset
)
3090 * We are writing an end-of-module record
3092 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3096 PUT_CHAR (OBJ_S_C_EOM
);
3098 * Store the error severity (0)
3102 * Store the entry point, if it exists
3107 * Store the entry point Psect
3111 * Store the entry point Psect offset
3118 Flush_VMS_Object_Record_Buffer ();
3122 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3128 register unsigned char *p
= ptr
;
3129 register unsigned char *end
= p
+ strlen (ptr
);
3130 register unsigned char c
;
3131 register int hash
= 0;
3136 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3142 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3145 VMS_Case_Hack_Symbol (In
, Out
)
3155 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3157 int Case_Hack_Bits
= 0;
3159 static char Hex_Table
[16] =
3160 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3163 * Kill any leading "_"
3165 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3168 new_name
= Out
; /* save this for later*/
3170 #if barfoo /* Dead code */
3171 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3175 /* We may need to truncate the symbol, save the hash for later*/
3176 if (strlen (In
) > 23)
3177 result
= hash_string (In
);
3179 * Is there a Psect Attribute to skip??
3181 if (HAS_PSECT_ATTRIBUTES (In
))
3186 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3189 if ((In
[0] == '$') && (In
[1] == '$'))
3199 /* if (strlen(In) > 31 && flagseen['+'])
3200 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3202 * Do the case conversion
3204 i
= 23; /* Maximum of 23 chars */
3205 while (*In
&& (--i
>= 0))
3207 Case_Hack_Bits
<<= 1;
3210 if ((destructor
== 1) && (i
== 21))
3212 switch (vms_name_mapping
)
3217 Case_Hack_Bits
|= 1;
3219 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3222 case 3: *Out
++ = *In
++;
3228 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3234 * If we saw a dollar sign, we don't do case hacking
3236 if (flagseen
['h'] || Saw_Dollar
)
3240 * If we have more than 23 characters and everything is lowercase
3241 * we can insert the full 31 characters
3246 * We have more than 23 characters
3247 * If we must add the case hack, then we have truncated the str
3251 if (Case_Hack_Bits
== 0)
3254 * And so far they are all lower case:
3255 * Check up to 8 more characters
3256 * and ensure that they are lowercase
3258 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3259 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3265 if ((i
== 8) || (In
[i
] == 0))
3268 * They are: Copy up to 31 characters
3269 * to the output string
3272 while ((--i
>= 0) && (*In
))
3273 switch (vms_name_mapping
){
3274 case 0: *Out
++ = islower(*In
) ?
3278 case 3: *Out
++ = *In
++;
3280 case 2: *Out
++ = isupper(*In
) ?
3289 * If there were any uppercase characters in the name we
3290 * take on the case hacking string
3293 /* Old behavior for regular GNU-C compiler */
3296 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3301 for (i
= 0; i
< 6; i
++)
3303 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3304 Case_Hack_Bits
>>= 4;
3310 Out
= pnt
; /*Cut back to 23 characters maximum */
3312 for (i
= 0; i
< 7; i
++)
3314 init
= result
& 0x01f;
3316 *Out
++ = '0' + init
;
3318 *Out
++ = 'A' + init
- 10;
3319 result
= result
>> 5;
3327 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3328 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3333 * Scan a symbol name for a psect attribute specification
3335 #define GLOBALSYMBOL_BIT 0x10000
3336 #define GLOBALVALUE_BIT 0x20000
3340 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3342 int *Attribute_Pointer
;
3353 {"PIC", GPS_S_M_PIC
},
3354 {"LIB", GPS_S_M_LIB
},
3355 {"OVR", GPS_S_M_OVR
},
3356 {"REL", GPS_S_M_REL
},
3357 {"GBL", GPS_S_M_GBL
},
3358 {"SHR", GPS_S_M_SHR
},
3359 {"EXE", GPS_S_M_EXE
},
3361 {"WRT", GPS_S_M_WRT
},
3362 {"VEC", GPS_S_M_VEC
},
3363 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3364 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3374 * Check for a PSECT attribute list
3376 if (!HAS_PSECT_ATTRIBUTES (Name
))
3377 return; /* If not, return */
3379 * Skip the attribute list indicator
3381 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3383 * Process the attributes ("_" separated, "$" terminated)
3385 while (*Name
!= '$')
3388 * Assume not negating
3394 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3397 * We are negating (and skip the NO)
3403 * Find the token delimiter
3406 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3409 * Look for the token in the attribute list
3411 for (i
= 0; Attributes
[i
].Name
; i
++)
3414 * If the strings match, set/clear the attr.
3416 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3422 *Attribute_Pointer
&=
3423 ~Attributes
[i
].Value
;
3425 *Attribute_Pointer
|=
3426 Attributes
[i
].Value
;
3434 * Now skip the attribute
3444 * Define a global symbol
3447 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3455 * We are writing a GSD record
3457 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3459 * If the buffer is empty we must insert the GSD record type
3461 if (Object_Record_Offset
== 0)
3462 PUT_CHAR (OBJ_S_C_GSD
);
3464 * We are writing a Global symbol definition subrecord
3466 if (Psect_Number
<= 255)
3468 PUT_CHAR (GSD_S_C_SYM
);
3472 PUT_CHAR (GSD_S_C_SYMW
);
3475 * Data type is undefined
3479 * Switch on Definition/Reference
3481 if ((Defined
& 1) != 0)
3485 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3486 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3488 if ((Defined
& 2) == 0)
3490 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3494 PUT_SHORT (GSY_S_M_DEF
);
3499 if (Psect_Number
<= 255)
3501 PUT_CHAR (Psect_Number
);
3505 PUT_SHORT (Psect_Number
);
3510 PUT_LONG (Psect_Offset
);
3516 * Flags = "RELOCATABLE" for regular symbol,
3517 * = "" for globalvalue (Defined & 2 == 1)
3519 if ((Defined
& 2) == 0)
3521 PUT_SHORT (GSY_S_M_REL
);
3529 * Finally, the global symbol name
3531 VMS_Case_Hack_Symbol (Name
, Local
);
3532 PUT_COUNTED_STRING (Local
);
3534 * Flush the buffer if it is more than 75% full
3536 if (Object_Record_Offset
>
3537 (sizeof (Object_Record_Buffer
) * 3 / 4))
3538 Flush_VMS_Object_Record_Buffer ();
3546 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3550 struct VMS_Symbol
*vsp
;
3553 int Psect_Attributes
;
3556 * Generate the appropriate PSECT flags given the PSECT type
3558 if (strcmp (Type
, "COMMON") == 0)
3561 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3563 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3564 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3566 else if (strcmp (Type
, "CONST") == 0)
3569 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3571 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3572 GPS_S_M_SHR
| GPS_S_M_RD
);
3574 else if (strcmp (Type
, "DATA") == 0)
3577 * The Data psects are PIC,REL,RD,WRT
3580 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3582 else if (strcmp (Type
, "TEXT") == 0)
3585 * The Text psects are PIC,REL,SHR,EXE,RD
3588 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3589 GPS_S_M_EXE
| GPS_S_M_RD
);
3594 * Error: Unknown psect type
3596 error ("Unknown VMS psect type");
3599 * Modify the psect attributes according to any attribute string
3601 if (HAS_PSECT_ATTRIBUTES (Name
))
3602 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3604 * Check for globalref/def/val.
3606 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3609 * globalvalue symbols were generated before. This code
3610 * prevents unsightly psect buildup, and makes sure that
3611 * fixup references are emitted correctly.
3613 vsp
->Psect_Index
= -1; /* to catch errors */
3614 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3615 return 1; /* decrement psect counter */
3618 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3620 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3622 case N_UNDF
| N_EXT
:
3623 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3624 vsp
->Psect_Offset
, 0);
3625 vsp
->Psect_Index
= -1;
3626 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3627 return 1; /* return and indicate no psect */
3628 case N_DATA
| N_EXT
:
3629 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3630 vsp
->Psect_Offset
, 1);
3631 /* In this case we still generate the psect */
3635 char Error_Line
[256];
3636 sprintf (Error_Line
,
3637 "Globalsymbol attribute for symbol %s was unexpected.\n",
3645 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3647 * We are writing a GSD record
3649 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3651 * If the buffer is empty we must insert the GSD record type
3653 if (Object_Record_Offset
== 0)
3654 PUT_CHAR (OBJ_S_C_GSD
);
3656 * We are writing a PSECT definition subrecord
3658 PUT_CHAR (GSD_S_C_PSC
);
3660 * Psects are always LONGWORD aligned
3664 * Specify the psect attributes
3666 PUT_SHORT (Psect_Attributes
);
3668 * Specify the allocation
3672 * Finally, the psect name
3674 VMS_Case_Hack_Symbol (Name
, Local
);
3675 PUT_COUNTED_STRING (Local
);
3677 * Flush the buffer if it is more than 75% full
3679 if (Object_Record_Offset
>
3680 (sizeof (Object_Record_Buffer
) * 3 / 4))
3681 Flush_VMS_Object_Record_Buffer ();
3687 * Given the pointer to a symbol we calculate how big the data at the
3688 * symbol is. We do this by looking for the next symbol (local or
3689 * global) which will indicate the start of another datum.
3692 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3693 register struct symbol
*sp
;
3696 struct symbol
*sp1
, *Next_Symbol
;
3697 /* Cache values to avoid extra lookups. */
3698 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
;
3701 * Find the next symbol
3702 * it delimits this datum
3705 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3708 * The data type must match
3710 if (S_GET_TYPE (sp1
) != N_DATA
)
3713 sp1_val
= S_GET_VALUE (sp1
);
3716 * The symbol must be AFTER this symbol
3718 if (sp1_val
<= sp_val
)
3721 * We ignore THIS symbol
3726 * If there is already a candidate selected for the
3727 * next symbol, see if we are a better candidate
3732 * We are a better candidate if we are "closer"
3735 if (sp1_val
> next_val
)
3739 * Make this the candidate
3745 * Calculate its size
3747 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
3751 * Check symbol names for the Psect hack with a globalvalue, and then
3752 * generate globalvalues for those that have it.
3755 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3760 register symbolS
*sp
;
3761 char *stripped_name
, *Name
;
3763 int Psect_Attributes
;
3767 * Scan the symbol table for globalvalues, and emit def/ref when
3768 * required. These will be caught again later and converted to
3771 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3774 * See if this is something we want to look at.
3776 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3777 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3780 * See if this has globalvalue specification.
3782 Name
= S_GET_NAME (sp
);
3784 if (!HAS_PSECT_ATTRIBUTES (Name
))
3787 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
3788 strcpy (stripped_name
, Name
);
3789 Psect_Attributes
= 0;
3790 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3792 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3794 switch (S_GET_RAW_TYPE (sp
))
3796 case N_UNDF
| N_EXT
:
3797 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3799 case N_DATA
| N_EXT
:
3800 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3802 error ("Invalid data type for globalvalue");
3803 globalvalue
= md_chars_to_number (Data_Segment
+
3804 S_GET_VALUE (sp
) - text_siz
, Size
);
3805 /* Three times for good luck. The linker seems to get confused
3806 if there are fewer than three */
3807 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3808 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3809 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3812 printf (" Invalid globalvalue of %s\n", stripped_name
);
3816 free (stripped_name
); /* clean up */
3823 * Define a procedure entry pt/mask
3826 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3835 * We are writing a GSD record
3837 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3839 * If the buffer is empty we must insert the GSD record type
3841 if (Object_Record_Offset
== 0)
3842 PUT_CHAR (OBJ_S_C_GSD
);
3844 * We are writing a Procedure Entry Pt/Mask subrecord
3846 if (Psect_Number
<= 255)
3848 PUT_CHAR (GSD_S_C_EPM
);
3852 PUT_CHAR (GSD_S_C_EPMW
);
3855 * Data type is undefined
3859 * Flags = "RELOCATABLE" and "DEFINED"
3861 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3865 if (Psect_Number
<= 255)
3867 PUT_CHAR (Psect_Number
);
3871 PUT_SHORT (Psect_Number
);
3876 PUT_LONG (Psect_Offset
);
3880 PUT_SHORT (Entry_Mask
);
3882 * Finally, the global symbol name
3884 VMS_Case_Hack_Symbol (Name
, Local
);
3885 PUT_COUNTED_STRING (Local
);
3887 * Flush the buffer if it is more than 75% full
3889 if (Object_Record_Offset
>
3890 (sizeof (Object_Record_Buffer
) * 3 / 4))
3891 Flush_VMS_Object_Record_Buffer ();
3896 * Set the current location counter to a particular Psect and Offset
3899 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
3905 * We are writing a "Record_Type" record
3907 Set_VMS_Object_File_Record (Record_Type
);
3909 * If the buffer is empty we must insert the record type
3911 if (Object_Record_Offset
== 0)
3912 PUT_CHAR (Record_Type
);
3914 * Stack the Psect base + Longword Offset
3916 if (Psect_Index
< 255)
3918 PUT_CHAR (TIR_S_C_STA_PL
);
3919 PUT_CHAR (Psect_Index
);
3923 PUT_CHAR (TIR_S_C_STA_WPL
);
3924 PUT_SHORT (Psect_Index
);
3928 * Set relocation base
3930 PUT_CHAR (TIR_S_C_CTL_SETRB
);
3932 * Flush the buffer if it is more than 75% full
3934 if (Object_Record_Offset
>
3935 (sizeof (Object_Record_Buffer
) * 3 / 4))
3936 Flush_VMS_Object_Record_Buffer ();
3941 * Store repeated immediate data in current Psect
3944 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
3946 register char *Pointer
;
3952 * Ignore zero bytes/words/longwords
3954 if ((Size
== sizeof (char)) && (*Pointer
== 0))
3956 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
3958 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
3961 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
3962 * then we do it manually
3966 while (--Repeat_Count
>= 0)
3967 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
3971 * We are writing a "Record_Type" record
3973 Set_VMS_Object_File_Record (Record_Type
);
3975 * If the buffer is empty we must insert record type
3977 if (Object_Record_Offset
== 0)
3978 PUT_CHAR (Record_Type
);
3980 * Stack the repeat count
3982 PUT_CHAR (TIR_S_C_STA_LW
);
3983 PUT_LONG (Repeat_Count
);
3985 * And now the command and its data
3987 PUT_CHAR (TIR_S_C_STO_RIVB
);
3990 PUT_CHAR (*Pointer
++);
3992 * Flush the buffer if it is more than 75% full
3994 if (Object_Record_Offset
>
3995 (sizeof (Object_Record_Buffer
) * 3 / 4))
3996 Flush_VMS_Object_Record_Buffer ();
4001 * Store a Position Independent Reference
4004 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4005 Psect
, Psect_Offset
, Record_Type
)
4006 struct symbol
*Symbol
;
4013 register struct VMS_Symbol
*vsp
=
4014 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4018 * We are writing a "Record_Type" record
4020 Set_VMS_Object_File_Record (Record_Type
);
4022 * If the buffer is empty we must insert record type
4024 if (Object_Record_Offset
== 0)
4025 PUT_CHAR (Record_Type
);
4027 * Set to the appropriate offset in the Psect
4032 * For a Code reference we need to fix the operand
4033 * specifier as well (so back up 1 byte)
4035 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4040 * For a Data reference we just store HERE
4042 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4045 * Make sure we are still generating a "Record Type" record
4047 if (Object_Record_Offset
== 0)
4048 PUT_CHAR (Record_Type
);
4050 * Dispatch on symbol type (so we can stack its value)
4052 switch (S_GET_RAW_TYPE (Symbol
))
4057 #ifdef NOT_VAX_11_C_COMPATIBLE
4058 case N_UNDF
| N_EXT
:
4059 case N_DATA
| N_EXT
:
4060 #endif /* NOT_VAX_11_C_COMPATIBLE */
4062 case N_TEXT
| N_EXT
:
4064 * Get the symbol name (case hacked)
4066 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4068 * Stack the global symbol value
4070 PUT_CHAR (TIR_S_C_STA_GBL
);
4071 PUT_COUNTED_STRING (Local
);
4075 * Stack the longword offset
4077 PUT_CHAR (TIR_S_C_STA_LW
);
4080 * Add the two, leaving the result on the stack
4082 PUT_CHAR (TIR_S_C_OPR_ADD
);
4086 * Uninitialized local data
4090 * Stack the Psect (+offset)
4092 if (vsp
->Psect_Index
< 255)
4094 PUT_CHAR (TIR_S_C_STA_PL
);
4095 PUT_CHAR (vsp
->Psect_Index
);
4099 PUT_CHAR (TIR_S_C_STA_WPL
);
4100 PUT_SHORT (vsp
->Psect_Index
);
4102 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4109 * Stack the Psect (+offset)
4111 if (vsp
->Psect_Index
< 255)
4113 PUT_CHAR (TIR_S_C_STA_PL
);
4114 PUT_CHAR (vsp
->Psect_Index
);
4118 PUT_CHAR (TIR_S_C_STA_WPL
);
4119 PUT_SHORT (vsp
->Psect_Index
);
4121 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4124 * Initialized local or global data
4127 #ifndef NOT_VAX_11_C_COMPATIBLE
4128 case N_UNDF
| N_EXT
:
4129 case N_DATA
| N_EXT
:
4130 #endif /* NOT_VAX_11_C_COMPATIBLE */
4132 * Stack the Psect (+offset)
4134 if (vsp
->Psect_Index
< 255)
4136 PUT_CHAR (TIR_S_C_STA_PL
);
4137 PUT_CHAR (vsp
->Psect_Index
);
4141 PUT_CHAR (TIR_S_C_STA_WPL
);
4142 PUT_SHORT (vsp
->Psect_Index
);
4144 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4148 * Store either a code or data reference
4150 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4152 * Flush the buffer if it is more than 75% full
4154 if (Object_Record_Offset
>
4155 (sizeof (Object_Record_Buffer
) * 3 / 4))
4156 Flush_VMS_Object_Record_Buffer ();
4161 * Check in the text area for an indirect pc-relative reference
4162 * and fix it up with addressing mode 0xff [PC indirect]
4164 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4165 * PIC CODE GENERATING FIXUP ROUTINE.
4168 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4171 register fragS
*fragP
;
4172 struct frag
*text_frag_root
;
4175 * The addressing mode byte is 1 byte before the address
4179 * Is it in THIS frag??
4181 if ((Offset
< fragP
->fr_address
) ||
4182 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4185 * We need to search for the fragment containing this
4188 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4190 if ((Offset
>= fragP
->fr_address
) &&
4191 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4195 * If we couldn't find the frag, things are BAD!!
4198 error ("Couldn't find fixup fragment when checking for indirect reference");
4201 * Check for indirect PC relative addressing mode
4203 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4205 static char Address_Mode
= 0xff;
4208 * Yes: Store the indirect mode back into the image
4209 * to fix up the damage done by STO_PICR
4211 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4212 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4217 * If the procedure "main()" exists we have to add the instruction
4218 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4220 VMS_Check_For_Main ()
4222 register symbolS
*symbolP
;
4223 #ifdef HACK_DEC_C_STARTUP /* JF */
4224 register struct frchain
*frchainP
;
4225 register fragS
*fragP
;
4226 register fragS
**prev_fragPP
;
4227 register struct fix
*fixP
;
4228 register fragS
*New_Frag
;
4230 #endif /* HACK_DEC_C_STARTUP */
4232 symbolP
= (struct symbol
*) symbol_find ("_main");
4233 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4234 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4236 #ifdef HACK_DEC_C_STARTUP
4241 * Remember the entry point symbol
4243 Entry_Point_Symbol
= symbolP
;
4244 #ifdef HACK_DEC_C_STARTUP
4249 * Scan all the fragment chains for the one with "_main"
4250 * (Actually we know the fragment from the symbol, but we need
4251 * the previous fragment so we can change its pointer)
4253 frchainP
= frchain_root
;
4257 * Scan all the fragments in this chain, remembering
4258 * the "previous fragment"
4260 prev_fragPP
= &frchainP
->frch_root
;
4261 fragP
= frchainP
->frch_root
;
4262 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4265 * Is this the fragment?
4267 if (fragP
== symbolP
->sy_frag
)
4270 * Yes: Modify the fragment by replacing
4271 * it with a new fragment.
4273 New_Frag
= (fragS
*)
4274 xmalloc (sizeof (*New_Frag
) +
4279 * The fragments are the same except
4280 * that the "fixed" area is larger
4283 New_Frag
->fr_fix
+= 6;
4285 * Copy the literal data opening a hole
4286 * 2 bytes after "_main" (i.e. just after
4287 * the entry mask). Into which we place
4288 * the JSB instruction.
4290 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4291 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4292 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4293 New_Frag
->fr_literal
[3] = 0xef;
4294 New_Frag
->fr_literal
[4] = 0;
4295 New_Frag
->fr_literal
[5] = 0;
4296 New_Frag
->fr_literal
[6] = 0;
4297 New_Frag
->fr_literal
[7] = 0;
4298 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4299 New_Frag
->fr_literal
[i
+ 6] =
4300 fragP
->fr_literal
[i
];
4302 * Now replace the old fragment with the
4303 * newly generated one.
4305 *prev_fragPP
= New_Frag
;
4307 * Remember the entry point symbol
4309 Entry_Point_Symbol
= symbolP
;
4311 * Scan the text area fixup structures
4312 * as offsets in the fragment may have
4315 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4318 * Look for references to this
4321 if (fixP
->fx_frag
== fragP
)
4324 * Change the fragment
4327 fixP
->fx_frag
= New_Frag
;
4329 * If the offset is after
4330 * the entry mask we need
4331 * to account for the JSB
4332 * instruction we just
4335 if (fixP
->fx_where
>= 2)
4336 fixP
->fx_where
+= 6;
4340 * Scan the symbols as offsets in the
4341 * fragment may have changed
4343 for (symbolP
= symbol_rootP
;
4345 symbolP
= symbol_next (symbolP
))
4348 * Look for references to this
4351 if (symbolP
->sy_frag
== fragP
)
4354 * Change the fragment
4357 symbolP
->sy_frag
= New_Frag
;
4359 * If the offset is after
4360 * the entry mask we need
4361 * to account for the JSB
4362 * instruction we just
4365 if (S_GET_VALUE (symbolP
) >= 2)
4366 S_SET_VALUE (symbolP
,
4367 S_GET_VALUE (symbolP
) + 6);
4371 * Make a symbol reference to
4372 * "_c$main_args" so we can get
4373 * its address inserted into the
4376 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4377 S_GET_NAME (symbolP
) = "_c$main_args";
4378 S_SET_TYPE (symbolP
, N_UNDF
);
4379 S_GET_OTHER (symbolP
) = 0;
4380 S_GET_DESC (symbolP
) = 0;
4381 S_SET_VALUE (symbolP
, 0);
4382 symbolP
->sy_name_offset
= 0;
4383 symbolP
->sy_number
= 0;
4384 symbolP
->sy_frag
= New_Frag
;
4385 symbolP
->sy_resolved
= 0;
4386 symbolP
->sy_resolving
= 0;
4387 /* this actually inserts at the beginning of the list */
4388 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4390 symbol_rootP
= symbolP
;
4392 * Generate a text fixup structure
4393 * to get "_c$main_args" stored into the
4396 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4397 fixP
->fx_frag
= New_Frag
;
4399 fixP
->fx_addsy
= symbolP
;
4401 fixP
->fx_offset
= 0;
4402 fixP
->fx_size
= sizeof (long);
4404 fixP
->fx_next
= text_fix_root
;
4405 text_fix_root
= fixP
;
4407 * Now make sure we exit from the loop
4413 * Try the next fragment
4415 prev_fragPP
= &fragP
->fr_next
;
4416 fragP
= fragP
->fr_next
;
4419 * Try the next fragment chain
4422 frchainP
= frchainP
->frch_next
;
4425 #endif /* HACK_DEC_C_STARTUP */
4430 * Write a VAX/VMS object file (everything else has been done!)
4432 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4437 struct frag
*text_frag_root
;
4438 struct frag
*data_frag_root
;
4440 register fragS
*fragP
;
4441 register symbolS
*symbolP
;
4442 register symbolS
*sp
;
4443 register struct fix
*fixP
;
4444 register struct VMS_Symbol
*vsp
;
4446 int Local_Initialized_Data_Size
= 0;
4448 int Psect_Number
= 0; /* Psect Index Number */
4449 int Text_Psect
= -1; /* Text Psect Index */
4450 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4451 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4454 * Create the VMS object file
4456 Create_VMS_Object_File ();
4458 * Write the module header records
4460 Write_VMS_MHD_Records ();
4463 * Store the Data segment:
4465 * Since this is REALLY hard to do any other way,
4466 * we actually manufacture the data segment and
4467 * the store the appropriate values out of it.
4468 * We need to generate this early, so that globalvalues
4469 * can be properly emitted.
4474 * Allocate the data segment
4476 Data_Segment
= (char *) xmalloc (data_siz
);
4478 * Run through the data fragments, filling in the segment
4480 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4482 register long int count
;
4483 register char *fill_literal
;
4484 register long int fill_size
;
4487 i
= fragP
->fr_address
- text_siz
;
4489 memcpy (Data_Segment
+ i
,
4494 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4495 fill_size
= fragP
->fr_var
;
4496 for (count
= fragP
->fr_offset
; count
; count
--)
4499 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4507 * Generate the VMS object file records
4508 * 1st GSD then TIR records
4511 /******* Global Symbol Dictionary *******/
4513 * Emit globalvalues now. We must do this before the text psect
4514 * is defined, or we will get linker warnings about multiply defined
4515 * symbols. All of the globalvalues "reference" psect 0, although
4516 * it really does not have anything to do with it.
4518 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4520 * Define the Text Psect
4522 Text_Psect
= Psect_Number
++;
4523 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4525 * Define the BSS Psect
4529 Bss_Psect
= Psect_Number
++;
4530 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4532 #ifndef gxx_bug_fixed
4534 * The g++ compiler does not write out external references to vtables
4535 * correctly. Check for this and holler if we see it happening.
4536 * If that compiler bug is ever fixed we can remove this.
4538 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4541 * Dispatch on symbol type
4543 switch (S_GET_RAW_TYPE (sp
)) {
4549 * Make a GSD global symbol reference
4552 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4554 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4555 S_GET_OTHER (sp
) = 1;
4556 /* Is this warning still needed? It sounds like it describes
4557 a compiler bug. Does it? If not, let's dump it. */
4558 as_warn("g++ wrote an extern reference to %s as a routine.",
4560 as_warn("I will fix it, but I hope that it was not really a routine");
4567 #endif /* gxx_bug_fixed */
4569 * Now scan the symbols and emit the appropriate GSD records
4571 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4574 * Dispatch on symbol type
4576 switch (S_GET_RAW_TYPE (sp
))
4579 * Global uninitialized data
4581 case N_UNDF
| N_EXT
:
4583 * Make a VMS data symbol entry
4585 vsp
= (struct VMS_Symbol
*)
4586 xmalloc (sizeof (*vsp
));
4588 vsp
->Size
= S_GET_VALUE (sp
);
4589 vsp
->Psect_Index
= Psect_Number
++;
4590 vsp
->Psect_Offset
= 0;
4591 vsp
->Next
= VMS_Symbols
;
4593 sp
->sy_number
= (int) vsp
;
4595 * Make the psect for this data
4597 if (S_GET_OTHER (sp
))
4598 Globalref
= VMS_Psect_Spec (
4604 Globalref
= VMS_Psect_Spec (
4612 /* See if this is an external vtable. We want to help the linker find
4613 these things in libraries, so we make a symbol reference. This
4614 is not compatible with VAX-C usage for variables, but since vtables are
4615 only used internally by g++, we can get away with this hack. */
4617 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4618 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4623 #ifdef NOT_VAX_11_C_COMPATIBLE
4625 * Place a global symbol at the
4626 * beginning of the Psect
4628 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4632 #endif /* NOT_VAX_11_C_COMPATIBLE */
4635 * Local uninitialized data
4639 * Make a VMS data symbol entry
4641 vsp
= (struct VMS_Symbol
*)
4642 xmalloc (sizeof (*vsp
));
4645 vsp
->Psect_Index
= Bss_Psect
;
4648 bss_address_frag
.fr_address
;
4649 vsp
->Next
= VMS_Symbols
;
4651 sp
->sy_number
= (int) vsp
;
4654 * Global initialized data
4656 case N_DATA
| N_EXT
:
4658 * Make a VMS data symbol entry
4660 vsp
= (struct VMS_Symbol
*)
4661 xmalloc (sizeof (*vsp
));
4663 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4664 text_siz
+ data_siz
);
4665 vsp
->Psect_Index
= Psect_Number
++;
4666 vsp
->Psect_Offset
= 0;
4667 vsp
->Next
= VMS_Symbols
;
4669 sp
->sy_number
= (int) vsp
;
4673 if (S_GET_OTHER (sp
))
4674 Globalref
= VMS_Psect_Spec (
4680 Globalref
= VMS_Psect_Spec (
4688 /* See if this is an external vtable. We want to help the linker find
4689 these things in libraries, so we make a symbol definition. This
4690 is not compatible with VAX-C usage for variables, but since vtables are
4691 only used internally by g++, we can get away with this hack. */
4693 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4694 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4699 #ifdef NOT_VAX_11_C_COMPATIBLE
4701 * Place a global symbol at the
4702 * beginning of the Psect
4704 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4708 #endif /* NOT_VAX_11_C_COMPATIBLE */
4711 * Local initialized data
4715 * Make a VMS data symbol entry
4717 vsp
= (struct VMS_Symbol
*)
4718 xmalloc (sizeof (*vsp
));
4721 VMS_Initialized_Data_Size (sp
,
4722 text_siz
+ data_siz
);
4723 vsp
->Psect_Index
= Data_Psect
;
4725 Local_Initialized_Data_Size
;
4726 Local_Initialized_Data_Size
+= vsp
->Size
;
4727 vsp
->Next
= VMS_Symbols
;
4729 sp
->sy_number
= (int) vsp
;
4732 * Global Text definition
4734 case N_TEXT
| N_EXT
:
4736 unsigned short Entry_Mask
;
4739 * Get the entry mask
4741 fragP
= sp
->sy_frag
;
4743 /* If first frag doesn't contain the data, what do we do?
4744 If it's possibly smaller than two bytes, that would
4745 imply that the entry mask is not stored where we're
4748 If you can find a test case that triggers this, report
4749 it (and tell me what the entry mask field ought to be),
4750 and I'll try to fix it. KR */
4751 /* First frag might be empty if we're generating listings.
4752 So skip empty rs_fill frags. */
4753 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
4754 fragP
= fragP
->fr_next
;
4756 if (fragP
->fr_fix
< 2)
4759 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4760 ((fragP
->fr_literal
[1] & 0xff)
4763 * Define the Procedure entry pt.
4765 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4772 * Local Text definition
4776 * Make a VMS data symbol entry
4778 if (Text_Psect
!= -1)
4780 vsp
= (struct VMS_Symbol
*)
4781 xmalloc (sizeof (*vsp
));
4784 vsp
->Psect_Index
= Text_Psect
;
4785 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4786 vsp
->Next
= VMS_Symbols
;
4788 sp
->sy_number
= (int) vsp
;
4796 * Make a GSD global symbol reference
4799 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4809 * Ignore STAB symbols
4810 * Including .stabs emitted by g++
4812 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4817 if (S_GET_TYPE (sp
) != 22)
4818 printf (" ERROR, unknown type (%d)\n",
4824 * Define the Data Psect
4826 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4831 Data_Psect
= Psect_Number
++;
4832 VMS_Psect_Spec ("$data",
4833 Local_Initialized_Data_Size
,
4836 * Scan the VMS symbols and fill in the data psect
4838 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4841 * Only look for undefined psects
4843 if (vsp
->Psect_Index
< 0)
4846 * And only initialized data
4848 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4849 vsp
->Psect_Index
= Data_Psect
;
4854 /******* Text Information and Relocation Records *******/
4856 * Write the text segment data
4861 * Scan the text fragments
4863 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4866 * Stop if we get to the data fragments
4868 if (fragP
== data_frag_root
)
4871 * Ignore fragments with no data
4873 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4876 * Go the the appropriate offset in the
4879 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4881 * Store the "fixed" part
4884 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4888 * Store the "variable" part
4890 if (fragP
->fr_var
&& fragP
->fr_offset
)
4891 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4898 * Now we go through the text segment fixups and
4899 * generate TIR records to fix up addresses within
4902 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4905 * We DO handle the case of "Symbol - Symbol" as
4906 * long as it is in the same segment.
4908 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4913 * They need to be in the same segment
4915 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4916 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4917 error ("Fixup data addsy and subsy didn't have the same type");
4919 * And they need to be in one that we
4920 * can check the psect on
4922 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4923 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4924 error ("Fixup data addsy and subsy didn't have an appropriate type");
4926 * This had better not be PC relative!
4929 error ("Fixup data was erroneously \"pcrel\"");
4931 * Subtract their values to get the
4934 i
= S_GET_VALUE (fixP
->fx_addsy
) -
4935 S_GET_VALUE (fixP
->fx_subsy
);
4937 * Now generate the fixup object records
4938 * Set the psect and store the data
4940 VMS_Set_Psect (Text_Psect
,
4942 fixP
->fx_frag
->fr_address
,
4944 VMS_Store_Immediate_Data (&i
,
4953 * Size will HAVE to be "long"
4955 if (fixP
->fx_size
!= sizeof (long))
4956 error ("Fixup datum was not a longword");
4958 * Symbol must be "added" (if it is ever
4960 * fix this assumption)
4962 if (fixP
->fx_addsy
== 0)
4963 error ("Fixup datum was not \"fixP->fx_addsy\"");
4965 * Store the symbol value in a PIC fashion
4967 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4972 fixP
->fx_frag
->fr_address
,
4975 * Check for indirect address reference,
4976 * which has to be fixed up (as the linker
4977 * will screw it up with TIR_S_C_STO_PICR).
4980 VMS_Fix_Indirect_Reference (Text_Psect
,
4982 fixP
->fx_frag
->fr_address
,
4988 * Store the Data segment:
4990 * Since this is REALLY hard to do any other way,
4991 * we actually manufacture the data segment and
4992 * the store the appropriate values out of it.
4993 * The segment was manufactured before, now we just
4994 * dump it into the appropriate psects.
5000 * Now we can run through all the data symbols
5001 * and store the data
5003 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5006 * Ignore anything other than data symbols
5008 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5011 * Set the Psect + Offset
5013 VMS_Set_Psect (vsp
->Psect_Index
,
5019 VMS_Store_Immediate_Data (Data_Segment
+
5020 S_GET_VALUE (vsp
->Symbol
) -
5026 * Now we go through the data segment fixups and
5027 * generate TIR records to fix up addresses within
5030 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5033 * Find the symbol for the containing datum
5035 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5038 * Only bother with Data symbols
5041 if (S_GET_TYPE (sp
) != N_DATA
)
5044 * Ignore symbol if After fixup
5046 if (S_GET_VALUE (sp
) >
5048 fixP
->fx_frag
->fr_address
))
5051 * See if the datum is here
5053 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5055 fixP
->fx_frag
->fr_address
))
5058 * We DO handle the case of "Symbol - Symbol" as
5059 * long as it is in the same segment.
5061 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5066 * They need to be in the same segment
5068 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5069 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5070 error ("Fixup data addsy and subsy didn't have the same type");
5072 * And they need to be in one that we
5073 * can check the psect on
5075 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5076 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5077 error ("Fixup data addsy and subsy didn't have an appropriate type");
5079 * This had better not be PC relative!
5082 error ("Fixup data was erroneously \"pcrel\"");
5084 * Subtract their values to get the
5087 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5088 S_GET_VALUE (fixP
->fx_subsy
);
5090 * Now generate the fixup object records
5091 * Set the psect and store the data
5093 VMS_Set_Psect (vsp
->Psect_Index
,
5094 fixP
->fx_frag
->fr_address
+
5096 S_GET_VALUE (vsp
->Symbol
) +
5099 VMS_Store_Immediate_Data (&i
,
5108 * Size will HAVE to be "long"
5110 if (fixP
->fx_size
!= sizeof (long))
5111 error ("Fixup datum was not a longword");
5113 * Symbol must be "added" (if it is ever
5115 * fix this assumption)
5117 if (fixP
->fx_addsy
== 0)
5118 error ("Fixup datum was not \"fixP->fx_addsy\"");
5120 * Store the symbol value in a PIC fashion
5122 VMS_Store_PIC_Symbol_Reference (
5127 fixP
->fx_frag
->fr_address
+
5129 S_GET_VALUE (vsp
->Symbol
) +
5142 * Write the Traceback Begin Module record
5144 VMS_TBT_Module_Begin ();
5146 * Scan the symbols and write out the routines
5147 * (this makes the assumption that symbols are in
5148 * order of ascending text segment offset)
5151 struct symbol
*Current_Routine
= 0;
5152 int Current_Line_Number
= 0;
5153 int Current_Offset
= -1;
5154 struct input_file
*Current_File
;
5156 /* Output debugging info for global variables and static variables that are not
5157 * specific to one routine. We also need to examine all stabs directives, to
5158 * find the definitions to all of the advanced data types, and this is done by
5159 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5160 * the object file, since there can be forward references in the stabs
5161 * directives. When through with parsing, the text of the stabs directive
5162 * is altered, with the definitions removed, so that later passes will see
5163 * directives as they would be written if the type were already defined.
5165 * We also look for files and include files, and make a list of them. We
5166 * examine the source file numbers to establish the actual lines that code was
5167 * generated from, and then generate offsets.
5170 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5173 * Deal with STAB symbols
5175 if (S_IS_DEBUG (symbolP
))
5178 * Dispatch on STAB type
5180 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5183 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5184 Current_File
->max_line
= S_GET_DESC (symbolP
);
5185 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5186 Current_File
->min_line
= S_GET_DESC (symbolP
);
5189 Current_File
= find_file (symbolP
);
5190 Current_File
->flag
= 1;
5191 Current_File
->min_line
= 1;
5194 Current_File
= find_file (symbolP
);
5197 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5200 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5202 case N_FUN
: /* For static constant symbols */
5204 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5210 /* now we take a quick sweep through the files and assign offsets
5211 to each one. This will essentially be the starting line number to the
5212 debugger for each file. Output the info for the debugger to specify the
5213 files, and then tell it how many lines to use */
5215 int File_Number
= 0;
5216 int Debugger_Offset
= 0;
5218 Current_File
= file_root
;
5219 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5221 if (Current_File
== (struct input_file
*) NULL
)
5223 if (Current_File
->max_line
== 0)
5225 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5228 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5231 /* show a few extra lines at the start of the region selected */
5232 if (Current_File
->min_line
> 2)
5233 Current_File
->min_line
-= 2;
5234 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5235 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5236 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5237 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5240 Current_File
->file_number
= ++File_Number
;
5241 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5242 Current_File
->file_number
);
5243 if (!file_available
)
5245 Current_File
->file_number
= 0;
5250 VMS_TBT_Source_Lines (Current_File
->file_number
,
5251 Current_File
->min_line
,
5252 Current_File
->max_line
- Current_File
->min_line
+ 1);
5255 Current_File
= (struct input_file
*) NULL
;
5257 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5260 * Deal with text symbols
5262 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5265 * Ignore symbols starting with "L",
5266 * as they are local symbols
5268 if (*S_GET_NAME (symbolP
) == 'L')
5271 * If there is a routine start defined,
5274 if (Current_Routine
)
5279 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5282 * Store the routine begin traceback info
5284 if (Text_Psect
!= -1)
5286 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5287 Current_Routine
= symbolP
;
5289 /* Output local symbols, i.e. all symbols that are associated with a specific
5290 * routine. We output them now so the debugger recognizes them as local to
5297 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5299 if (!S_IS_DEBUG (symbolP1
))
5301 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5303 pnt
= S_GET_NAME (symbolP
);
5304 pnt1
= S_GET_NAME (symbolP1
);
5307 while (*pnt
++ == *pnt1
++)
5310 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5311 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5314 if (symbolP1
!= (symbolS
*) NULL
)
5315 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5316 } /* local symbol block */
5323 * Deal with STAB symbols
5325 if (S_IS_DEBUG (symbolP
))
5328 * Dispatch on STAB type
5330 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5336 /* Offset the line into the correct portion
5338 if (Current_File
->file_number
== 0)
5340 /* Sometimes the same offset gets several source
5341 * lines assigned to it.
5342 * We should be selective about which lines
5343 * we allow, we should prefer lines that are
5344 * in the main source file when debugging
5345 * inline functions. */
5346 if ((Current_File
->file_number
!= 1) &&
5347 S_GET_VALUE (symbolP
) ==
5350 /* calculate actual debugger source line */
5351 S_GET_DESC (symbolP
)
5352 += Current_File
->offset
;
5354 * If this is the 1st N_SLINE, setup
5355 * PC/Line correlation. Otherwise
5356 * do the delta PC/Line. If the offset
5357 * for the line number is not +ve we need
5358 * to do another PC/Line correlation
5361 if (Current_Offset
== -1)
5363 VMS_TBT_Line_PC_Correlation (
5364 S_GET_DESC (symbolP
),
5365 S_GET_VALUE (symbolP
),
5371 if ((S_GET_DESC (symbolP
) -
5372 Current_Line_Number
) <= 0)
5375 * Line delta is not +ve, we
5376 * need to close the line and
5377 * start a new PC/Line
5380 VMS_TBT_Line_PC_Correlation (0,
5381 S_GET_VALUE (symbolP
) -
5385 VMS_TBT_Line_PC_Correlation (
5386 S_GET_DESC (symbolP
),
5387 S_GET_VALUE (symbolP
),
5394 * Line delta is +ve, all is well
5396 VMS_TBT_Line_PC_Correlation (
5397 S_GET_DESC (symbolP
) -
5398 Current_Line_Number
,
5399 S_GET_VALUE (symbolP
) -
5406 * Update the current line/PC
5408 Current_Line_Number
= S_GET_DESC (symbolP
);
5409 Current_Offset
= S_GET_VALUE (symbolP
);
5419 * Remember that we had a source file
5420 * and emit the source file debugger
5424 find_file (symbolP
);
5426 /* We need to make sure that we are really in the actual source file when
5427 * we compute the maximum line number. Otherwise the debugger gets really
5431 find_file (symbolP
);
5437 * If there is a routine start defined,
5438 * terminate it (and the line numbers)
5440 if (Current_Routine
)
5443 * Terminate the line numbers
5445 VMS_TBT_Line_PC_Correlation (0,
5446 text_siz
- S_GET_VALUE (Current_Routine
),
5450 * Terminate the routine
5452 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5456 * Write the Traceback End Module TBT record
5458 VMS_TBT_Module_End ();
5461 * Write the End Of Module record
5463 if (Entry_Point_Symbol
== 0)
5464 Write_VMS_EOM_Record (-1, 0);
5466 Write_VMS_EOM_Record (Text_Psect
,
5467 S_GET_VALUE (Entry_Point_Symbol
));
5470 * All done, close the object file
5472 Close_VMS_Object_File ();
5475 /* end of obj-vms.c */