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
27 /* What we do if there is a goof. */
28 #define error as_fatal
30 #ifdef HO_VMS /* These are of no use if we are cross assembling. */
31 #include <fab.h> /* Define File Access Block */
32 #include <nam.h> /* Define NAM Block */
33 #include <xab.h> /* Define XAB - all different types*/
36 * Version string of the compiler that produced the code we are
37 * assembling. (And this assembler, if we do not have compiler info.)
39 extern const char version_string
[];
40 char *compiler_version_string
;
42 /* Flag that determines how we map names. This takes several values, and
43 * is set with the -h switch. A value of zero implies names should be
44 * upper case, and the presence of the -h switch inhibits the case hack.
45 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
46 * A value of 2 (set with -h2) implies names should be
47 * all lower case, with no case hack. A value of 3 (set with -h3) implies
48 * that case should be preserved. */
50 /* If the -+ switch is given, then the hash is appended to any name that is
51 * longer than 31 characters, irregardless of the setting of the -h switch.
54 char vms_name_mapping
= 0;
57 extern char *strchr ();
59 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
62 * We augment the "gas" symbol structure with this
66 struct VMS_Symbol
*Next
;
67 struct symbol
*Symbol
;
72 struct VMS_Symbol
*VMS_Symbols
= 0;
74 /* We need this to keep track of the various input files, so that we can
75 * give the debugger the correct source line.
80 struct input_file
*next
;
81 struct input_file
*same_file_fpnt
;
91 static struct input_file
*file_root
= (struct input_file
*) NULL
;
94 static struct input_file
*find_file
PARAMS ((symbolS
*));
97 * This enum is used to keep track of the various types of variables that
103 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, UNKNOWN
107 * This structure contains the information from the stabs directives, and the
108 * information is filled in by VMS_typedef_parse. Everything that is needed
109 * to generate the debugging record for a given symbol is present here.
110 * This could be done more efficiently, using nested struct/unions, but for now
111 * I am happy that it works.
113 struct VMS_DBG_Symbol
115 struct VMS_DBG_Symbol
*next
;
116 enum advanced_type advanced
; /* description of what this is */
117 int dbx_type
; /* this record is for this type */
118 int type2
; /* For advanced types this is the type referred to.
119 i.e. the type a pointer points to, or the type
120 of object that makes up an array */
121 int VMS_type
; /* Use this type when generating a variable def */
122 int index_min
; /* used for arrays - this will be present for all */
123 int index_max
; /* entries, but will be meaningless for non-arrays */
124 int data_size
; /* size in bytes of the data type. For an array, this
125 is the size of one element in the array */
126 int struc_numb
; /* Number of the structure/union/enum - used for ref */
129 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
=
130 {(struct VMS_DBG_Symbol
*) NULL
};
133 * We need this structure to keep track of forward references to
134 * struct/union/enum that have not been defined yet. When they are ultimately
135 * defined, then we can go back and generate the TIR commands to make a back
141 struct forward_ref
*next
;
147 struct forward_ref
*f_ref_root
=
148 {(struct forward_ref
*) NULL
};
151 * This routine is used to compare the names of certain types to various
152 * fixed types that are known by the debugger.
154 #define type_check(x) !strcmp( symbol_name , x )
157 * This variable is used to keep track of the name of the symbol we are
158 * working on while we are parsing the stabs directives.
160 static char *symbol_name
;
162 /* We use this counter to assign numbers to all of the structures, unions
163 * and enums that we define. When we actually declare a variable to the
164 * debugger, we can simply do it by number, rather than describing the
165 * whole thing each time.
168 static structure_count
= 0;
170 /* This variable is used to keep track of the current structure number
171 * for a given variable. If this is < 0, that means that the structure
172 * has not yet been defined to the debugger. This is still cool, since
173 * the VMS object language has ways of fixing things up after the fact,
174 * so we just make a note of this, and generate fixups at the end.
176 static int struct_number
;
180 * Variable descriptors are used tell the debugger the data types of certain
181 * more complicated variables (basically anything involving a structure,
182 * union, enum, array or pointer). Some non-pointer variables of the
183 * basic types that the debugger knows about do not require a variable
186 * Since it is impossible to have a variable descriptor longer than 128
187 * bytes by virtue of the way that the VMS object language is set up,
188 * it makes not sense to make the arrays any longer than this, or worrying
189 * about dynamic sizing of the array.
191 * These are the arrays and counters that we use to build a variable
195 #define MAX_DEBUG_RECORD 128
196 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
197 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
198 static int Lpnt
; /* index into Local */
199 static int Apoint
; /* index into Asuffix */
200 static char overflow
; /* flag to indicate we have written too much*/
201 static int total_len
; /* used to calculate the total length of variable
202 descriptor plus array descriptor - used for len byte*/
204 /* Flag if we have told user about finding global constants in the text
206 static gave_compiler_message
= 0;
208 /* A pointer to the current routine that we are working on. */
210 static symbolS
*Current_Routine
;
212 /* The psect number for $code a.k.a. the text section. */
214 static int Text_Psect
;
218 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
220 static int VMS_Object_File_FD
; /* File Descriptor for object file */
221 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
222 static int Object_Record_Offset
;/* Offset to end of data */
223 static int Current_Object_Record_Type
; /* Type of record in above */
226 * Macros for placing data into the object record buffer
229 #define PUT_LONG(val) \
230 { md_number_to_chars(Object_Record_Buffer + \
231 Object_Record_Offset, val, 4); \
232 Object_Record_Offset += 4; }
234 #define PUT_SHORT(val) \
235 { md_number_to_chars(Object_Record_Buffer + \
236 Object_Record_Offset, val, 2); \
237 Object_Record_Offset += 2; }
239 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
241 #define PUT_COUNTED_STRING(cp) {\
242 register char *p = cp; \
243 PUT_CHAR(strlen(p)); \
244 while (*p) PUT_CHAR(*p++);}
247 * Macro for determining if a Name has psect attributes attached
250 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
251 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
253 #define HAS_PSECT_ATTRIBUTES(Name) \
254 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
255 PSECT_ATTRIBUTES_STRING, \
256 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
259 /* in: segT out: N_TYPE bits */
260 const short seg_N_TYPE
[] =
266 N_UNDF
, /* unknown */
270 N_UNDF
, /* bignum/flonum */
271 N_UNDF
, /* difference */
275 N_REGISTER
, /* register */
278 const segT N_TYPE_seg
[N_TYPE
+ 2] =
279 { /* N_TYPE == 0x1E = 32-2 */
280 SEG_UNKNOWN
, /* N_UNDF == 0 */
282 SEG_ABSOLUTE
, /* N_ABS == 2 */
284 SEG_TEXT
, /* N_TEXT == 4 */
286 SEG_DATA
, /* N_DATA == 6 */
288 SEG_BSS
, /* N_BSS == 8 */
290 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
291 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
292 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
293 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
298 /* The following code defines the special types of pseudo-ops that we
309 temp
= get_absolute_expression ();
310 subseg_new (SEG_DATA
, (subsegT
) temp
);
312 demand_empty_rest_of_line ();
318 * Handle .stabX directives, which used to be open-coded.
319 * So much creeping featurism overloaded the semantics that we decided
320 * to put all .stabX thinking in one place. Here.
322 * We try to make any .stabX directive legal. Other people's AS will often
323 * do assembly-time consistency checks: eg assigning meaning to n_type bits
324 * and "protecting" you from setting them to certain values. (They also zero
325 * certain bits before emitting symbols. Tut tut.)
327 * If an expression is not absolute we either gripe or use the relocation
328 * information. Other people's assemblers silently forget information they
329 * don't need and invent information they need that you didn't supply.
331 * .stabX directives always make a symbol table entry. It may be junk if
332 * the rest of your .stabX directive is malformed.
338 register symbolS
*symbolP
= 0;
339 register char *string
;
342 int goof
; /* TRUE if we have aborted. */
346 * Enter with input_line_pointer pointing past .stabX and any following
349 goof
= 0; /* JF who forgot this?? */
352 string
= demand_copy_C_string (&length
);
354 if (*input_line_pointer
== ',')
355 input_line_pointer
++;
358 as_bad ("I need a comma after symbol's name");
366 * Input_line_pointer->after ','. String->symbol name.
370 symbolP
= symbol_new (string
,
377 S_SET_NAME (symbolP
, NULL
); /* .stabd feature. */
378 S_SET_VALUE (symbolP
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
379 symbolP
->sy_frag
= frag_now
;
383 symbolP
->sy_frag
= &zero_address_frag
;
387 symbolP
->sy_frag
= &zero_address_frag
;
395 if (get_absolute_expression_and_terminator (&longint
) == ',')
396 symbolP
->sy_symbol
.n_type
= saved_type
= longint
;
399 as_bad ("I want a comma after the n_type expression");
401 input_line_pointer
--; /* Backup over a non-',' char. */
407 if (get_absolute_expression_and_terminator (&longint
) == ',')
408 S_SET_OTHER (symbolP
, longint
);
411 as_bad ("I want a comma after the n_other expression");
413 input_line_pointer
--; /* Backup over a non-',' char. */
419 S_SET_DESC (symbolP
, get_absolute_expression ());
420 if (what
== 's' || what
== 'n')
422 if (*input_line_pointer
!= ',')
424 as_bad ("I want a comma after the n_desc expression");
429 input_line_pointer
++;
434 if ((!goof
) && (what
== 's' || what
== 'n'))
436 pseudo_set (symbolP
);
437 symbolP
->sy_symbol
.n_type
= saved_type
;
441 ignore_rest_of_line ();
443 demand_empty_rest_of_line ();
444 } /* obj_aout_stab() */
446 const pseudo_typeS obj_pseudo_table
[] =
448 {"stabd", obj_aout_stab
, 'd'},/* stabs */
449 {"stabn", obj_aout_stab
, 'n'},/* stabs */
450 {"stabs", obj_aout_stab
, 's'},/* stabs */
451 {"const", s_const
, 0},
454 }; /* obj_pseudo_table */
457 obj_read_begin_hook ()
460 } /* obj_read_begin_hook() */
463 obj_crawl_symbol_chain (headers
)
464 object_headers
*headers
;
468 int symbol_number
= 0;
470 /* JF deal with forward references first... */
471 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
473 if (symbolP
->sy_forward
)
475 S_SET_VALUE (symbolP
, S_GET_VALUE (symbolP
)
476 + S_GET_VALUE (symbolP
->sy_forward
)
477 + symbolP
->sy_forward
->sy_frag
->fr_address
);
478 symbolP
->sy_forward
= 0;
479 } /* if it has a forward reference */
480 } /* walk the symbol chain */
482 { /* crawl symbol table */
483 register int symbol_number
= 0;
486 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
487 while ((symbolP
= *symbolPP
) != NULL
)
489 S_GET_VALUE (symbolP
) += symbolP
->sy_frag
->fr_address
;
491 /* OK, here is how we decide which symbols go out into the
492 brave new symtab. Symbols that do are:
494 * symbols with no name (stabd's?)
495 * symbols with debug info in their N_TYPE
497 Symbols that don't are:
498 * symbols that are registers
499 * symbols with \1 as their 3rd character (numeric labels)
500 * "local labels" as defined by S_LOCAL_NAME(name)
501 if the -L switch was passed to gas.
503 All other symbols are output. We complain if a deleted
504 symbol was marked external. */
507 if (!S_IS_REGISTER (symbolP
))
509 symbolP
->sy_name_offset
= 0;
510 symbolPP
= &(symbol_next (symbolP
));
514 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
516 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
519 } /* if this symbol should be in the output */
520 } /* for each symbol */
522 H_SET_STRING_SIZE (headers
, string_byte_count
);
523 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
524 } /* crawl symbol table */
526 } /* obj_crawl_symbol_chain() */
529 /****** VMS OBJECT FILE HACKING ROUTINES *******/
533 * Create the VMS object file
536 Create_VMS_Object_File ()
538 #if defined(eunice) || !defined(HO_VMS)
539 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
541 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
542 "mbc=16", "deq=64", "fop=tef", "shr=nil");
547 if (VMS_Object_File_FD
< 0)
549 char Error_Line
[256];
551 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
556 * Initialize object file hacking variables
558 Object_Record_Offset
= 0;
559 Current_Object_Record_Type
= -1;
564 * Flush the object record buffer to the object file
567 Flush_VMS_Object_Record_Buffer ()
572 * If the buffer is empty, we are done
574 if (Object_Record_Offset
== 0)
577 * Write the data to the file
579 #ifndef HO_VMS /* For cross-assembly purposes. */
580 i
= write (VMS_Object_File_FD
, &Object_Record_Offset
, 2);
581 #endif /* not HO_VMS */
582 i
= write (VMS_Object_File_FD
,
583 Object_Record_Buffer
,
584 Object_Record_Offset
);
585 if (i
!= Object_Record_Offset
)
586 error ("I/O error writing VMS object file");
587 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
589 /* pad it if needed */
591 if (Object_Record_Offset
& 1 != 0)
592 write (VMS_Object_File_FD
, &zero
, 1);
593 #endif /* not HO_VMS */
595 * The buffer is now empty
597 Object_Record_Offset
= 0;
602 * Declare a particular type of object file record
605 Set_VMS_Object_File_Record (Type
)
609 * If the type matches, we are done
611 if (Type
== Current_Object_Record_Type
)
614 * Otherwise: flush the buffer
616 Flush_VMS_Object_Record_Buffer ();
620 Current_Object_Record_Type
= Type
;
626 * Close the VMS Object file
629 Close_VMS_Object_File ()
631 short int m_one
= -1;
632 #ifndef HO_VMS /* For cross-assembly purposes. */
633 /* Write a 0xffff into the file, which means "End of File" */
634 write (VMS_Object_File_FD
, &m_one
, 2);
635 #endif /* not HO_VMS */
636 close (VMS_Object_File_FD
);
641 * Store immediate data in current Psect
644 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
652 * We are writing a "Record_Type" record
654 Set_VMS_Object_File_Record (Record_Type
);
656 * We can only store 128 bytes at a time
661 * Store a maximum of 128 bytes
663 i
= (Size
> 128) ? 128 : Size
;
666 * If we cannot accommodate this record, flush the
669 if ((Object_Record_Offset
+ i
+ 1) >=
670 sizeof (Object_Record_Buffer
))
671 Flush_VMS_Object_Record_Buffer ();
673 * If the buffer is empty we must insert record type
675 if (Object_Record_Offset
== 0)
676 PUT_CHAR (Record_Type
);
680 PUT_CHAR (-i
& 0xff);
685 PUT_CHAR (*Pointer
++);
687 * Flush the buffer if it is more than 75% full
689 if (Object_Record_Offset
>
690 (sizeof (Object_Record_Buffer
) * 3 / 4))
691 Flush_VMS_Object_Record_Buffer ();
696 * Make a data reference
699 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
706 * We are writing a "Record_Type" record
708 Set_VMS_Object_File_Record (Record_Type
);
710 * If the buffer is empty we must insert the record type
712 if (Object_Record_Offset
== 0)
713 PUT_CHAR (Record_Type
);
715 * Stack the Psect base + Longword Offset
719 if (Psect_Index
> 127)
721 PUT_CHAR (TIR_S_C_STA_WPL
);
722 PUT_SHORT (Psect_Index
);
727 PUT_CHAR (TIR_S_C_STA_PL
);
728 PUT_CHAR (Psect_Index
);
736 PUT_CHAR (TIR_S_C_STA_WPL
);
737 PUT_SHORT (Psect_Index
);
740 else if (Offset
> 127)
742 PUT_CHAR (TIR_S_C_STA_WPW
);
743 PUT_SHORT (Psect_Index
);
748 PUT_CHAR (TIR_S_C_STA_WPB
);
749 PUT_SHORT (Psect_Index
);
754 * Set relocation base
756 PUT_CHAR (TIR_S_C_STO_PIDR
);
758 * Flush the buffer if it is more than 75% full
760 if (Object_Record_Offset
>
761 (sizeof (Object_Record_Buffer
) * 3 / 4))
762 Flush_VMS_Object_Record_Buffer ();
766 * Make a debugger reference to a struct, union or enum.
769 VMS_Store_Struct (Struct_Index
)
773 * We are writing a "OBJ_S_C_DBG" record
775 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
777 * If the buffer is empty we must insert the record type
779 if (Object_Record_Offset
== 0)
780 PUT_CHAR (OBJ_S_C_DBG
);
781 PUT_CHAR (TIR_S_C_STA_UW
);
782 PUT_SHORT (Struct_Index
);
783 PUT_CHAR (TIR_S_C_CTL_STKDL
);
784 PUT_CHAR (TIR_S_C_STO_L
);
786 * Flush the buffer if it is more than 75% full
788 if (Object_Record_Offset
>
789 (sizeof (Object_Record_Buffer
) * 3 / 4))
790 Flush_VMS_Object_Record_Buffer ();
794 * Make a debugger reference to partially define a struct, union or enum.
797 VMS_Def_Struct (Struct_Index
)
801 * We are writing a "OBJ_S_C_DBG" record
803 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
805 * If the buffer is empty we must insert the record type
807 if (Object_Record_Offset
== 0)
808 PUT_CHAR (OBJ_S_C_DBG
);
809 PUT_CHAR (TIR_S_C_STA_UW
);
810 PUT_SHORT (Struct_Index
);
811 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
813 * Flush the buffer if it is more than 75% full
815 if (Object_Record_Offset
>
816 (sizeof (Object_Record_Buffer
) * 3 / 4))
817 Flush_VMS_Object_Record_Buffer ();
821 VMS_Set_Struct (Struct_Index
)
823 { /* see previous functions for comments */
824 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
825 if (Object_Record_Offset
== 0)
826 PUT_CHAR (OBJ_S_C_DBG
);
827 PUT_CHAR (TIR_S_C_STA_UW
);
828 PUT_SHORT (Struct_Index
);
829 PUT_CHAR (TIR_S_C_CTL_STLOC
);
830 if (Object_Record_Offset
>
831 (sizeof (Object_Record_Buffer
) * 3 / 4))
832 Flush_VMS_Object_Record_Buffer ();
836 * Write the Traceback Module Begin record
839 VMS_TBT_Module_Begin ()
841 register char *cp
, *cp1
;
843 char Module_Name
[256];
847 * Get module name (the FILENAME part of the object file)
853 if ((*cp
== ']') || (*cp
== '>') ||
854 (*cp
== ':') || (*cp
== '/'))
860 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
864 * Limit it to 31 characters
866 while (--cp1
>= Module_Name
)
869 if (strlen (Module_Name
) > 31)
872 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
876 * Arrange to store the data locally (leave room for size byte)
882 *cp
++ = DST_S_C_MODBEG
;
888 * Language type == "C"
890 *(long *) cp
= DST_S_C_C
;
893 * Store the module name
895 *cp
++ = strlen (Module_Name
);
900 * Now we can store the record size
905 * Put it into the object record
907 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
912 * Write the Traceback Module End record
915 VMS_TBT_Module_End ()
923 Local
[1] = DST_S_C_MODEND
;
925 * Put it into the object record
927 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
932 * Write the Traceback Routine Begin record
935 VMS_TBT_Routine_Begin (symbolP
, Psect
)
936 struct symbol
*symbolP
;
939 register char *cp
, *cp1
;
946 * Strip the leading "_" from the name
948 Name
= S_GET_NAME (symbolP
);
952 * Get the text psect offset
954 Offset
= S_GET_VALUE (symbolP
);
956 * Calculate the record size
958 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
966 Local
[1] = DST_S_C_RTNBEG
;
972 * Store the data so far
974 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
976 * Make sure we are still generating a OBJ_S_C_TBT record
978 if (Object_Record_Offset
== 0)
979 PUT_CHAR (OBJ_S_C_TBT
);
981 * Now get the symbol address
983 PUT_CHAR (TIR_S_C_STA_WPL
);
987 * Store the data reference
989 PUT_CHAR (TIR_S_C_STO_PIDR
);
991 * Store the counted string as data
995 Size
= strlen (cp1
) + 1;
999 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1004 * Write the Traceback Routine End record
1005 * We *must* search the symbol table to find the next routine, since
1006 * the assember has a way of reassembling the symbol table OUT OF ORDER
1007 * Thus the next routine in the symbol list is not necessarily the
1008 * next one in memory. For debugging to work correctly we must know the
1009 * size of the routine.
1012 VMS_TBT_Routine_End (Max_Size
, sp
)
1017 int Size
= 0x7fffffff;
1021 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1023 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1025 if (*S_GET_NAME (symbolP
) == 'L')
1027 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
1028 (S_GET_VALUE (symbolP
) < Size
))
1029 Size
= S_GET_VALUE (symbolP
);
1030 /* check if gcc_compiled. has size of zero */
1031 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
1033 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1034 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1035 Size
= S_GET_VALUE (symbolP
);
1039 if (Size
== 0x7fffffff)
1041 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
1049 Local
[1] = DST_S_C_RTNEND
;
1057 *((long *) (Local
+ 3)) = Size
;
1061 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1065 * Write the Traceback Block End record
1068 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1069 struct symbol
*symbolP
;
1073 register char *cp
, *cp1
;
1080 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1086 * Begin Block - We simulate with a phony routine
1088 Local
[1] = DST_S_C_BLKBEG
;
1094 * Store the data so far
1096 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1098 * Make sure we are still generating a OBJ_S_C_DBG record
1100 if (Object_Record_Offset
== 0)
1101 PUT_CHAR (OBJ_S_C_DBG
);
1103 * Now get the symbol address
1105 PUT_CHAR (TIR_S_C_STA_WPL
);
1108 * Get the text psect offset
1110 Offset
= S_GET_VALUE (symbolP
);
1113 * Store the data reference
1115 PUT_CHAR (TIR_S_C_STO_PIDR
);
1117 * Store the counted string as data
1121 Size
= strlen (cp1
) + 1;
1125 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1130 * Write the Traceback Block End record
1133 VMS_TBT_Block_End (Size
)
1139 * End block - simulate with a phony end routine
1142 Local
[1] = DST_S_C_BLKEND
;
1143 *((long *) (Local
+ 3)) = Size
;
1148 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1154 * Write a Line number / PC correlation record
1157 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1167 * If not delta, set our PC/Line number correlation
1174 Local
[0] = 1 + 1 + 2 + 1 + 4;
1176 * Line Number/PC correlation
1178 Local
[1] = DST_S_C_LINE_NUM
;
1182 Local
[2] = DST_S_C_SET_LINE_NUM
;
1183 *((unsigned short *) (Local
+ 3)) = Line_Number
- 1;
1187 Local
[5] = DST_S_C_SET_ABS_PC
;
1188 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1190 * Make sure we are still generating a OBJ_S_C_TBT record
1192 if (Object_Record_Offset
== 0)
1193 PUT_CHAR (OBJ_S_C_TBT
);
1196 PUT_CHAR (TIR_S_C_STA_PL
);
1201 PUT_CHAR (TIR_S_C_STA_WPL
);
1205 PUT_CHAR (TIR_S_C_STO_PIDR
);
1207 * Do a PC offset of 0 to register the line number
1210 Local
[1] = DST_S_C_LINE_NUM
;
1211 Local
[2] = 0; /* Increment PC by 0 and register line # */
1212 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1217 * If Delta is negative, terminate the line numbers
1221 Local
[0] = 1 + 1 + 4;
1222 Local
[1] = DST_S_C_LINE_NUM
;
1223 Local
[2] = DST_S_C_TERM_L
;
1224 *((long *) (Local
+ 3)) = Offset
;
1225 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1232 * Do a PC/Line delta
1235 *cp
++ = DST_S_C_LINE_NUM
;
1236 if (Line_Number
> 1)
1239 * We need to increment the line number
1241 if (Line_Number
- 1 <= 255)
1243 *cp
++ = DST_S_C_INCR_LINUM
;
1244 *cp
++ = Line_Number
- 1;
1248 *cp
++ = DST_S_C_INCR_LINUM_W
;
1249 *(short *) cp
= Line_Number
- 1;
1250 cp
+= sizeof (short);
1262 if (Offset
< 0x10000)
1264 *cp
++ = DST_S_C_DELTA_PC_W
;
1265 *(short *) cp
= Offset
;
1266 cp
+= sizeof (short);
1270 *cp
++ = DST_S_C_DELTA_PC_L
;
1271 *(long *) cp
= Offset
;
1272 cp
+= sizeof (long);
1275 Local
[0] = cp
- (Local
+ 1);
1276 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1282 * Describe a source file to the debugger
1285 VMS_TBT_Source_File (Filename
, ID_Number
)
1289 register char *cp
, *cp1
;
1292 #ifndef HO_VMS /* Used for cross-assembly */
1293 i
= strlen (Filename
);
1295 static struct FAB Fab
;
1296 static struct NAM Nam
;
1297 static struct XABDAT Date_Xab
;
1298 static struct XABFHC File_Header_Xab
;
1299 char Es_String
[255], Rs_String
[255];
1304 Fab
.fab$b_bid
= FAB$C_BID
;
1305 Fab
.fab$b_bln
= sizeof (Fab
);
1306 Fab
.fab$l_nam
= (&Nam
);
1307 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1309 * Setup the Nam block so we can find out the FULL name
1310 * of the source file.
1312 Nam
.nam$b_bid
= NAM$C_BID
;
1313 Nam
.nam$b_bln
= sizeof (Nam
);
1314 Nam
.nam$l_rsa
= Rs_String
;
1315 Nam
.nam$b_rss
= sizeof (Rs_String
);
1316 Nam
.nam$l_esa
= Es_String
;
1317 Nam
.nam$b_ess
= sizeof (Es_String
);
1319 * Setup the Date and File Header Xabs
1321 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1322 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1323 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1324 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1325 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1327 * Get the file information
1329 Fab
.fab$l_fna
= Filename
;
1330 Fab
.fab$b_fns
= strlen (Filename
);
1331 Status
= sys$
open (&Fab
);
1334 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1340 * Calculate the size of the resultant string
1347 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1349 * Source declaration
1351 Local
[1] = DST_S_C_SOURCE
;
1353 * Make formfeeds count as source records
1355 Local
[2] = DST_S_C_SRC_FORMFEED
;
1357 * Declare source file
1359 Local
[3] = DST_S_C_SRC_DECLFILE
;
1360 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1369 *(short *) cp
= ID_Number
;
1370 cp
+= sizeof (short);
1373 * Creation Date. Unknown, so we fill with zeroes.
1376 cp
+= sizeof (long);
1378 cp
+= sizeof (long);
1383 cp
+= sizeof (long);
1388 cp
+= sizeof (short);
1398 #else /* Use this code when assembling for VMS on a VMS system */
1402 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1403 cp
+= sizeof (long);
1404 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1405 cp
+= sizeof (long);
1409 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1410 cp
+= sizeof (long);
1414 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1415 cp
+= sizeof (short);
1419 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1429 * Library module name (none)
1435 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1441 * Give the number of source lines to the debugger
1444 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1446 int Starting_Line_Number
;
1447 int Number_Of_Lines
;
1455 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1457 * Source declaration
1459 Local
[1] = DST_S_C_SOURCE
;
1464 *cp
++ = DST_S_C_SRC_SETFILE
;
1468 *(short *) cp
= ID_Number
;
1469 cp
+= sizeof (short);
1473 *cp
++ = DST_S_C_SRC_SETREC_L
;
1474 *(long *) cp
= Starting_Line_Number
;
1475 cp
+= sizeof (long);
1479 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1480 *(short *) cp
= Number_Of_Lines
;
1481 cp
+= sizeof (short);
1485 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1491 /* This routine locates a file in the list of files. If an entry does not
1492 * exist, one is created. For include files, a new entry is always created
1493 * such that inline functions can be properly debugged. */
1494 static struct input_file
*
1498 struct input_file
*same_file
;
1499 struct input_file
*fpnt
;
1500 same_file
= (struct input_file
*) NULL
;
1501 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1503 if (fpnt
== (struct input_file
*) NULL
)
1505 if (fpnt
->spnt
== sp
)
1508 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1510 if (fpnt
== (struct input_file
*) NULL
)
1512 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1514 if (fpnt
->flag
== 1)
1520 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1521 if (file_root
== (struct input_file
*) NULL
)
1525 struct input_file
*fpnt1
;
1526 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1529 fpnt
->next
= (struct input_file
*) NULL
;
1530 fpnt
->name
= S_GET_NAME (sp
);
1531 fpnt
->min_line
= 0x7fffffff;
1535 fpnt
->file_number
= 0;
1537 fpnt
->same_file_fpnt
= same_file
;
1542 * The following functions and definitions are used to generate object records
1543 * that will describe program variables to the VMS debugger.
1545 * This file contains many of the routines needed to output debugging info into
1546 * the object file that the VMS debugger needs to understand symbols. These
1547 * routines are called very late in the assembly process, and thus we can be
1548 * fairly lax about changing things, since the GSD and the TIR sections have
1549 * already been output.
1553 /* This routine converts a number string into an integer, and stops when it
1554 * sees an invalid character the return value is the address of the character
1555 * just past the last character read. No error is generated.
1558 cvt_integer (str
, rtn
)
1563 neg
= *str
== '-' ? ++str
, -1 : 1;
1564 ival
= 0; /* first get the number of the type for dbx */
1565 while ((*str
<= '9') && (*str
>= '0'))
1566 ival
= 10 * ival
+ *str
++ - '0';
1571 /* this routine fixes the names that are generated by C++, ".this" is a good
1572 * example. The period does not work for the debugger, since it looks like
1573 * the syntax for a structure element, and thus it gets mightily confused
1575 * We also use this to strip the PsectAttribute hack from the name before we
1576 * write a debugger record */
1584 * Kill any leading "_"
1589 * Is there a Psect Attribute to skip??
1591 if (HAS_PSECT_ATTRIBUTES (pnt
))
1596 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1599 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1607 /* Here we fix the .this -> $this conversion */
1608 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1616 /* When defining a structure, this routine is called to find the name of
1617 * the actual structure. It is assumed that str points to the equal sign
1618 * in the definition, and it moves backward until it finds the start of the
1619 * name. If it finds a 0, then it knows that this structure def is in the
1620 * outermost level, and thus symbol_name points to the symbol name.
1623 get_struct_name (str
)
1628 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1633 while ((*pnt
!= ';') && (*pnt
!= '='))
1637 while ((*pnt
< '0') || (*pnt
> '9'))
1639 while ((*pnt
>= '0') && (*pnt
<= '9'))
1644 /* search symbol list for type number dbx_type. Return a pointer to struct */
1645 static struct VMS_DBG_Symbol
*
1646 find_symbol (dbx_type
)
1649 struct VMS_DBG_Symbol
*spnt
;
1650 spnt
= VMS_Symbol_type_list
;
1651 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1653 if (spnt
->dbx_type
== dbx_type
)
1657 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1658 return 0; /*Dunno what this is*/
1663 /* this routine puts info into either Local or Asuffix, depending on the sign
1664 * of size. The reason is that it is easier to build the variable descriptor
1665 * backwards, while the array descriptor is best built forwards. In the end
1666 * they get put together, if there is not a struct/union/enum along the way
1677 pnt
= (char *) &val
;
1685 for (i
= 0; i
< size1
; i
++)
1687 Local
[Lpnt
--] = *pnt
--;
1695 for (i
= 0; i
< size1
; i
++)
1697 Asuffix
[Apoint
++] = *pnt
++;
1698 if (Apoint
>= MAX_DEBUG_RECORD
)
1701 Apoint
= MAX_DEBUG_RECORD
- 1;
1706 /* this routine generates the array descriptor for a given array */
1708 array_suffix (spnt2
)
1709 struct VMS_DBG_Symbol
*spnt2
;
1711 struct VMS_DBG_Symbol
*spnt
;
1712 struct VMS_DBG_Symbol
*spnt1
;
1718 while (spnt
->advanced
!= ARRAY
)
1720 spnt
= find_symbol (spnt
->type2
);
1721 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1727 while (spnt1
->advanced
== ARRAY
)
1730 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1731 spnt1
= find_symbol (spnt1
->type2
);
1733 total_size
= total_size
* spnt1
->data_size
;
1734 push (spnt1
->data_size
, 2);
1735 if (spnt1
->VMS_type
== 0xa3)
1738 push (spnt1
->VMS_type
, 1);
1740 for (i
= 0; i
< 6; i
++)
1744 push (total_size
, 4);
1747 while (spnt1
->advanced
== ARRAY
)
1749 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1750 spnt1
= find_symbol (spnt1
->type2
);
1753 while (spnt1
->advanced
== ARRAY
)
1755 push (spnt1
->index_min
, 4);
1756 push (spnt1
->index_max
, 4);
1757 spnt1
= find_symbol (spnt1
->type2
);
1761 /* this routine generates the start of a variable descriptor based upon
1762 * a struct/union/enum that has yet to be defined. We define this spot as
1763 * a new location, and save four bytes for the address. When the struct is
1764 * finally defined, then we can go back and plug in the correct address
1767 new_forward_ref (dbx_type
)
1770 struct forward_ref
*fpnt
;
1771 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1772 fpnt
->next
= f_ref_root
;
1774 fpnt
->dbx_type
= dbx_type
;
1775 fpnt
->struc_numb
= ++structure_count
;
1776 fpnt
->resolved
= 'N';
1779 push (total_len
, -2);
1780 struct_number
= -fpnt
->struc_numb
;
1783 /* this routine generates the variable descriptor used to describe non-basic
1784 * variables. It calls itself recursively until it gets to the bottom of it
1785 * all, and then builds the descriptor backwards. It is easiest to do it this
1786 *way since we must periodically write length bytes, and it is easiest if we know
1787 *the value when it is time to write it.
1790 gen1 (spnt
, array_suffix_len
)
1791 struct VMS_DBG_Symbol
*spnt
;
1792 int array_suffix_len
;
1794 struct VMS_DBG_Symbol
*spnt1
;
1796 switch (spnt
->advanced
)
1799 push (DBG_S_C_VOID
, -1);
1801 push (total_len
, -2);
1805 if (array_suffix_len
== 0)
1807 push (spnt
->VMS_type
, -1);
1808 push (DBG_S_C_BASIC
, -1);
1810 push (total_len
, -2);
1820 struct_number
= spnt
->struc_numb
;
1821 if (struct_number
< 0)
1823 new_forward_ref (spnt
->dbx_type
);
1826 push (DBG_S_C_STRUCT
, -1);
1828 push (total_len
, -2);
1831 spnt1
= find_symbol (spnt
->type2
);
1833 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1834 new_forward_ref (spnt
->type2
);
1836 i
= gen1 (spnt1
, 0);
1838 { /* (*void) is a special case, do not put pointer suffix*/
1839 push (DBG_S_C_POINTER
, -1);
1841 push (total_len
, -2);
1846 while (spnt1
->advanced
== ARRAY
)
1848 spnt1
= find_symbol (spnt1
->type2
);
1849 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1851 printf ("gcc-as warning(debugger output):");
1852 printf ("Forward reference error, dbx type %d\n",
1857 /* It is too late to generate forward references, so the user gets a message.
1858 * This should only happen on a compiler error */
1859 i
= gen1 (spnt1
, 1);
1861 array_suffix (spnt
);
1862 array_suffix_len
= Apoint
- i
;
1863 switch (spnt1
->advanced
)
1871 push (total_len
, -2);
1874 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1876 total_len
+= array_suffix_len
+ 8;
1877 push (total_len
, -2);
1881 /* This generates a suffix for a variable. If it is not a defined type yet,
1882 * then dbx_type contains the type we are expecting so we can generate a
1883 * forward reference. This calls gen1 to build most of the descriptor, and
1884 * then it puts the icing on at the end. It then dumps whatever is needed
1885 * to get a complete descriptor (i.e. struct reference, array suffix ).
1888 generate_suffix (spnt
, dbx_type
)
1889 struct VMS_DBG_Symbol
*spnt
;
1894 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1895 struct VMS_DBG_Symbol
*spnt1
;
1897 Lpnt
= MAX_DEBUG_RECORD
- 1;
1901 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1902 new_forward_ref (dbx_type
);
1905 if (spnt
->VMS_type
!= 0xa3)
1906 return 0; /* no suffix needed */
1911 push (total_len
, -1);
1912 /* if the variable descriptor overflows the record, output a descriptor for
1913 * a pointer to void.
1915 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1917 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1918 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1922 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1923 Local
[i
++] = Local
[++Lpnt
];
1925 /* we use this for a reference to a structure that has already been defined */
1926 if (struct_number
> 0)
1928 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1930 VMS_Store_Struct (struct_number
);
1932 /* we use this for a forward reference to a structure that has yet to be
1933 *defined. We store four bytes of zero to make room for the actual address once
1936 if (struct_number
< 0)
1938 struct_number
= -struct_number
;
1939 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1941 VMS_Def_Struct (struct_number
);
1942 for (i
= 0; i
< 4; i
++)
1944 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1949 Local
[Lpnt
++] = Asuffix
[i
++];
1951 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1955 /* This routine generates a symbol definition for a C sybmol for the debugger.
1956 * It takes a psect and offset for global symbols - if psect < 0, then this is
1957 * a local variable and the offset is relative to FP. In this case it can
1958 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1961 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1962 struct VMS_DBG_Symbol
*spnt
;
1972 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
1974 { /* this is a local variable, referenced to SP */
1975 maxlen
= 7 + strlen (Name_pnt
);
1976 Local
[i
++] = maxlen
;
1977 Local
[i
++] = spnt
->VMS_type
;
1979 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
1981 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
1982 pnt
= (char *) &Offset
;
1983 for (j
= 0; j
< 4; j
++)
1984 Local
[i
++] = *pnt
++; /* copy the offset */
1988 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
1989 Local
[i
++] = 7 + strlen (Name_pnt
);
1990 Local
[i
++] = spnt
->VMS_type
;
1992 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1994 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
1996 Local
[i
++] = strlen (Name_pnt
);
1997 while (*Name_pnt
!= '\0')
1998 Local
[i
++] = *Name_pnt
++;
1999 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2000 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2001 generate_suffix (spnt
, 0);
2005 /* This routine parses the stabs entries in order to make the definition
2006 * for the debugger of local symbols and function parameters
2009 VMS_local_stab_Parse (sp
)
2015 struct VMS_DBG_Symbol
*spnt
;
2016 struct VMS_Symbol
*vsp
;
2020 str
= S_GET_NAME (sp
);
2021 pnt
= (char *) strchr (str
, ':');
2022 if (pnt
== (char *) NULL
)
2023 return; /* no colon present */
2024 pnt1
= pnt
++; /* save this for later, and skip colon */
2026 return 0; /* ignore static constants */
2027 /* there is one little catch that we must be aware of. Sometimes function
2028 * parameters are optimized into registers, and the compiler, in its infiite
2029 * wisdom outputs stabs records for *both*. In general we want to use the
2030 * register if it is present, so we must search the rest of the symbols for
2031 * this function to see if this parameter is assigned to a register.
2039 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2041 if (!S_IS_DEBUG (sp1
))
2043 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2045 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2046 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2048 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2050 str1
= S_GET_NAME (sp1
); /* and get the name */
2052 while (*pnt2
!= ':')
2059 if ((*str1
!= ':') || (*pnt2
!= ':'))
2061 return; /* they are the same! lets skip this one */
2063 /* first find the dbx symbol type from list, and then find VMS type */
2064 pnt
++; /* skip p in case no register */
2067 pnt
= cvt_integer (pnt
, &dbx_type
);
2068 spnt
= find_symbol (dbx_type
);
2069 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2070 return 0; /*Dunno what this is*/
2072 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2073 *pnt1
= ':'; /* and restore the string */
2077 /* This routine parses a stabs entry to find the information required to define
2078 * a variable. It is used for global and static variables.
2079 * Basically we need to know the address of the symbol. With older versions
2080 * of the compiler, const symbols are
2081 * treated differently, in that if they are global they are written into the
2082 * text psect. The global symbol entry for such a const is actually written
2083 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2084 * of psects, we must search the entry points as well. static consts are even
2085 * harder, since they are never assigned a memory address. The compiler passes
2086 * a stab to tell us the value, but I am not sure what to do with it.
2090 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2093 int type1
, type2
, Text_Psect
;
2099 struct VMS_DBG_Symbol
*spnt
;
2100 struct VMS_Symbol
*vsp
;
2104 str
= S_GET_NAME (sp
);
2105 pnt
= (char *) strchr (str
, ':');
2106 if (pnt
== (char *) NULL
)
2107 return; /* no colon present */
2108 pnt1
= pnt
; /* save this for later*/
2110 if (*pnt
== expected_type
)
2112 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2113 spnt
= find_symbol (dbx_type
);
2114 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2115 return 0; /*Dunno what this is*/
2116 /* now we need to search the symbol table to find the psect and offset for
2121 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2123 pnt
= S_GET_NAME (vsp
->Symbol
);
2124 if (pnt
!= (char *) NULL
)
2126 /* make sure name is the same, and make sure correct symbol type */
2127 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2128 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2129 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2133 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2135 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2136 *pnt1
= ':'; /* and restore the string */
2139 /* the symbol was not in the symbol list, but it may be an "entry point"
2140 if it was a constant */
2141 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2144 * Dispatch on STAB type
2146 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2148 pnt
= S_GET_NAME (sp1
);
2151 if (strcmp (pnt
, str
) == 0)
2153 if (!gave_compiler_message
&& expected_type
== 'G')
2155 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2156 printf ("global constant(s) in the text psect. These will not be available to\n");
2157 printf ("other modules, since this is not the correct way to handle this. You\n");
2158 printf ("have two options: 1) get a patched compiler that does not put global\n");
2159 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2160 printf ("definitions of global variables in your source module(s). Don't say\n");
2161 printf ("I didn't warn you!");
2162 gave_compiler_message
= 1;
2164 VMS_DBG_record (spnt
,
2169 *S_GET_NAME (sp1
) = 'L';
2170 /* fool assembler to not output this
2171 * as a routine in the TBT */
2176 *pnt1
= ':'; /* and restore the string */
2181 VMS_GSYM_Parse (sp
, Text_Psect
)
2184 { /* Global variables */
2185 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2190 VMS_LCSYM_Parse (sp
, Text_Psect
)
2193 { /* Static symbols - uninitialized */
2194 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2198 VMS_STSYM_Parse (sp
, Text_Psect
)
2201 { /* Static symbols - initialized */
2202 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2206 /* for register symbols, we must figure out what range of addresses within the
2207 * psect are valid. We will use the brackets in the stab directives to give us
2208 * guidance as to the PC range that this variable is in scope. I am still not
2209 * completely comfortable with this but as I learn more, I seem to get a better
2210 * handle on what is going on.
2214 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2215 symbolS
*sp
, *Current_Routine
;
2222 struct VMS_DBG_Symbol
*spnt
;
2227 int Min_Offset
= -1; /* min PC of validity */
2228 int Max_Offset
= 0; /* max PC of validity */
2230 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2233 * Dispatch on STAB type
2235 switch (S_GET_RAW_TYPE (symbolP
))
2239 Min_Offset
= S_GET_VALUE (symbolP
);
2244 S_GET_VALUE (symbolP
) - 1;
2247 if ((Min_Offset
!= -1) && (bcnt
== 0))
2249 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2251 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2252 if (*pnt
== 'F' || *pnt
== 'f') break;
2255 /* check to see that the addresses were defined. If not, then there were no
2256 * brackets in the function, and we must try to search for the next function
2257 * Since functions can be in any order, we should search all of the symbol list
2258 * to find the correct ending address. */
2259 if (Min_Offset
== -1)
2261 int Max_Source_Offset
;
2263 Min_Offset
= S_GET_VALUE (sp
);
2264 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2267 * Dispatch on STAB type
2269 This_Offset
= S_GET_VALUE (symbolP
);
2270 switch (S_GET_RAW_TYPE (symbolP
))
2272 case N_TEXT
| N_EXT
:
2273 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2274 Max_Offset
= This_Offset
;
2277 if (This_Offset
> Max_Source_Offset
)
2278 Max_Source_Offset
= This_Offset
;
2281 /* if this is the last routine, then we use the PC of the last source line
2282 * as a marker of the max PC for which this reg is valid */
2283 if (Max_Offset
== 0x7fffffff)
2284 Max_Offset
= Max_Source_Offset
;
2287 str
= S_GET_NAME (sp
);
2288 pnt
= (char *) strchr (str
, ':');
2289 if (pnt
== (char *) NULL
)
2290 return; /* no colon present */
2291 pnt1
= pnt
; /* save this for later*/
2295 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2296 spnt
= find_symbol (dbx_type
);
2297 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2298 return 0; /*Dunno what this is yet*/
2300 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2301 maxlen
= 25 + strlen (pnt
);
2302 Local
[i
++] = maxlen
;
2303 Local
[i
++] = spnt
->VMS_type
;
2305 Local
[i
++] = strlen (pnt
) + 1;
2309 Local
[i
++] = strlen (pnt
);
2310 while (*pnt
!= '\0')
2311 Local
[i
++] = *pnt
++;
2317 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2319 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2320 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2322 Local
[i
++] = S_GET_VALUE (sp
);
2326 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2328 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2329 generate_suffix (spnt
, 0);
2332 /* this function examines a structure definition, checking all of the elements
2333 * to make sure that all of them are fully defined. The only thing that we
2334 * kick out are arrays of undefined structs, since we do not know how big
2335 * they are. All others we can handle with a normal forward reference.
2338 forward_reference (pnt
)
2342 struct VMS_DBG_Symbol
*spnt
;
2343 struct VMS_DBG_Symbol
*spnt1
;
2344 pnt
= cvt_integer (pnt
+ 1, &i
);
2346 return 0; /* no forward references */
2349 pnt
= (char *) strchr (pnt
, ':');
2350 pnt
= cvt_integer (pnt
+ 1, &i
);
2351 spnt
= find_symbol (i
);
2352 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2354 while ((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2357 spnt1
= find_symbol (spnt
->type2
);
2358 if ((spnt
->advanced
== ARRAY
) &&
2359 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2361 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2365 pnt
= cvt_integer (pnt
+ 1, &i
);
2366 pnt
= cvt_integer (pnt
+ 1, &i
);
2367 } while (*++pnt
!= ';');
2368 return 0; /* no forward refences found */
2371 /* This routine parses the stabs directives to find any definitions of dbx type
2372 * numbers. It makes a note of all of them, creating a structure element
2373 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2374 * debugger that describes the struct/union/enum, so that further references
2375 * to these data types will be by number
2376 * We have to process pointers right away, since there can be references
2377 * to them later in the same stabs directive. We cannot have forward
2378 * references to pointers, (but we can have a forward reference to a pointer to
2379 * a structure/enum/union) and this is why we process them immediately.
2380 * After we process the pointer, then we search for defs that are nested even
2384 VMS_typedef_parse (str
)
2392 struct forward_ref
*fpnt
;
2394 int convert_integer
;
2395 struct VMS_DBG_Symbol
*spnt
;
2396 struct VMS_DBG_Symbol
*spnt1
;
2397 /* check for any nested def's */
2398 pnt
= (char *) strchr (str
+ 1, '=');
2399 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*'))
2400 if (VMS_typedef_parse (pnt
) == 1)
2402 /* now find dbx_type of entry */
2405 { /* check for static constants */
2406 *str
= '\0'; /* for now we ignore them */
2409 while ((*pnt
<= '9') && (*pnt
>= '0'))
2411 pnt
++; /* and get back to the number */
2412 cvt_integer (pnt
, &i1
);
2413 spnt
= find_symbol (i1
);
2414 /* first we see if this has been defined already, due to a forward reference*/
2415 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2417 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2419 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2420 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2421 VMS_Symbol_type_list
= spnt
;
2425 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2426 spnt
->next
= VMS_Symbol_type_list
;
2427 VMS_Symbol_type_list
= spnt
;
2429 spnt
->dbx_type
= i1
; /* and save the type */
2431 /* for structs and unions, do a partial parse, otherwise we sometimes get
2432 * circular definitions that are impossible to resolve. We read enough info
2433 * so that any reference to this type has enough info to be resolved
2435 pnt
= str
+ 1; /* point to character past equal sign */
2436 if ((*pnt
== 'u') || (*pnt
== 's'))
2439 if ((*pnt
<= '9') && (*pnt
>= '0'))
2441 if (type_check ("void"))
2442 { /* this is the void symbol */
2444 spnt
->advanced
= VOID
;
2447 if (type_check ("unknown type"))
2448 { /* this is the void symbol */
2450 spnt
->advanced
= UNKNOWN
;
2453 printf ("gcc-as warning(debugger output):");
2454 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2455 return 1; /* do not know what this is */
2457 /* now define this module*/
2458 pnt
= str
+ 1; /* point to character past equal sign */
2462 spnt
->advanced
= BASIC
;
2463 if (type_check ("int"))
2465 spnt
->VMS_type
= DBG_S_C_SLINT
;
2466 spnt
->data_size
= 4;
2468 else if (type_check ("long int"))
2470 spnt
->VMS_type
= DBG_S_C_SLINT
;
2471 spnt
->data_size
= 4;
2473 else if (type_check ("unsigned int"))
2475 spnt
->VMS_type
= DBG_S_C_ULINT
;
2476 spnt
->data_size
= 4;
2478 else if (type_check ("long unsigned int"))
2480 spnt
->VMS_type
= DBG_S_C_ULINT
;
2481 spnt
->data_size
= 4;
2483 else if (type_check ("short int"))
2485 spnt
->VMS_type
= DBG_S_C_SSINT
;
2486 spnt
->data_size
= 2;
2488 else if (type_check ("short unsigned int"))
2490 spnt
->VMS_type
= DBG_S_C_USINT
;
2491 spnt
->data_size
= 2;
2493 else if (type_check ("char"))
2495 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2496 spnt
->data_size
= 1;
2498 else if (type_check ("signed char"))
2500 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2501 spnt
->data_size
= 1;
2503 else if (type_check ("unsigned char"))
2505 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2506 spnt
->data_size
= 1;
2508 else if (type_check ("float"))
2510 spnt
->VMS_type
= DBG_S_C_REAL4
;
2511 spnt
->data_size
= 4;
2513 else if (type_check ("double"))
2515 spnt
->VMS_type
= DBG_S_C_REAL8
;
2516 spnt
->data_size
= 8;
2518 pnt1
= (char *) strchr (str
, ';') + 1;
2523 spnt
->advanced
= STRUCT
;
2525 spnt
->advanced
= UNION
;
2526 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2527 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2528 if (forward_reference (pnt
))
2530 spnt
->struc_numb
= -1;
2533 spnt
->struc_numb
= ++structure_count
;
2535 pnt
= get_struct_name (str
);
2536 VMS_Def_Struct (spnt
->struc_numb
);
2538 while (fpnt
!= (struct forward_ref
*) NULL
)
2540 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2542 fpnt
->resolved
= 'Y';
2543 VMS_Set_Struct (fpnt
->struc_numb
);
2544 VMS_Store_Struct (spnt
->struc_numb
);
2548 VMS_Set_Struct (spnt
->struc_numb
);
2550 Local
[i
++] = 11 + strlen (pnt
);
2551 Local
[i
++] = DBG_S_C_STRUCT_START
;
2553 for (i1
= 0; i1
< 4; i1
++)
2555 Local
[i
++] = strlen (pnt
);
2557 while (*pnt2
!= '\0')
2558 Local
[i
++] = *pnt2
++;
2559 i2
= spnt
->data_size
* 8; /* number of bits */
2560 pnt2
= (char *) &i2
;
2561 for (i1
= 0; i1
< 4; i1
++)
2562 Local
[i
++] = *pnt2
++;
2563 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2565 if (pnt
!= symbol_name
)
2567 pnt
+= strlen (pnt
);
2569 }; /* replace colon for later */
2570 while (*++pnt1
!= ';')
2572 pnt
= (char *) strchr (pnt1
, ':');
2575 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2576 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2577 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2578 if ((dtype
== 1) && (i3
!= 32))
2581 push (19 + strlen (pnt2
), 1);
2583 push (1 + strlen (pnt2
), 4);
2584 push (strlen (pnt2
), 1);
2585 while (*pnt2
!= '\0')
2587 push (i3
, 2); /* size of bitfield */
2590 push (i2
, 4); /* start position */
2591 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2596 Local
[i
++] = 7 + strlen (pnt2
);
2597 spnt1
= find_symbol (dtype
);
2598 /* check if this is a forward reference */
2599 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2600 Local
[i
++] = spnt1
->VMS_type
;
2602 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2603 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2605 for (i1
= 0; i1
< 4; i1
++)
2606 Local
[i
++] = *pnt
++;
2607 Local
[i
++] = strlen (pnt2
);
2608 while (*pnt2
!= '\0')
2609 Local
[i
++] = *pnt2
++;
2610 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2612 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2613 generate_suffix (spnt1
, dtype
);
2614 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2615 generate_suffix (spnt1
, 0);
2619 Local
[i
++] = 0x01; /* length byte */
2620 Local
[i
++] = DBG_S_C_STRUCT_END
;
2621 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2625 spnt
->advanced
= ENUM
;
2626 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2627 spnt
->struc_numb
= ++structure_count
;
2628 spnt
->data_size
= 4;
2629 VMS_Def_Struct (spnt
->struc_numb
);
2631 while (fpnt
!= (struct forward_ref
*) NULL
)
2633 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2635 fpnt
->resolved
= 'Y';
2636 VMS_Set_Struct (fpnt
->struc_numb
);
2637 VMS_Store_Struct (spnt
->struc_numb
);
2641 VMS_Set_Struct (spnt
->struc_numb
);
2643 Local
[i
++] = 3 + strlen (symbol_name
);
2644 Local
[i
++] = DBG_S_C_ENUM_START
;
2646 Local
[i
++] = strlen (symbol_name
);
2648 while (*pnt2
!= '\0')
2649 Local
[i
++] = *pnt2
++;
2650 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2652 while (*++pnt
!= ';')
2654 pnt1
= (char *) strchr (pnt
, ':');
2656 pnt1
= cvt_integer (pnt1
, &i1
);
2657 Local
[i
++] = 7 + strlen (pnt
);
2658 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2660 pnt2
= (char *) &i1
;
2661 for (i2
= 0; i2
< 4; i2
++)
2662 Local
[i
++] = *pnt2
++;
2663 Local
[i
++] = strlen (pnt
);
2665 while (*pnt
!= '\0')
2666 Local
[i
++] = *pnt
++;
2667 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2669 pnt
= pnt1
; /* Skip final semicolon */
2671 Local
[i
++] = 0x01; /* len byte */
2672 Local
[i
++] = DBG_S_C_ENUM_END
;
2673 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2678 spnt
->advanced
= ARRAY
;
2679 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2680 pnt
= (char *) strchr (pnt
, ';');
2681 if (pnt
== (char *) NULL
)
2683 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2684 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2685 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2688 spnt
->advanced
= FUNCTION
;
2689 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2690 /* this masquerades as a basic type*/
2691 spnt
->data_size
= 4;
2692 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2695 spnt
->advanced
= POINTER
;
2696 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2697 spnt
->data_size
= 4;
2698 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2699 pnt
= (char *) strchr (str
+ 1, '=');
2700 if ((pnt
!= (char *) NULL
))
2701 if (VMS_typedef_parse (pnt
) == 1)
2705 spnt
->advanced
= UNKNOWN
;
2707 printf ("gcc-as warning(debugger output):");
2708 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2709 return 1; /* unable to decipher */
2711 /* this removes the evidence of the definition so that the outer levels of
2712 parsing do not have to worry about it */
2714 while (*pnt1
!= '\0')
2722 * This is the root routine that parses the stabs entries for definitions.
2723 * it calls VMS_typedef_parse, which can in turn call itself.
2724 * We need to be careful, since sometimes there are forward references to
2725 * other symbol types, and these cannot be resolved until we have completed
2736 int incomplete
, i
, pass
, incom1
;
2737 struct VMS_DBG_Symbol
*spnt
;
2738 struct VMS_Symbol
*vsp
;
2739 struct forward_ref
*fpnt
;
2745 incom1
= incomplete
;
2747 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2750 * Deal with STAB symbols
2752 if (S_IS_DEBUG (sp
))
2755 * Dispatch on STAB type
2757 switch (S_GET_RAW_TYPE (sp
))
2765 case N_FUN
: /*sometimes these contain typedefs*/
2766 str
= S_GET_NAME (sp
);
2768 pnt
= (char *) strchr (str
, ':');
2769 if (pnt
== (char *) NULL
)
2773 pnt2
= (char *) strchr (pnt1
, '=');
2774 if (pnt2
== (char *) NULL
)
2776 *pnt
= ':'; /* replace colon */
2778 }; /* no symbol here */
2779 incomplete
+= VMS_typedef_parse (pnt2
);
2780 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2786 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2787 /* repeat until all refs resolved if possible */
2788 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2789 if (incomplete
!= 0)
2791 printf ("gcc-as warning(debugger output):");
2792 printf ("Unable to resolve %d circular references.\n", incomplete
);
2796 while (fpnt
!= (struct forward_ref
*) NULL
)
2798 if (fpnt
->resolved
!= 'Y')
2800 if (find_symbol (fpnt
->dbx_type
) !=
2801 (struct VMS_DBG_Symbol
*) NULL
)
2803 printf ("gcc-as warning(debugger output):");
2804 printf ("Forward reference error, dbx type %d\n",
2809 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2810 pnt2
= (char *) strchr (&fixit
[1], '=');
2811 VMS_typedef_parse (pnt2
);
2818 Define_Local_Symbols (s1
, s2
)
2822 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2824 if (symbolP1
== (symbolS
*) NULL
)
2826 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2828 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2829 if (*pnt
== 'F' || *pnt
== 'f') break;
2832 * Deal with STAB symbols
2834 if (S_IS_DEBUG (symbolP1
))
2837 * Dispatch on STAB type
2839 switch (S_GET_RAW_TYPE (symbolP1
))
2843 VMS_local_stab_Parse (symbolP1
);
2846 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
2854 /* This function crawls the symbol chain searching for local symbols that need
2855 * to be described to the debugger. When we enter a new scope with a "{", it
2856 * creates a new "block", which helps the debugger keep track of which scope
2857 * we are currently in.
2861 Define_Routine (symbolP
, Level
)
2871 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
2873 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2875 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2876 if (*pnt
== 'F' || *pnt
== 'f') break;
2879 * Deal with STAB symbols
2881 if (S_IS_DEBUG (symbolP1
))
2884 * Dispatch on STAB type
2886 switch (S_GET_RAW_TYPE (symbolP1
))
2891 sprintf (str
, "$%d", rcount
++);
2892 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
2894 Offset
= S_GET_VALUE (symbolP1
);
2895 Define_Local_Symbols (sstart
, symbolP1
);
2897 Define_Routine (symbolP1
, Level
+ 1);
2899 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
2908 /* we end up here if there were no brackets in this function. Define
2910 Define_Local_Symbols (sstart
, (symbolS
*) 0);
2916 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
2918 symbolS
*Curr_Routine
;
2921 Current_Routine
= Curr_Routine
;
2922 Text_Psect
= Txt_Psect
;
2923 Define_Routine (symbolP
, 0);
2930 #include <sys/types.h>
2933 /* Manufacure a VMS like time on a unix based system. */
2934 get_VMS_time_on_unix (Now
)
2940 pnt
= ctime (&timeb
);
2946 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
2949 #endif /* not HO_VMS */
2951 * Write the MHD (Module Header) records
2954 Write_VMS_MHD_Records ()
2956 register char *cp
, *cp1
;
2963 char Module_Name
[256];
2967 * We are writing a module header record
2969 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
2971 * ***************************
2972 * *MAIN MODULE HEADER RECORD*
2973 * ***************************
2975 * Store record type and header type
2977 PUT_CHAR (OBJ_S_C_HDR
);
2978 PUT_CHAR (MHD_S_C_MHD
);
2980 * Structure level is 0
2982 PUT_CHAR (OBJ_S_C_STRLVL
);
2984 * Maximum record size is size of the object record buffer
2986 PUT_SHORT (sizeof (Object_Record_Buffer
));
2988 * Get module name (the FILENAME part of the object file)
2994 if ((*cp
== ']') || (*cp
== '>') ||
2995 (*cp
== ':') || (*cp
== '/'))
3001 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3005 * Limit it to 31 characters and store in the object record
3007 while (--cp1
>= Module_Name
)
3010 if (strlen (Module_Name
) > 31)
3013 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3014 Module_Name
[31] = 0;
3016 PUT_COUNTED_STRING (Module_Name
);
3018 * Module Version is "V1.0"
3020 PUT_COUNTED_STRING ("V1.0");
3022 * Creation time is "now" (17 chars of time string)
3025 get_VMS_time_on_unix (&Now
[0]);
3027 Descriptor
.Size
= 17;
3028 Descriptor
.Ptr
= Now
;
3029 sys$
asctim (0, &Descriptor
, 0, 0);
3031 for (i
= 0; i
< 17; i
++)
3034 * Patch time is "never" (17 zeros)
3036 for (i
= 0; i
< 17; i
++)
3041 Flush_VMS_Object_Record_Buffer ();
3043 * *************************
3044 * *LANGUAGE PROCESSOR NAME*
3045 * *************************
3047 * Store record type and header type
3049 PUT_CHAR (OBJ_S_C_HDR
);
3050 PUT_CHAR (MHD_S_C_LNM
);
3052 * Store language processor name and version
3053 * (not a counted string!)
3055 cp
= compiler_version_string
;
3061 cp
= strchr (version_string
, '.');
3071 Flush_VMS_Object_Record_Buffer ();
3076 * Write the EOM (End Of Module) record
3079 Write_VMS_EOM_Record (Psect
, Offset
)
3084 * We are writing an end-of-module record
3086 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3090 PUT_CHAR (OBJ_S_C_EOM
);
3092 * Store the error severity (0)
3096 * Store the entry point, if it exists
3101 * Store the entry point Psect
3105 * Store the entry point Psect offset
3112 Flush_VMS_Object_Record_Buffer ();
3116 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3122 register unsigned char *p
= ptr
;
3123 register unsigned char *end
= p
+ strlen (ptr
);
3124 register unsigned char c
;
3125 register int hash
= 0;
3130 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3136 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3139 VMS_Case_Hack_Symbol (In
, Out
)
3149 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3151 int Case_Hack_Bits
= 0;
3153 static char Hex_Table
[16] =
3154 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3157 * Kill any leading "_"
3159 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3162 new_name
= Out
; /* save this for later*/
3164 #if barfoo /* Dead code */
3165 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3169 /* We may need to truncate the symbol, save the hash for later*/
3170 if (strlen (In
) > 23)
3171 result
= hash_string (In
);
3173 * Is there a Psect Attribute to skip??
3175 if (HAS_PSECT_ATTRIBUTES (In
))
3180 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3183 if ((In
[0] == '$') && (In
[1] == '$'))
3193 /* if (strlen(In) > 31 && flagseen['+'])
3194 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3196 * Do the case conversion
3198 i
= 23; /* Maximum of 23 chars */
3199 while (*In
&& (--i
>= 0))
3201 Case_Hack_Bits
<<= 1;
3204 if ((destructor
== 1) && (i
== 21))
3206 switch (vms_name_mapping
)
3211 Case_Hack_Bits
|= 1;
3213 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3216 case 3: *Out
++ = *In
++;
3222 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3228 * If we saw a dollar sign, we don't do case hacking
3230 if (flagseen
['h'] || Saw_Dollar
)
3234 * If we have more than 23 characters and everything is lowercase
3235 * we can insert the full 31 characters
3240 * We have more than 23 characters
3241 * If we must add the case hack, then we have truncated the str
3245 if (Case_Hack_Bits
== 0)
3248 * And so far they are all lower case:
3249 * Check up to 8 more characters
3250 * and ensure that they are lowercase
3252 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3253 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3259 if ((i
== 8) || (In
[i
] == 0))
3262 * They are: Copy up to 31 characters
3263 * to the output string
3266 while ((--i
>= 0) && (*In
))
3267 switch (vms_name_mapping
){
3268 case 0: *Out
++ = islower(*In
) ?
3272 case 3: *Out
++ = *In
++;
3274 case 2: *Out
++ = isupper(*In
) ?
3283 * If there were any uppercase characters in the name we
3284 * take on the case hacking string
3287 /* Old behavior for regular GNU-C compiler */
3290 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3295 for (i
= 0; i
< 6; i
++)
3297 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3298 Case_Hack_Bits
>>= 4;
3304 Out
= pnt
; /*Cut back to 23 characters maximum */
3306 for (i
= 0; i
< 7; i
++)
3308 init
= result
& 0x01f;
3310 *Out
++ = '0' + init
;
3312 *Out
++ = 'A' + init
- 10;
3313 result
= result
>> 5;
3321 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3322 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3327 * Scan a symbol name for a psect attribute specification
3329 #define GLOBALSYMBOL_BIT 0x10000
3330 #define GLOBALVALUE_BIT 0x20000
3334 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3336 int *Attribute_Pointer
;
3347 {"PIC", GPS_S_M_PIC
},
3348 {"LIB", GPS_S_M_LIB
},
3349 {"OVR", GPS_S_M_OVR
},
3350 {"REL", GPS_S_M_REL
},
3351 {"GBL", GPS_S_M_GBL
},
3352 {"SHR", GPS_S_M_SHR
},
3353 {"EXE", GPS_S_M_EXE
},
3355 {"WRT", GPS_S_M_WRT
},
3356 {"VEC", GPS_S_M_VEC
},
3357 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3358 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3368 * Check for a PSECT attribute list
3370 if (!HAS_PSECT_ATTRIBUTES (Name
))
3371 return; /* If not, return */
3373 * Skip the attribute list indicator
3375 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3377 * Process the attributes ("_" separated, "$" terminated)
3379 while (*Name
!= '$')
3382 * Assume not negating
3388 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3391 * We are negating (and skip the NO)
3397 * Find the token delimiter
3400 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3403 * Look for the token in the attribute list
3405 for (i
= 0; Attributes
[i
].Name
; i
++)
3408 * If the strings match, set/clear the attr.
3410 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3416 *Attribute_Pointer
&=
3417 ~Attributes
[i
].Value
;
3419 *Attribute_Pointer
|=
3420 Attributes
[i
].Value
;
3428 * Now skip the attribute
3442 * Define a global symbol
3445 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3453 * We are writing a GSD record
3455 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3457 * If the buffer is empty we must insert the GSD record type
3459 if (Object_Record_Offset
== 0)
3460 PUT_CHAR (OBJ_S_C_GSD
);
3462 * We are writing a Global symbol definition subrecord
3464 if (Psect_Number
<= 255)
3466 PUT_CHAR (GSD_S_C_SYM
);
3470 PUT_CHAR (GSD_S_C_SYMW
);
3473 * Data type is undefined
3477 * Switch on Definition/Reference
3479 if ((Defined
& 1) != 0)
3483 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3484 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3486 if ((Defined
& 2) == 0)
3488 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3492 PUT_SHORT (GSY_S_M_DEF
);
3497 if (Psect_Number
<= 255)
3499 PUT_CHAR (Psect_Number
);
3503 PUT_SHORT (Psect_Number
);
3508 PUT_LONG (Psect_Offset
);
3514 * Flags = "RELOCATABLE" for regular symbol,
3515 * = "" for globalvalue (Defined & 2 == 1)
3517 if ((Defined
& 2) == 0)
3519 PUT_SHORT (GSY_S_M_REL
);
3527 * Finally, the global symbol name
3529 VMS_Case_Hack_Symbol (Name
, Local
);
3530 PUT_COUNTED_STRING (Local
);
3532 * Flush the buffer if it is more than 75% full
3534 if (Object_Record_Offset
>
3535 (sizeof (Object_Record_Buffer
) * 3 / 4))
3536 Flush_VMS_Object_Record_Buffer ();
3544 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3548 struct VMS_Symbol
*vsp
;
3551 int Psect_Attributes
;
3554 * Generate the appropriate PSECT flags given the PSECT type
3556 if (strcmp (Type
, "COMMON") == 0)
3559 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3561 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3562 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3564 else if (strcmp (Type
, "CONST") == 0)
3567 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3569 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3570 GPS_S_M_SHR
| GPS_S_M_RD
);
3572 else if (strcmp (Type
, "DATA") == 0)
3575 * The Data psects are PIC,REL,RD,WRT
3578 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3580 else if (strcmp (Type
, "TEXT") == 0)
3583 * The Text psects are PIC,REL,SHR,EXE,RD
3586 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3587 GPS_S_M_EXE
| GPS_S_M_RD
);
3592 * Error: Unknown psect type
3594 error ("Unknown VMS psect type");
3597 * Modify the psect attributes according to any attribute string
3599 if (HAS_PSECT_ATTRIBUTES (Name
))
3600 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3602 * Check for globalref/def/val.
3604 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3607 * globalvalue symbols were generated before. This code
3608 * prevents unsightly psect buildup, and makes sure that
3609 * fixup references are emitted correctly.
3611 vsp
->Psect_Index
= -1; /* to catch errors */
3612 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3613 return 1; /* decrement psect counter */
3616 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3618 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3620 case N_UNDF
| N_EXT
:
3621 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3622 vsp
->Psect_Offset
, 0);
3623 vsp
->Psect_Index
= -1;
3624 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3625 return 1; /* return and indicate no psect */
3626 case N_DATA
| N_EXT
:
3627 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3628 vsp
->Psect_Offset
, 1);
3629 /* In this case we still generate the psect */
3633 char Error_Line
[256];
3634 sprintf (Error_Line
,
3635 "Globalsymbol attribute for symbol %s was unexpected.\n",
3643 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3645 * We are writing a GSD record
3647 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3649 * If the buffer is empty we must insert the GSD record type
3651 if (Object_Record_Offset
== 0)
3652 PUT_CHAR (OBJ_S_C_GSD
);
3654 * We are writing a PSECT definition subrecord
3656 PUT_CHAR (GSD_S_C_PSC
);
3658 * Psects are always LONGWORD aligned
3662 * Specify the psect attributes
3664 PUT_SHORT (Psect_Attributes
);
3666 * Specify the allocation
3670 * Finally, the psect name
3672 VMS_Case_Hack_Symbol (Name
, Local
);
3673 PUT_COUNTED_STRING (Local
);
3675 * Flush the buffer if it is more than 75% full
3677 if (Object_Record_Offset
>
3678 (sizeof (Object_Record_Buffer
) * 3 / 4))
3679 Flush_VMS_Object_Record_Buffer ();
3685 * Given the pointer to a symbol we calculate how big the data at the
3686 * symbol is. We do this by looking for the next symbol (local or
3687 * global) which will indicate the start of another datum.
3690 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3691 register struct symbol
*sp
;
3694 register struct symbol
*sp1
, *Next_Symbol
;
3697 * Find the next symbol
3698 * it delimits this datum
3701 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3704 * The data type must match
3706 if (S_GET_TYPE (sp1
) != N_DATA
)
3709 * The symbol must be AFTER this symbol
3711 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3714 * We ignore THIS symbol
3719 * If there is already a candidate selected for the
3720 * next symbol, see if we are a better candidate
3725 * We are a better candidate if we are "closer"
3728 if (S_GET_VALUE (sp1
) >
3729 S_GET_VALUE (Next_Symbol
))
3732 * Win: Make this the candidate
3739 * This is the 1st candidate
3745 * Calculate its size
3747 return (Next_Symbol
?
3748 (S_GET_VALUE (Next_Symbol
) -
3750 (End_Of_Data
- S_GET_VALUE (sp
)));
3754 * Check symbol names for the Psect hack with a globalvalue, and then
3755 * generate globalvalues for those that have it.
3758 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3763 register symbolS
*sp
;
3764 char *stripped_name
, *Name
;
3766 int Psect_Attributes
;
3770 * Scan the symbol table for globalvalues, and emit def/ref when
3771 * required. These will be caught again later and converted to
3774 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3777 * See if this is something we want to look at.
3779 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3780 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3783 * See if this has globalvalue specification.
3785 Name
= S_GET_NAME (sp
);
3787 if (!HAS_PSECT_ATTRIBUTES (Name
))
3790 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3791 strcpy (stripped_name
, Name
);
3792 Psect_Attributes
= 0;
3793 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3795 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3797 switch (S_GET_RAW_TYPE (sp
))
3799 case N_UNDF
| N_EXT
:
3800 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3802 case N_DATA
| N_EXT
:
3803 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3805 error ("Invalid data type for globalvalue");
3808 memcpy (&globalvalue
, Data_Segment
+ S_GET_VALUE (sp
) -
3810 /* Three times for good luck. The linker seems to get confused
3811 if there are fewer than three */
3812 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3813 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3814 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3817 printf (" Invalid globalvalue of %s\n", stripped_name
);
3821 free (stripped_name
); /* clean up */
3828 * Define a procedure entry pt/mask
3831 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3840 * We are writing a GSD record
3842 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3844 * If the buffer is empty we must insert the GSD record type
3846 if (Object_Record_Offset
== 0)
3847 PUT_CHAR (OBJ_S_C_GSD
);
3849 * We are writing a Procedure Entry Pt/Mask subrecord
3851 if (Psect_Number
<= 255)
3853 PUT_CHAR (GSD_S_C_EPM
);
3857 PUT_CHAR (GSD_S_C_EPMW
);
3860 * Data type is undefined
3864 * Flags = "RELOCATABLE" and "DEFINED"
3866 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3870 if (Psect_Number
<= 255)
3872 PUT_CHAR (Psect_Number
);
3876 PUT_SHORT (Psect_Number
);
3881 PUT_LONG (Psect_Offset
);
3885 PUT_SHORT (Entry_Mask
);
3887 * Finally, the global symbol name
3889 VMS_Case_Hack_Symbol (Name
, Local
);
3890 PUT_COUNTED_STRING (Local
);
3892 * Flush the buffer if it is more than 75% full
3894 if (Object_Record_Offset
>
3895 (sizeof (Object_Record_Buffer
) * 3 / 4))
3896 Flush_VMS_Object_Record_Buffer ();
3901 * Set the current location counter to a particular Psect and Offset
3904 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
3910 * We are writing a "Record_Type" record
3912 Set_VMS_Object_File_Record (Record_Type
);
3914 * If the buffer is empty we must insert the record type
3916 if (Object_Record_Offset
== 0)
3917 PUT_CHAR (Record_Type
);
3919 * Stack the Psect base + Longword Offset
3921 if (Psect_Index
< 255)
3923 PUT_CHAR (TIR_S_C_STA_PL
);
3924 PUT_CHAR (Psect_Index
);
3928 PUT_CHAR (TIR_S_C_STA_WPL
);
3929 PUT_SHORT (Psect_Index
);
3933 * Set relocation base
3935 PUT_CHAR (TIR_S_C_CTL_SETRB
);
3937 * Flush the buffer if it is more than 75% full
3939 if (Object_Record_Offset
>
3940 (sizeof (Object_Record_Buffer
) * 3 / 4))
3941 Flush_VMS_Object_Record_Buffer ();
3946 * Store repeated immediate data in current Psect
3949 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
3951 register char *Pointer
;
3957 * Ignore zero bytes/words/longwords
3959 if ((Size
== sizeof (char)) && (*Pointer
== 0))
3961 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
3963 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
3966 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
3967 * then we do it manually
3971 while (--Repeat_Count
>= 0)
3972 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
3976 * We are writing a "Record_Type" record
3978 Set_VMS_Object_File_Record (Record_Type
);
3980 * If the buffer is empty we must insert record type
3982 if (Object_Record_Offset
== 0)
3983 PUT_CHAR (Record_Type
);
3985 * Stack the repeat count
3987 PUT_CHAR (TIR_S_C_STA_LW
);
3988 PUT_LONG (Repeat_Count
);
3990 * And now the command and its data
3992 PUT_CHAR (TIR_S_C_STO_RIVB
);
3995 PUT_CHAR (*Pointer
++);
3997 * Flush the buffer if it is more than 75% full
3999 if (Object_Record_Offset
>
4000 (sizeof (Object_Record_Buffer
) * 3 / 4))
4001 Flush_VMS_Object_Record_Buffer ();
4006 * Store a Position Independent Reference
4009 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4010 Psect
, Psect_Offset
, Record_Type
)
4011 struct symbol
*Symbol
;
4018 register struct VMS_Symbol
*vsp
=
4019 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4023 * We are writing a "Record_Type" record
4025 Set_VMS_Object_File_Record (Record_Type
);
4027 * If the buffer is empty we must insert record type
4029 if (Object_Record_Offset
== 0)
4030 PUT_CHAR (Record_Type
);
4032 * Set to the appropriate offset in the Psect
4037 * For a Code reference we need to fix the operand
4038 * specifier as well (so back up 1 byte)
4040 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4045 * For a Data reference we just store HERE
4047 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4050 * Make sure we are still generating a "Record Type" record
4052 if (Object_Record_Offset
== 0)
4053 PUT_CHAR (Record_Type
);
4055 * Dispatch on symbol type (so we can stack its value)
4057 switch (S_GET_RAW_TYPE (Symbol
))
4062 #ifdef NOT_VAX_11_C_COMPATIBLE
4063 case N_UNDF
| N_EXT
:
4064 case N_DATA
| N_EXT
:
4065 #endif /* NOT_VAX_11_C_COMPATIBLE */
4067 case N_TEXT
| N_EXT
:
4069 * Get the symbol name (case hacked)
4071 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4073 * Stack the global symbol value
4075 PUT_CHAR (TIR_S_C_STA_GBL
);
4076 PUT_COUNTED_STRING (Local
);
4080 * Stack the longword offset
4082 PUT_CHAR (TIR_S_C_STA_LW
);
4085 * Add the two, leaving the result on the stack
4087 PUT_CHAR (TIR_S_C_OPR_ADD
);
4091 * Uninitialized local data
4095 * Stack the Psect (+offset)
4097 if (vsp
->Psect_Index
< 255)
4099 PUT_CHAR (TIR_S_C_STA_PL
);
4100 PUT_CHAR (vsp
->Psect_Index
);
4104 PUT_CHAR (TIR_S_C_STA_WPL
);
4105 PUT_SHORT (vsp
->Psect_Index
);
4107 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4114 * Stack the Psect (+offset)
4116 if (vsp
->Psect_Index
< 255)
4118 PUT_CHAR (TIR_S_C_STA_PL
);
4119 PUT_CHAR (vsp
->Psect_Index
);
4123 PUT_CHAR (TIR_S_C_STA_WPL
);
4124 PUT_SHORT (vsp
->Psect_Index
);
4126 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4129 * Initialized local or global data
4132 #ifndef NOT_VAX_11_C_COMPATIBLE
4133 case N_UNDF
| N_EXT
:
4134 case N_DATA
| N_EXT
:
4135 #endif /* NOT_VAX_11_C_COMPATIBLE */
4137 * Stack the Psect (+offset)
4139 if (vsp
->Psect_Index
< 255)
4141 PUT_CHAR (TIR_S_C_STA_PL
);
4142 PUT_CHAR (vsp
->Psect_Index
);
4146 PUT_CHAR (TIR_S_C_STA_WPL
);
4147 PUT_SHORT (vsp
->Psect_Index
);
4149 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4153 * Store either a code or data reference
4155 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4157 * Flush the buffer if it is more than 75% full
4159 if (Object_Record_Offset
>
4160 (sizeof (Object_Record_Buffer
) * 3 / 4))
4161 Flush_VMS_Object_Record_Buffer ();
4166 * Check in the text area for an indirect pc-relative reference
4167 * and fix it up with addressing mode 0xff [PC indirect]
4169 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4170 * PIC CODE GENERATING FIXUP ROUTINE.
4173 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4176 register fragS
*fragP
;
4177 struct frag
*text_frag_root
;
4180 * The addressing mode byte is 1 byte before the address
4184 * Is it in THIS frag??
4186 if ((Offset
< fragP
->fr_address
) ||
4187 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4190 * We need to search for the fragment containing this
4193 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4195 if ((Offset
>= fragP
->fr_address
) &&
4196 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4200 * If we couldn't find the frag, things are BAD!!
4203 error ("Couldn't find fixup fragment when checking for indirect reference");
4206 * Check for indirect PC relative addressing mode
4208 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4210 static char Address_Mode
= 0xff;
4213 * Yes: Store the indirect mode back into the image
4214 * to fix up the damage done by STO_PICR
4216 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4217 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4224 * This is a hacked _doprnt() for VAX-11 "C". It understands that
4225 * it is ONLY called by as_fatal(Format, Args) with a pointer to the
4226 * "Args" argument. From this we can make it all work right!
4228 #if !defined(eunice) && defined(HO_VMS)
4229 _doprnt (Format
, a
, f
)
4234 int Nargs
= ((int *) a
)[-2]; /* This understands as_fatal() */
4239 fprintf (f
, "_doprnt error on \"%s\"!!", Format
);
4242 fprintf (f
, Format
);
4245 fprintf (f
, Format
, a
[0]);
4248 fprintf (f
, Format
, a
[0], a
[1]);
4251 fprintf (f
, Format
, a
[0], a
[1], a
[2]);
4254 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3]);
4257 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4]);
4260 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
4263 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6]);
4266 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]);
4269 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8]);
4278 * If the procedure "main()" exists we have to add the instruction
4279 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4281 VMS_Check_For_Main ()
4283 register symbolS
*symbolP
;
4284 #ifdef HACK_DEC_C_STARTUP /* JF */
4285 register struct frchain
*frchainP
;
4286 register fragS
*fragP
;
4287 register fragS
**prev_fragPP
;
4288 register struct fix
*fixP
;
4289 register fragS
*New_Frag
;
4291 #endif /* HACK_DEC_C_STARTUP */
4293 symbolP
= (struct symbol
*) symbol_find ("_main");
4294 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4295 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4297 #ifdef HACK_DEC_C_STARTUP
4302 * Remember the entry point symbol
4304 Entry_Point_Symbol
= symbolP
;
4305 #ifdef HACK_DEC_C_STARTUP
4310 * Scan all the fragment chains for the one with "_main"
4311 * (Actually we know the fragment from the symbol, but we need
4312 * the previous fragment so we can change its pointer)
4314 frchainP
= frchain_root
;
4318 * Scan all the fragments in this chain, remembering
4319 * the "previous fragment"
4321 prev_fragPP
= &frchainP
->frch_root
;
4322 fragP
= frchainP
->frch_root
;
4323 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4326 * Is this the fragment?
4328 if (fragP
== symbolP
->sy_frag
)
4331 * Yes: Modify the fragment by replacing
4332 * it with a new fragment.
4334 New_Frag
= (fragS
*)
4335 xmalloc (sizeof (*New_Frag
) +
4340 * The fragments are the same except
4341 * that the "fixed" area is larger
4344 New_Frag
->fr_fix
+= 6;
4346 * Copy the literal data opening a hole
4347 * 2 bytes after "_main" (i.e. just after
4348 * the entry mask). Into which we place
4349 * the JSB instruction.
4351 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4352 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4353 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4354 New_Frag
->fr_literal
[3] = 0xef;
4355 New_Frag
->fr_literal
[4] = 0;
4356 New_Frag
->fr_literal
[5] = 0;
4357 New_Frag
->fr_literal
[6] = 0;
4358 New_Frag
->fr_literal
[7] = 0;
4359 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4360 New_Frag
->fr_literal
[i
+ 6] =
4361 fragP
->fr_literal
[i
];
4363 * Now replace the old fragment with the
4364 * newly generated one.
4366 *prev_fragPP
= New_Frag
;
4368 * Remember the entry point symbol
4370 Entry_Point_Symbol
= symbolP
;
4372 * Scan the text area fixup structures
4373 * as offsets in the fragment may have
4376 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4379 * Look for references to this
4382 if (fixP
->fx_frag
== fragP
)
4385 * Change the fragment
4388 fixP
->fx_frag
= New_Frag
;
4390 * If the offset is after
4391 * the entry mask we need
4392 * to account for the JSB
4393 * instruction we just
4396 if (fixP
->fx_where
>= 2)
4397 fixP
->fx_where
+= 6;
4401 * Scan the symbols as offsets in the
4402 * fragment may have changed
4404 for (symbolP
= symbol_rootP
;
4406 symbolP
= symbol_next (symbolP
))
4409 * Look for references to this
4412 if (symbolP
->sy_frag
== fragP
)
4415 * Change the fragment
4418 symbolP
->sy_frag
= New_Frag
;
4420 * If the offset is after
4421 * the entry mask we need
4422 * to account for the JSB
4423 * instruction we just
4426 if (S_GET_VALUE (symbolP
) >= 2)
4427 S_GET_VALUE (symbolP
) += 6;
4431 * Make a symbol reference to
4432 * "_c$main_args" so we can get
4433 * its address inserted into the
4436 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4437 S_GET_NAME (symbolP
) = "_c$main_args";
4438 S_SET_TYPE (symbolP
, N_UNDF
);
4439 S_GET_OTHER (symbolP
) = 0;
4440 S_GET_DESC (symbolP
) = 0;
4441 S_GET_VALUE (symbolP
) = 0;
4442 symbolP
->sy_name_offset
= 0;
4443 symbolP
->sy_number
= 0;
4444 symbolP
->sy_frag
= New_Frag
;
4445 symbolP
->sy_forward
= 0;
4446 /* this actually inserts at the beginning of the list */
4447 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4449 symbol_rootP
= symbolP
;
4451 * Generate a text fixup structure
4452 * to get "_c$main_args" stored into the
4455 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4456 fixP
->fx_frag
= New_Frag
;
4458 fixP
->fx_addsy
= symbolP
;
4460 fixP
->fx_offset
= 0;
4461 fixP
->fx_size
= sizeof (long);
4463 fixP
->fx_next
= text_fix_root
;
4464 text_fix_root
= fixP
;
4466 * Now make sure we exit from the loop
4472 * Try the next fragment
4474 prev_fragPP
= &fragP
->fr_next
;
4475 fragP
= fragP
->fr_next
;
4478 * Try the next fragment chain
4481 frchainP
= frchainP
->frch_next
;
4484 #endif /* HACK_DEC_C_STARTUP */
4489 * Write a VAX/VMS object file (everything else has been done!)
4491 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4496 struct frag
*text_frag_root
;
4497 struct frag
*data_frag_root
;
4499 register fragS
*fragP
;
4500 register symbolS
*symbolP
;
4501 register symbolS
*sp
;
4502 register struct fix
*fixP
;
4503 register struct VMS_Symbol
*vsp
;
4505 int Local_Initialized_Data_Size
= 0;
4507 int Psect_Number
= 0; /* Psect Index Number */
4508 int Text_Psect
= -1; /* Text Psect Index */
4509 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4510 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4513 * Create the VMS object file
4515 Create_VMS_Object_File ();
4517 * Write the module header records
4519 Write_VMS_MHD_Records ();
4522 * Store the Data segment:
4524 * Since this is REALLY hard to do any other way,
4525 * we actually manufacture the data segment and
4526 * the store the appropriate values out of it.
4527 * We need to generate this early, so that globalvalues
4528 * can be properly emitted.
4533 * Allocate the data segment
4535 Data_Segment
= (char *) xmalloc (data_siz
);
4537 * Run through the data fragments, filling in the segment
4539 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4541 register long int count
;
4542 register char *fill_literal
;
4543 register long int fill_size
;
4546 i
= fragP
->fr_address
- text_siz
;
4548 memcpy (Data_Segment
+ i
,
4553 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4554 fill_size
= fragP
->fr_var
;
4555 for (count
= fragP
->fr_offset
; count
; count
--)
4558 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4566 * Generate the VMS object file records
4567 * 1st GSD then TIR records
4570 /******* Global Symbol Dictionary *******/
4572 * Emit globalvalues now. We must do this before the text psect
4573 * is defined, or we will get linker warnings about multiply defined
4574 * symbols. All of the globalvalues "reference" psect 0, although
4575 * it really does not have anything to do with it.
4577 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4579 * Define the Text Psect
4581 Text_Psect
= Psect_Number
++;
4582 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4584 * Define the BSS Psect
4588 Bss_Psect
= Psect_Number
++;
4589 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4591 #ifndef gxx_bug_fixed
4593 * The g++ compiler does not write out external references to vtables
4594 * correctly. Check for this and holler if we see it happening.
4595 * If that compiler bug is ever fixed we can remove this.
4597 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4600 * Dispatch on symbol type
4602 switch (S_GET_RAW_TYPE (sp
)) {
4608 * Make a GSD global symbol reference
4611 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4613 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4614 as_warn("g++ wrote an extern reference to %s as a routine.",
4616 as_warn("I will fix it, but I hope that it was not really a routine");
4623 #endif /* gxx_bug_fixed */
4625 * Now scan the symbols and emit the appropriate GSD records
4627 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4630 * Dispatch on symbol type
4632 switch (S_GET_RAW_TYPE (sp
))
4635 * Global uninitialized data
4637 case N_UNDF
| N_EXT
:
4639 * Make a VMS data symbol entry
4641 vsp
= (struct VMS_Symbol
*)
4642 xmalloc (sizeof (*vsp
));
4644 vsp
->Size
= S_GET_VALUE (sp
);
4645 vsp
->Psect_Index
= Psect_Number
++;
4646 vsp
->Psect_Offset
= 0;
4647 vsp
->Next
= VMS_Symbols
;
4649 sp
->sy_number
= (int) vsp
;
4651 * Make the psect for this data
4653 if (S_GET_OTHER (sp
))
4654 Globalref
= VMS_Psect_Spec (
4660 Globalref
= VMS_Psect_Spec (
4667 #ifdef NOT_VAX_11_C_COMPATIBLE
4669 * Place a global symbol at the
4670 * beginning of the Psect
4672 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4676 #endif /* NOT_VAX_11_C_COMPATIBLE */
4679 * Local uninitialized data
4683 * Make a VMS data symbol entry
4685 vsp
= (struct VMS_Symbol
*)
4686 xmalloc (sizeof (*vsp
));
4689 vsp
->Psect_Index
= Bss_Psect
;
4692 bss_address_frag
.fr_address
;
4693 vsp
->Next
= VMS_Symbols
;
4695 sp
->sy_number
= (int) vsp
;
4698 * Global initialized data
4700 case N_DATA
| N_EXT
:
4702 * Make a VMS data symbol entry
4704 vsp
= (struct VMS_Symbol
*)
4705 xmalloc (sizeof (*vsp
));
4707 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4708 text_siz
+ data_siz
);
4709 vsp
->Psect_Index
= Psect_Number
++;
4710 vsp
->Psect_Offset
= 0;
4711 vsp
->Next
= VMS_Symbols
;
4713 sp
->sy_number
= (int) vsp
;
4717 if (S_GET_OTHER (sp
))
4718 Globalref
= VMS_Psect_Spec (
4724 Globalref
= VMS_Psect_Spec (
4731 #ifdef NOT_VAX_11_C_COMPATIBLE
4733 * Place a global symbol at the
4734 * beginning of the Psect
4736 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4740 #endif /* NOT_VAX_11_C_COMPATIBLE */
4743 * Local initialized data
4747 * Make a VMS data symbol entry
4749 vsp
= (struct VMS_Symbol
*)
4750 xmalloc (sizeof (*vsp
));
4753 VMS_Initialized_Data_Size (sp
,
4754 text_siz
+ data_siz
);
4755 vsp
->Psect_Index
= Data_Psect
;
4757 Local_Initialized_Data_Size
;
4758 Local_Initialized_Data_Size
+= vsp
->Size
;
4759 vsp
->Next
= VMS_Symbols
;
4761 sp
->sy_number
= (int) vsp
;
4764 * Global Text definition
4766 case N_TEXT
| N_EXT
:
4768 unsigned short Entry_Mask
;
4771 * Get the entry mask
4773 fragP
= sp
->sy_frag
;
4774 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4775 ((fragP
->fr_literal
[1] & 0xff)
4778 * Define the Procedure entry pt.
4780 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4787 * Local Text definition
4791 * Make a VMS data symbol entry
4793 if (Text_Psect
!= -1)
4795 vsp
= (struct VMS_Symbol
*)
4796 xmalloc (sizeof (*vsp
));
4799 vsp
->Psect_Index
= Text_Psect
;
4800 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4801 vsp
->Next
= VMS_Symbols
;
4803 sp
->sy_number
= (int) vsp
;
4811 * Make a GSD global symbol reference
4814 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4824 * Ignore STAB symbols
4825 * Including .stabs emitted by g++
4827 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4832 if (S_GET_TYPE (sp
) != 22)
4833 printf (" ERROR, unknown type (%d)\n",
4839 * Define the Data Psect
4841 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4846 Data_Psect
= Psect_Number
++;
4847 VMS_Psect_Spec ("$data",
4848 Local_Initialized_Data_Size
,
4851 * Scan the VMS symbols and fill in the data psect
4853 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4856 * Only look for undefined psects
4858 if (vsp
->Psect_Index
< 0)
4861 * And only initialized data
4863 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4864 vsp
->Psect_Index
= Data_Psect
;
4869 /******* Text Information and Relocation Records *******/
4871 * Write the text segment data
4876 * Scan the text fragments
4878 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4881 * Stop if we get to the data fragments
4883 if (fragP
== data_frag_root
)
4886 * Ignore fragments with no data
4888 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4891 * Go the the appropriate offset in the
4894 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4896 * Store the "fixed" part
4899 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4903 * Store the "variable" part
4905 if (fragP
->fr_var
&& fragP
->fr_offset
)
4906 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4913 * Now we go through the text segment fixups and
4914 * generate TIR records to fix up addresses within
4917 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4920 * We DO handle the case of "Symbol - Symbol" as
4921 * long as it is in the same segment.
4923 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4928 * They need to be in the same segment
4930 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4931 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4932 error ("Fixup data addsy and subsy didn't have the same type");
4934 * And they need to be in one that we
4935 * can check the psect on
4937 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4938 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4939 error ("Fixup data addsy and subsy didn't have an appropriate type");
4941 * This had better not be PC relative!
4944 error ("Fixup data was erroneously \"pcrel\"");
4946 * Subtract their values to get the
4949 i
= S_GET_VALUE (fixP
->fx_addsy
) -
4950 S_GET_VALUE (fixP
->fx_subsy
);
4952 * Now generate the fixup object records
4953 * Set the psect and store the data
4955 VMS_Set_Psect (Text_Psect
,
4957 fixP
->fx_frag
->fr_address
,
4959 VMS_Store_Immediate_Data (&i
,
4968 * Size will HAVE to be "long"
4970 if (fixP
->fx_size
!= sizeof (long))
4971 error ("Fixup datum was not a longword");
4973 * Symbol must be "added" (if it is ever
4975 * fix this assumption)
4977 if (fixP
->fx_addsy
== 0)
4978 error ("Fixup datum was not \"fixP->fx_addsy\"");
4980 * Store the symbol value in a PIC fashion
4982 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4987 fixP
->fx_frag
->fr_address
,
4990 * Check for indirect address reference,
4991 * which has to be fixed up (as the linker
4992 * will screw it up with TIR_S_C_STO_PICR).
4995 VMS_Fix_Indirect_Reference (Text_Psect
,
4997 fixP
->fx_frag
->fr_address
,
5003 * Store the Data segment:
5005 * Since this is REALLY hard to do any other way,
5006 * we actually manufacture the data segment and
5007 * the store the appropriate values out of it.
5008 * The segment was manufactured before, now we just
5009 * dump it into the appropriate psects.
5015 * Now we can run through all the data symbols
5016 * and store the data
5018 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5021 * Ignore anything other than data symbols
5023 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5026 * Set the Psect + Offset
5028 VMS_Set_Psect (vsp
->Psect_Index
,
5034 VMS_Store_Immediate_Data (Data_Segment
+
5035 S_GET_VALUE (vsp
->Symbol
) -
5041 * Now we go through the data segment fixups and
5042 * generate TIR records to fix up addresses within
5045 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5048 * Find the symbol for the containing datum
5050 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5053 * Only bother with Data symbols
5056 if (S_GET_TYPE (sp
) != N_DATA
)
5059 * Ignore symbol if After fixup
5061 if (S_GET_VALUE (sp
) >
5063 fixP
->fx_frag
->fr_address
))
5066 * See if the datum is here
5068 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5070 fixP
->fx_frag
->fr_address
))
5073 * We DO handle the case of "Symbol - Symbol" as
5074 * long as it is in the same segment.
5076 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5081 * They need to be in the same segment
5083 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5084 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5085 error ("Fixup data addsy and subsy didn't have the same type");
5087 * And they need to be in one that we
5088 * can check the psect on
5090 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5091 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5092 error ("Fixup data addsy and subsy didn't have an appropriate type");
5094 * This had better not be PC relative!
5097 error ("Fixup data was erroneously \"pcrel\"");
5099 * Subtract their values to get the
5102 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5103 S_GET_VALUE (fixP
->fx_subsy
);
5105 * Now generate the fixup object records
5106 * Set the psect and store the data
5108 VMS_Set_Psect (vsp
->Psect_Index
,
5109 fixP
->fx_frag
->fr_address
+
5111 S_GET_VALUE (vsp
->Symbol
) +
5114 VMS_Store_Immediate_Data (&i
,
5123 * Size will HAVE to be "long"
5125 if (fixP
->fx_size
!= sizeof (long))
5126 error ("Fixup datum was not a longword");
5128 * Symbol must be "added" (if it is ever
5130 * fix this assumption)
5132 if (fixP
->fx_addsy
== 0)
5133 error ("Fixup datum was not \"fixP->fx_addsy\"");
5135 * Store the symbol value in a PIC fashion
5137 VMS_Store_PIC_Symbol_Reference (
5142 fixP
->fx_frag
->fr_address
+
5144 S_GET_VALUE (vsp
->Symbol
) +
5157 * Write the Traceback Begin Module record
5159 VMS_TBT_Module_Begin ();
5161 * Scan the symbols and write out the routines
5162 * (this makes the assumption that symbols are in
5163 * order of ascending text segment offset)
5166 struct symbol
*Current_Routine
= 0;
5167 int Current_Line_Number
= 0;
5168 int Current_Offset
= -1;
5169 struct input_file
*Current_File
;
5171 /* Output debugging info for global variables and static variables that are not
5172 * specific to one routine. We also need to examine all stabs directives, to
5173 * find the definitions to all of the advanced data types, and this is done by
5174 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5175 * the object file, since there can be forward references in the stabs
5176 * directives. When through with parsing, the text of the stabs directive
5177 * is altered, with the definitions removed, so that later passes will see
5178 * directives as they would be written if the type were already defined.
5180 * We also look for files and include files, and make a list of them. We
5181 * examine the source file numbers to establish the actual lines that code was
5182 * generated from, and then generate offsets.
5185 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5188 * Deal with STAB symbols
5190 if (S_IS_DEBUG (symbolP
))
5193 * Dispatch on STAB type
5195 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5198 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5199 Current_File
->max_line
= S_GET_DESC (symbolP
);
5200 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5201 Current_File
->min_line
= S_GET_DESC (symbolP
);
5204 Current_File
= find_file (symbolP
);
5205 Current_File
->flag
= 1;
5206 Current_File
->min_line
= 1;
5209 Current_File
= find_file (symbolP
);
5212 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5215 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5217 case N_FUN
: /* For static constant symbols */
5219 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5225 /* now we take a quick sweep through the files and assign offsets
5226 to each one. This will essentially be the starting line number to the
5227 debugger for each file. Output the info for the debugger to specify the
5228 files, and then tell it how many lines to use */
5230 int File_Number
= 0;
5231 int Debugger_Offset
= 0;
5233 Current_File
= file_root
;
5234 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5236 if (Current_File
== (struct input_file
*) NULL
)
5238 if (Current_File
->max_line
== 0)
5240 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5243 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5246 /* show a few extra lines at the start of the region selected */
5247 if (Current_File
->min_line
> 2)
5248 Current_File
->min_line
-= 2;
5249 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5250 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5251 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5252 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5255 Current_File
->file_number
= ++File_Number
;
5256 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5257 Current_File
->file_number
);
5258 if (!file_available
)
5260 Current_File
->file_number
= 0;
5265 VMS_TBT_Source_Lines (Current_File
->file_number
,
5266 Current_File
->min_line
,
5267 Current_File
->max_line
- Current_File
->min_line
+ 1);
5270 Current_File
= (struct input_file
*) NULL
;
5272 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5275 * Deal with text symbols
5277 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5280 * Ignore symbols starting with "L",
5281 * as they are local symbols
5283 if (*S_GET_NAME (symbolP
) == 'L')
5286 * If there is a routine start defined,
5289 if (Current_Routine
)
5294 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5297 * Store the routine begin traceback info
5299 if (Text_Psect
!= -1)
5301 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5302 Current_Routine
= symbolP
;
5304 /* Output local symbols, i.e. all symbols that are associated with a specific
5305 * routine. We output them now so the debugger recognizes them as local to
5312 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5314 if (!S_IS_DEBUG (symbolP1
))
5316 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5318 pnt
= S_GET_NAME (symbolP
);
5319 pnt1
= S_GET_NAME (symbolP1
);
5322 while (*pnt
++ == *pnt1
++)
5325 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5326 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5329 if (symbolP1
!= (symbolS
*) NULL
)
5330 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5331 } /* local symbol block */
5338 * Deal with STAB symbols
5340 if (S_IS_DEBUG (symbolP
))
5343 * Dispatch on STAB type
5345 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5351 /* Offset the line into the correct portion
5353 if (Current_File
->file_number
== 0)
5355 /* Sometimes the same offset gets several source
5356 * lines assigned to it.
5357 * We should be selective about which lines
5358 * we allow, we should prefer lines that are
5359 * in the main source file when debugging
5360 * inline functions. */
5361 if ((Current_File
->file_number
!= 1) &&
5362 S_GET_VALUE (symbolP
) ==
5365 /* calculate actual debugger source line */
5366 S_GET_DESC (symbolP
)
5367 += Current_File
->offset
;
5369 * If this is the 1st N_SLINE, setup
5370 * PC/Line correlation. Otherwise
5371 * do the delta PC/Line. If the offset
5372 * for the line number is not +ve we need
5373 * to do another PC/Line correlation
5376 if (Current_Offset
== -1)
5378 VMS_TBT_Line_PC_Correlation (
5379 S_GET_DESC (symbolP
),
5380 S_GET_VALUE (symbolP
),
5386 if ((S_GET_DESC (symbolP
) -
5387 Current_Line_Number
) <= 0)
5390 * Line delta is not +ve, we
5391 * need to close the line and
5392 * start a new PC/Line
5395 VMS_TBT_Line_PC_Correlation (0,
5396 S_GET_VALUE (symbolP
) -
5400 VMS_TBT_Line_PC_Correlation (
5401 S_GET_DESC (symbolP
),
5402 S_GET_VALUE (symbolP
),
5409 * Line delta is +ve, all is well
5411 VMS_TBT_Line_PC_Correlation (
5412 S_GET_DESC (symbolP
) -
5413 Current_Line_Number
,
5414 S_GET_VALUE (symbolP
) -
5421 * Update the current line/PC
5423 Current_Line_Number
= S_GET_DESC (symbolP
);
5424 Current_Offset
= S_GET_VALUE (symbolP
);
5434 * Remember that we had a source file
5435 * and emit the source file debugger
5439 find_file (symbolP
);
5441 /* We need to make sure that we are really in the actual source file when
5442 * we compute the maximum line number. Otherwise the debugger gets really
5446 find_file (symbolP
);
5452 * If there is a routine start defined,
5453 * terminate it (and the line numbers)
5455 if (Current_Routine
)
5458 * Terminate the line numbers
5460 VMS_TBT_Line_PC_Correlation (0,
5461 text_siz
- S_GET_VALUE (Current_Routine
),
5465 * Terminate the routine
5467 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5471 * Write the Traceback End Module TBT record
5473 VMS_TBT_Module_End ();
5476 * Write the End Of Module record
5478 if (Entry_Point_Symbol
== 0)
5479 Write_VMS_EOM_Record (-1, 0);
5481 Write_VMS_EOM_Record (Text_Psect
,
5482 S_GET_VALUE (Entry_Point_Symbol
));
5485 * All done, close the object file
5487 Close_VMS_Object_File ();
5490 /* end of obj-vms.c */