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 (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
)
645 register char *Pointer
;
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 (int Struct_Index
)
772 * We are writing a "OBJ_S_C_DBG" record
774 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
776 * If the buffer is empty we must insert the record type
778 if (Object_Record_Offset
== 0)
779 PUT_CHAR (OBJ_S_C_DBG
);
780 PUT_CHAR (TIR_S_C_STA_UW
);
781 PUT_SHORT (Struct_Index
);
782 PUT_CHAR (TIR_S_C_CTL_STKDL
);
783 PUT_CHAR (TIR_S_C_STO_L
);
785 * Flush the buffer if it is more than 75% full
787 if (Object_Record_Offset
>
788 (sizeof (Object_Record_Buffer
) * 3 / 4))
789 Flush_VMS_Object_Record_Buffer ();
793 * Make a debugger reference to partially define a struct, union or enum.
796 VMS_Def_Struct (int Struct_Index
)
799 * We are writing a "OBJ_S_C_DBG" record
801 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
803 * If the buffer is empty we must insert the record type
805 if (Object_Record_Offset
== 0)
806 PUT_CHAR (OBJ_S_C_DBG
);
807 PUT_CHAR (TIR_S_C_STA_UW
);
808 PUT_SHORT (Struct_Index
);
809 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
811 * Flush the buffer if it is more than 75% full
813 if (Object_Record_Offset
>
814 (sizeof (Object_Record_Buffer
) * 3 / 4))
815 Flush_VMS_Object_Record_Buffer ();
819 VMS_Set_Struct (int Struct_Index
)
820 { /* see previous functions for comments */
821 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
822 if (Object_Record_Offset
== 0)
823 PUT_CHAR (OBJ_S_C_DBG
);
824 PUT_CHAR (TIR_S_C_STA_UW
);
825 PUT_SHORT (Struct_Index
);
826 PUT_CHAR (TIR_S_C_CTL_STLOC
);
827 if (Object_Record_Offset
>
828 (sizeof (Object_Record_Buffer
) * 3 / 4))
829 Flush_VMS_Object_Record_Buffer ();
833 * Write the Traceback Module Begin record
836 VMS_TBT_Module_Begin ()
838 register char *cp
, *cp1
;
840 char Module_Name
[256];
844 * Get module name (the FILENAME part of the object file)
850 if ((*cp
== ']') || (*cp
== '>') ||
851 (*cp
== ':') || (*cp
== '/'))
857 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
861 * Limit it to 31 characters
863 while (--cp1
>= Module_Name
)
866 if (strlen (Module_Name
) > 31)
869 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
873 * Arrange to store the data locally (leave room for size byte)
879 *cp
++ = DST_S_C_MODBEG
;
885 * Language type == "C"
887 *(long *) cp
= DST_S_C_C
;
890 * Store the module name
892 *cp
++ = strlen (Module_Name
);
897 * Now we can store the record size
902 * Put it into the object record
904 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
909 * Write the Traceback Module End record
912 VMS_TBT_Module_End ()
920 Local
[1] = DST_S_C_MODEND
;
922 * Put it into the object record
924 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
929 * Write the Traceback Routine Begin record
932 VMS_TBT_Routine_Begin (symbolP
, Psect
)
933 struct symbol
*symbolP
;
936 register char *cp
, *cp1
;
943 * Strip the leading "_" from the name
945 Name
= S_GET_NAME (symbolP
);
949 * Get the text psect offset
951 Offset
= S_GET_VALUE (symbolP
);
953 * Calculate the record size
955 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
963 Local
[1] = DST_S_C_RTNBEG
;
969 * Store the data so far
971 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
973 * Make sure we are still generating a OBJ_S_C_TBT record
975 if (Object_Record_Offset
== 0)
976 PUT_CHAR (OBJ_S_C_TBT
);
978 * Now get the symbol address
980 PUT_CHAR (TIR_S_C_STA_WPL
);
984 * Store the data reference
986 PUT_CHAR (TIR_S_C_STO_PIDR
);
988 * Store the counted string as data
992 Size
= strlen (cp1
) + 1;
996 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1001 * Write the Traceback Routine End record
1002 * We *must* search the symbol table to find the next routine, since
1003 * the assember has a way of reassembling the symbol table OUT OF ORDER
1004 * Thus the next routine in the symbol list is not necessarily the
1005 * next one in memory. For debugging to work correctly we must know the
1006 * size of the routine.
1009 VMS_TBT_Routine_End (Max_Size
, sp
)
1014 int Size
= 0x7fffffff;
1018 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1020 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1022 if (*S_GET_NAME (symbolP
) == 'L')
1024 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
1025 (S_GET_VALUE (symbolP
) < Size
))
1026 Size
= S_GET_VALUE (symbolP
);
1027 /* check if gcc_compiled. has size of zero */
1028 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
1030 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1031 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1032 Size
= S_GET_VALUE (symbolP
);
1036 if (Size
== 0x7fffffff)
1038 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
1046 Local
[1] = DST_S_C_RTNEND
;
1054 *((long *) (Local
+ 3)) = Size
;
1058 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1062 * Write the Traceback Block End record
1065 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1066 struct symbol
*symbolP
;
1070 register char *cp
, *cp1
;
1077 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1083 * Begin Block - We simulate with a phony routine
1085 Local
[1] = DST_S_C_BLKBEG
;
1091 * Store the data so far
1093 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1095 * Make sure we are still generating a OBJ_S_C_DBG record
1097 if (Object_Record_Offset
== 0)
1098 PUT_CHAR (OBJ_S_C_DBG
);
1100 * Now get the symbol address
1102 PUT_CHAR (TIR_S_C_STA_WPL
);
1105 * Get the text psect offset
1107 Offset
= S_GET_VALUE (symbolP
);
1110 * Store the data reference
1112 PUT_CHAR (TIR_S_C_STO_PIDR
);
1114 * Store the counted string as data
1118 Size
= strlen (cp1
) + 1;
1122 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1127 * Write the Traceback Block End record
1130 VMS_TBT_Block_End (int Size
)
1135 * End block - simulate with a phony end routine
1138 Local
[1] = DST_S_C_BLKEND
;
1139 *((long *) (Local
+ 3)) = Size
;
1144 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1150 * Write a Line number / PC correlation record
1153 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1163 * If not delta, set our PC/Line number correlation
1170 Local
[0] = 1 + 1 + 2 + 1 + 4;
1172 * Line Number/PC correlation
1174 Local
[1] = DST_S_C_LINE_NUM
;
1178 Local
[2] = DST_S_C_SET_LINE_NUM
;
1179 *((unsigned short *) (Local
+ 3)) = Line_Number
- 1;
1183 Local
[5] = DST_S_C_SET_ABS_PC
;
1184 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1186 * Make sure we are still generating a OBJ_S_C_TBT record
1188 if (Object_Record_Offset
== 0)
1189 PUT_CHAR (OBJ_S_C_TBT
);
1192 PUT_CHAR (TIR_S_C_STA_PL
);
1197 PUT_CHAR (TIR_S_C_STA_WPL
);
1201 PUT_CHAR (TIR_S_C_STO_PIDR
);
1203 * Do a PC offset of 0 to register the line number
1206 Local
[1] = DST_S_C_LINE_NUM
;
1207 Local
[2] = 0; /* Increment PC by 0 and register line # */
1208 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1213 * If Delta is negative, terminate the line numbers
1217 Local
[0] = 1 + 1 + 4;
1218 Local
[1] = DST_S_C_LINE_NUM
;
1219 Local
[2] = DST_S_C_TERM_L
;
1220 *((long *) (Local
+ 3)) = Offset
;
1221 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1228 * Do a PC/Line delta
1231 *cp
++ = DST_S_C_LINE_NUM
;
1232 if (Line_Number
> 1)
1235 * We need to increment the line number
1237 if (Line_Number
- 1 <= 255)
1239 *cp
++ = DST_S_C_INCR_LINUM
;
1240 *cp
++ = Line_Number
- 1;
1244 *cp
++ = DST_S_C_INCR_LINUM_W
;
1245 *(short *) cp
= Line_Number
- 1;
1246 cp
+= sizeof (short);
1258 if (Offset
< 0x10000)
1260 *cp
++ = DST_S_C_DELTA_PC_W
;
1261 *(short *) cp
= Offset
;
1262 cp
+= sizeof (short);
1266 *cp
++ = DST_S_C_DELTA_PC_L
;
1267 *(long *) cp
= Offset
;
1268 cp
+= sizeof (long);
1271 Local
[0] = cp
- (Local
+ 1);
1272 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1278 * Describe a source file to the debugger
1281 VMS_TBT_Source_File (Filename
, ID_Number
)
1285 register char *cp
, *cp1
;
1288 #ifndef HO_VMS /* Used for cross-assembly */
1289 i
= strlen (Filename
);
1291 static struct FAB Fab
;
1292 static struct NAM Nam
;
1293 static struct XABDAT Date_Xab
;
1294 static struct XABFHC File_Header_Xab
;
1295 char Es_String
[255], Rs_String
[255];
1300 Fab
.fab$b_bid
= FAB$C_BID
;
1301 Fab
.fab$b_bln
= sizeof (Fab
);
1302 Fab
.fab$l_nam
= (&Nam
);
1303 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1305 * Setup the Nam block so we can find out the FULL name
1306 * of the source file.
1308 Nam
.nam$b_bid
= NAM$C_BID
;
1309 Nam
.nam$b_bln
= sizeof (Nam
);
1310 Nam
.nam$l_rsa
= Rs_String
;
1311 Nam
.nam$b_rss
= sizeof (Rs_String
);
1312 Nam
.nam$l_esa
= Es_String
;
1313 Nam
.nam$b_ess
= sizeof (Es_String
);
1315 * Setup the Date and File Header Xabs
1317 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1318 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1319 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1320 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1321 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1323 * Get the file information
1325 Fab
.fab$l_fna
= Filename
;
1326 Fab
.fab$b_fns
= strlen (Filename
);
1327 Status
= sys$
open (&Fab
);
1330 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1336 * Calculate the size of the resultant string
1343 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1345 * Source declaration
1347 Local
[1] = DST_S_C_SOURCE
;
1349 * Make formfeeds count as source records
1351 Local
[2] = DST_S_C_SRC_FORMFEED
;
1353 * Declare source file
1355 Local
[3] = DST_S_C_SRC_DECLFILE
;
1356 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1365 *(short *) cp
= ID_Number
;
1366 cp
+= sizeof (short);
1369 * Creation Date. Unknown, so we fill with zeroes.
1372 cp
+= sizeof (long);
1374 cp
+= sizeof (long);
1379 cp
+= sizeof (long);
1384 cp
+= sizeof (short);
1394 #else /* Use this code when assembling for VMS on a VMS system */
1398 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1399 cp
+= sizeof (long);
1400 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1401 cp
+= sizeof (long);
1405 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1406 cp
+= sizeof (long);
1410 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1411 cp
+= sizeof (short);
1415 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1425 * Library module name (none)
1431 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1437 * Give the number of source lines to the debugger
1440 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1442 int Starting_Line_Number
;
1443 int Number_Of_Lines
;
1451 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1453 * Source declaration
1455 Local
[1] = DST_S_C_SOURCE
;
1460 *cp
++ = DST_S_C_SRC_SETFILE
;
1464 *(short *) cp
= ID_Number
;
1465 cp
+= sizeof (short);
1469 *cp
++ = DST_S_C_SRC_SETREC_L
;
1470 *(long *) cp
= Starting_Line_Number
;
1471 cp
+= sizeof (long);
1475 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1476 *(short *) cp
= Number_Of_Lines
;
1477 cp
+= sizeof (short);
1481 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1487 /* This routine locates a file in the list of files. If an entry does not
1488 * exist, one is created. For include files, a new entry is always created
1489 * such that inline functions can be properly debugged. */
1490 static struct input_file
*
1494 struct input_file
*same_file
;
1495 struct input_file
*fpnt
;
1496 same_file
= (struct input_file
*) NULL
;
1497 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1499 if (fpnt
== (struct input_file
*) NULL
)
1501 if (fpnt
->spnt
== sp
)
1504 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1506 if (fpnt
== (struct input_file
*) NULL
)
1508 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1510 if (fpnt
->flag
== 1)
1516 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1517 if (file_root
== (struct input_file
*) NULL
)
1521 struct input_file
*fpnt1
;
1522 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1525 fpnt
->next
= (struct input_file
*) NULL
;
1526 fpnt
->name
= S_GET_NAME (sp
);
1527 fpnt
->min_line
= 0x7fffffff;
1531 fpnt
->file_number
= 0;
1533 fpnt
->same_file_fpnt
= same_file
;
1538 * The following functions and definitions are used to generate object records
1539 * that will describe program variables to the VMS debugger.
1541 * This file contains many of the routines needed to output debugging info into
1542 * the object file that the VMS debugger needs to understand symbols. These
1543 * routines are called very late in the assembly process, and thus we can be
1544 * fairly lax about changing things, since the GSD and the TIR sections have
1545 * already been output.
1549 /* This routine converts a number string into an integer, and stops when it
1550 * sees an invalid character the return value is the address of the character
1551 * just past the last character read. No error is generated.
1554 cvt_integer (str
, rtn
)
1559 neg
= *str
== '-' ? ++str
, -1 : 1;
1560 ival
= 0; /* first get the number of the type for dbx */
1561 while ((*str
<= '9') && (*str
>= '0'))
1562 ival
= 10 * ival
+ *str
++ - '0';
1567 /* this routine fixes the names that are generated by C++, ".this" is a good
1568 * example. The period does not work for the debugger, since it looks like
1569 * the syntax for a structure element, and thus it gets mightily confused
1571 * We also use this to strip the PsectAttribute hack from the name before we
1572 * write a debugger record */
1580 * Kill any leading "_"
1585 * Is there a Psect Attribute to skip??
1587 if (HAS_PSECT_ATTRIBUTES (pnt
))
1592 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1595 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1603 /* Here we fix the .this -> $this conversion */
1604 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1612 /* When defining a structure, this routine is called to find the name of
1613 * the actual structure. It is assumed that str points to the equal sign
1614 * in the definition, and it moves backward until it finds the start of the
1615 * name. If it finds a 0, then it knows that this structure def is in the
1616 * outermost level, and thus symbol_name points to the symbol name.
1619 get_struct_name (str
)
1624 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1629 while ((*pnt
!= ';') && (*pnt
!= '='))
1633 while ((*pnt
< '0') || (*pnt
> '9'))
1635 while ((*pnt
>= '0') && (*pnt
<= '9'))
1640 /* search symbol list for type number dbx_type. Return a pointer to struct */
1641 static struct VMS_DBG_Symbol
*
1642 find_symbol (dbx_type
)
1645 struct VMS_DBG_Symbol
*spnt
;
1646 spnt
= VMS_Symbol_type_list
;
1647 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1649 if (spnt
->dbx_type
== dbx_type
)
1653 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1654 return 0; /*Dunno what this is*/
1659 /* this routine puts info into either Local or Asuffix, depending on the sign
1660 * of size. The reason is that it is easier to build the variable descriptor
1661 * backwards, while the array descriptor is best built forwards. In the end
1662 * they get put together, if there is not a struct/union/enum along the way
1673 pnt
= (char *) &val
;
1681 for (i
= 0; i
< size1
; i
++)
1683 Local
[Lpnt
--] = *pnt
--;
1691 for (i
= 0; i
< size1
; i
++)
1693 Asuffix
[Apoint
++] = *pnt
++;
1694 if (Apoint
>= MAX_DEBUG_RECORD
)
1697 Apoint
= MAX_DEBUG_RECORD
- 1;
1702 /* this routine generates the array descriptor for a given array */
1704 array_suffix (spnt2
)
1705 struct VMS_DBG_Symbol
*spnt2
;
1707 struct VMS_DBG_Symbol
*spnt
;
1708 struct VMS_DBG_Symbol
*spnt1
;
1714 while (spnt
->advanced
!= ARRAY
)
1716 spnt
= find_symbol (spnt
->type2
);
1717 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1723 while (spnt1
->advanced
== ARRAY
)
1726 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1727 spnt1
= find_symbol (spnt1
->type2
);
1729 total_size
= total_size
* spnt1
->data_size
;
1730 push (spnt1
->data_size
, 2);
1731 if (spnt1
->VMS_type
== 0xa3)
1734 push (spnt1
->VMS_type
, 1);
1736 for (i
= 0; i
< 6; i
++)
1740 push (total_size
, 4);
1743 while (spnt1
->advanced
== ARRAY
)
1745 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1746 spnt1
= find_symbol (spnt1
->type2
);
1749 while (spnt1
->advanced
== ARRAY
)
1751 push (spnt1
->index_min
, 4);
1752 push (spnt1
->index_max
, 4);
1753 spnt1
= find_symbol (spnt1
->type2
);
1757 /* this routine generates the start of a variable descriptor based upon
1758 * a struct/union/enum that has yet to be defined. We define this spot as
1759 * a new location, and save four bytes for the address. When the struct is
1760 * finally defined, then we can go back and plug in the correct address
1763 new_forward_ref (dbx_type
)
1766 struct forward_ref
*fpnt
;
1767 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1768 fpnt
->next
= f_ref_root
;
1770 fpnt
->dbx_type
= dbx_type
;
1771 fpnt
->struc_numb
= ++structure_count
;
1772 fpnt
->resolved
= 'N';
1775 push (total_len
, -2);
1776 struct_number
= -fpnt
->struc_numb
;
1779 /* this routine generates the variable descriptor used to describe non-basic
1780 * variables. It calls itself recursively until it gets to the bottom of it
1781 * all, and then builds the descriptor backwards. It is easiest to do it this
1782 *way since we must periodically write length bytes, and it is easiest if we know
1783 *the value when it is time to write it.
1786 gen1 (spnt
, array_suffix_len
)
1787 struct VMS_DBG_Symbol
*spnt
;
1788 int array_suffix_len
;
1790 struct VMS_DBG_Symbol
*spnt1
;
1792 switch (spnt
->advanced
)
1795 push (DBG_S_C_VOID
, -1);
1797 push (total_len
, -2);
1801 if (array_suffix_len
== 0)
1803 push (spnt
->VMS_type
, -1);
1804 push (DBG_S_C_BASIC
, -1);
1806 push (total_len
, -2);
1816 struct_number
= spnt
->struc_numb
;
1817 if (struct_number
< 0)
1819 new_forward_ref (spnt
->dbx_type
);
1822 push (DBG_S_C_STRUCT
, -1);
1824 push (total_len
, -2);
1827 spnt1
= find_symbol (spnt
->type2
);
1829 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1830 new_forward_ref (spnt
->type2
);
1832 i
= gen1 (spnt1
, 0);
1834 { /* (*void) is a special case, do not put pointer suffix*/
1835 push (DBG_S_C_POINTER
, -1);
1837 push (total_len
, -2);
1842 while (spnt1
->advanced
== ARRAY
)
1844 spnt1
= find_symbol (spnt1
->type2
);
1845 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1847 printf ("gcc-as warning(debugger output):");
1848 printf ("Forward reference error, dbx type %d\n",
1853 /* It is too late to generate forward references, so the user gets a message.
1854 * This should only happen on a compiler error */
1855 i
= gen1 (spnt1
, 1);
1857 array_suffix (spnt
);
1858 array_suffix_len
= Apoint
- i
;
1859 switch (spnt1
->advanced
)
1867 push (total_len
, -2);
1870 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1872 total_len
+= array_suffix_len
+ 8;
1873 push (total_len
, -2);
1877 /* This generates a suffix for a variable. If it is not a defined type yet,
1878 * then dbx_type contains the type we are expecting so we can generate a
1879 * forward reference. This calls gen1 to build most of the descriptor, and
1880 * then it puts the icing on at the end. It then dumps whatever is needed
1881 * to get a complete descriptor (i.e. struct reference, array suffix ).
1884 generate_suffix (spnt
, dbx_type
)
1885 struct VMS_DBG_Symbol
*spnt
;
1891 {5, 0xaf, 0, 1, 0, 5};
1892 struct VMS_DBG_Symbol
*spnt1
;
1894 Lpnt
= MAX_DEBUG_RECORD
- 1;
1898 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1899 new_forward_ref (dbx_type
);
1902 if (spnt
->VMS_type
!= 0xa3)
1903 return 0; /* no suffix needed */
1908 push (total_len
, -1);
1909 /* if the variable descriptor overflows the record, output a descriptor for
1910 * a pointer to void.
1912 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1914 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1915 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1919 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1920 Local
[i
++] = Local
[++Lpnt
];
1922 /* we use this for a reference to a structure that has already been defined */
1923 if (struct_number
> 0)
1925 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1927 VMS_Store_Struct (struct_number
);
1929 /* we use this for a forward reference to a structure that has yet to be
1930 *defined. We store four bytes of zero to make room for the actual address once
1933 if (struct_number
< 0)
1935 struct_number
= -struct_number
;
1936 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1938 VMS_Def_Struct (struct_number
);
1939 for (i
= 0; i
< 4; i
++)
1941 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1946 Local
[Lpnt
++] = Asuffix
[i
++];
1948 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1952 /* This routine generates a symbol definition for a C sybmol for the debugger.
1953 * It takes a psect and offset for global symbols - if psect < 0, then this is
1954 * a local variable and the offset is relative to FP. In this case it can
1955 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1958 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1959 struct VMS_DBG_Symbol
*spnt
;
1969 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
1971 { /* this is a local variable, referenced to SP */
1972 maxlen
= 7 + strlen (Name_pnt
);
1973 Local
[i
++] = maxlen
;
1974 Local
[i
++] = spnt
->VMS_type
;
1976 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
1978 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
1979 pnt
= (char *) &Offset
;
1980 for (j
= 0; j
< 4; j
++)
1981 Local
[i
++] = *pnt
++; /* copy the offset */
1985 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
1986 Local
[i
++] = 7 + strlen (Name_pnt
);
1987 Local
[i
++] = spnt
->VMS_type
;
1989 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1991 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
1993 Local
[i
++] = strlen (Name_pnt
);
1994 while (*Name_pnt
!= '\0')
1995 Local
[i
++] = *Name_pnt
++;
1996 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1997 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1998 generate_suffix (spnt
, 0);
2002 /* This routine parses the stabs entries in order to make the definition
2003 * for the debugger of local symbols and function parameters
2006 VMS_local_stab_Parse (sp
)
2012 struct VMS_DBG_Symbol
*spnt
;
2013 struct VMS_Symbol
*vsp
;
2017 str
= S_GET_NAME (sp
);
2018 pnt
= (char *) strchr (str
, ':');
2019 if (pnt
== (char *) NULL
)
2020 return; /* no colon present */
2021 pnt1
= pnt
++; /* save this for later, and skip colon */
2023 return 0; /* ignore static constants */
2024 /* there is one little catch that we must be aware of. Sometimes function
2025 * parameters are optimized into registers, and the compiler, in its infiite
2026 * wisdom outputs stabs records for *both*. In general we want to use the
2027 * register if it is present, so we must search the rest of the symbols for
2028 * this function to see if this parameter is assigned to a register.
2036 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2038 if (!S_IS_DEBUG (sp1
))
2040 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2042 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2043 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2045 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2047 str1
= S_GET_NAME (sp1
); /* and get the name */
2049 while (*pnt2
!= ':')
2056 if ((*str1
!= ':') || (*pnt2
!= ':'))
2058 return; /* they are the same! lets skip this one */
2060 /* first find the dbx symbol type from list, and then find VMS type */
2061 pnt
++; /* skip p in case no register */
2064 pnt
= cvt_integer (pnt
, &dbx_type
);
2065 spnt
= find_symbol (dbx_type
);
2066 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2067 return 0; /*Dunno what this is*/
2069 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2070 *pnt1
= ':'; /* and restore the string */
2074 /* This routine parses a stabs entry to find the information required to define
2075 * a variable. It is used for global and static variables.
2076 * Basically we need to know the address of the symbol. With older versions
2077 * of the compiler, const symbols are
2078 * treated differently, in that if they are global they are written into the
2079 * text psect. The global symbol entry for such a const is actually written
2080 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2081 * of psects, we must search the entry points as well. static consts are even
2082 * harder, since they are never assigned a memory address. The compiler passes
2083 * a stab to tell us the value, but I am not sure what to do with it.
2087 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2090 int type1
, type2
, Text_Psect
;
2096 struct VMS_DBG_Symbol
*spnt
;
2097 struct VMS_Symbol
*vsp
;
2101 str
= S_GET_NAME (sp
);
2102 pnt
= (char *) strchr (str
, ':');
2103 if (pnt
== (char *) NULL
)
2104 return; /* no colon present */
2105 pnt1
= pnt
; /* save this for later*/
2107 if (*pnt
== expected_type
)
2109 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2110 spnt
= find_symbol (dbx_type
);
2111 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2112 return 0; /*Dunno what this is*/
2113 /* now we need to search the symbol table to find the psect and offset for
2118 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2120 pnt
= S_GET_NAME (vsp
->Symbol
);
2121 if (pnt
!= (char *) NULL
)
2123 /* make sure name is the same, and make sure correct symbol type */
2124 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2125 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2126 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2130 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2132 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2133 *pnt1
= ':'; /* and restore the string */
2136 /* the symbol was not in the symbol list, but it may be an "entry point"
2137 if it was a constant */
2138 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2141 * Dispatch on STAB type
2143 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2145 pnt
= S_GET_NAME (sp1
);
2148 if (strcmp (pnt
, str
) == 0)
2150 if (!gave_compiler_message
&& expected_type
== 'G')
2152 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2153 printf ("global constant(s) in the text psect. These will not be available to\n");
2154 printf ("other modules, since this is not the correct way to handle this. You\n");
2155 printf ("have two options: 1) get a patched compiler that does not put global\n");
2156 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2157 printf ("definitions of global variables in your source module(s). Don't say\n");
2158 printf ("I didn't warn you!");
2159 gave_compiler_message
= 1;
2161 VMS_DBG_record (spnt
,
2166 *S_GET_NAME (sp1
) = 'L';
2167 /* fool assembler to not output this
2168 * as a routine in the TBT */
2173 *pnt1
= ':'; /* and restore the string */
2178 VMS_GSYM_Parse (sp
, Text_Psect
)
2181 { /* Global variables */
2182 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2187 VMS_LCSYM_Parse (sp
, Text_Psect
)
2190 { /* Static symbols - uninitialized */
2191 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2195 VMS_STSYM_Parse (sp
, Text_Psect
)
2198 { /* Static symbols - initialized */
2199 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2203 /* for register symbols, we must figure out what range of addresses within the
2204 * psect are valid. We will use the brackets in the stab directives to give us
2205 * guidance as to the PC range that this variable is in scope. I am still not
2206 * completely comfortable with this but as I learn more, I seem to get a better
2207 * handle on what is going on.
2211 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2212 symbolS
*sp
, *Current_Routine
;
2219 struct VMS_DBG_Symbol
*spnt
;
2224 int Min_Offset
= -1; /* min PC of validity */
2225 int Max_Offset
= 0; /* max PC of validity */
2227 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2230 * Dispatch on STAB type
2232 switch (S_GET_RAW_TYPE (symbolP
))
2236 Min_Offset
= S_GET_VALUE (symbolP
);
2241 S_GET_VALUE (symbolP
) - 1;
2244 if ((Min_Offset
!= -1) && (bcnt
== 0))
2246 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2248 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2249 if (*pnt
== 'F' || *pnt
== 'f') break;
2252 /* check to see that the addresses were defined. If not, then there were no
2253 * brackets in the function, and we must try to search for the next function
2254 * Since functions can be in any order, we should search all of the symbol list
2255 * to find the correct ending address. */
2256 if (Min_Offset
== -1)
2258 int Max_Source_Offset
;
2260 Min_Offset
= S_GET_VALUE (sp
);
2261 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2264 * Dispatch on STAB type
2266 This_Offset
= S_GET_VALUE (symbolP
);
2267 switch (S_GET_RAW_TYPE (symbolP
))
2269 case N_TEXT
| N_EXT
:
2270 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2271 Max_Offset
= This_Offset
;
2274 if (This_Offset
> Max_Source_Offset
)
2275 Max_Source_Offset
= This_Offset
;
2278 /* if this is the last routine, then we use the PC of the last source line
2279 * as a marker of the max PC for which this reg is valid */
2280 if (Max_Offset
== 0x7fffffff)
2281 Max_Offset
= Max_Source_Offset
;
2284 str
= S_GET_NAME (sp
);
2285 pnt
= (char *) strchr (str
, ':');
2286 if (pnt
== (char *) NULL
)
2287 return; /* no colon present */
2288 pnt1
= pnt
; /* save this for later*/
2292 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2293 spnt
= find_symbol (dbx_type
);
2294 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2295 return 0; /*Dunno what this is yet*/
2297 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2298 maxlen
= 25 + strlen (pnt
);
2299 Local
[i
++] = maxlen
;
2300 Local
[i
++] = spnt
->VMS_type
;
2302 Local
[i
++] = strlen (pnt
) + 1;
2306 Local
[i
++] = strlen (pnt
);
2307 while (*pnt
!= '\0')
2308 Local
[i
++] = *pnt
++;
2314 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2316 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2317 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2319 Local
[i
++] = S_GET_VALUE (sp
);
2323 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2325 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2326 generate_suffix (spnt
, 0);
2329 /* this function examines a structure definition, checking all of the elements
2330 * to make sure that all of them are fully defined. The only thing that we
2331 * kick out are arrays of undefined structs, since we do not know how big
2332 * they are. All others we can handle with a normal forward reference.
2335 forward_reference (pnt
)
2339 struct VMS_DBG_Symbol
*spnt
;
2340 struct VMS_DBG_Symbol
*spnt1
;
2341 pnt
= cvt_integer (pnt
+ 1, &i
);
2343 return 0; /* no forward references */
2346 pnt
= (char *) strchr (pnt
, ':');
2347 pnt
= cvt_integer (pnt
+ 1, &i
);
2348 spnt
= find_symbol (i
);
2349 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2351 while ((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2354 spnt1
= find_symbol (spnt
->type2
);
2355 if ((spnt
->advanced
== ARRAY
) &&
2356 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2358 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2362 pnt
= cvt_integer (pnt
+ 1, &i
);
2363 pnt
= cvt_integer (pnt
+ 1, &i
);
2364 } while (*++pnt
!= ';');
2365 return 0; /* no forward refences found */
2368 /* This routine parses the stabs directives to find any definitions of dbx type
2369 * numbers. It makes a note of all of them, creating a structure element
2370 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2371 * debugger that describes the struct/union/enum, so that further references
2372 * to these data types will be by number
2373 * We have to process pointers right away, since there can be references
2374 * to them later in the same stabs directive. We cannot have forward
2375 * references to pointers, (but we can have a forward reference to a pointer to
2376 * a structure/enum/union) and this is why we process them immediately.
2377 * After we process the pointer, then we search for defs that are nested even
2381 VMS_typedef_parse (str
)
2389 struct forward_ref
*fpnt
;
2391 int convert_integer
;
2392 struct VMS_DBG_Symbol
*spnt
;
2393 struct VMS_DBG_Symbol
*spnt1
;
2394 /* check for any nested def's */
2395 pnt
= (char *) strchr (str
+ 1, '=');
2396 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*'))
2397 if (VMS_typedef_parse (pnt
) == 1)
2399 /* now find dbx_type of entry */
2402 { /* check for static constants */
2403 *str
= '\0'; /* for now we ignore them */
2406 while ((*pnt
<= '9') && (*pnt
>= '0'))
2408 pnt
++; /* and get back to the number */
2409 cvt_integer (pnt
, &i1
);
2410 spnt
= find_symbol (i1
);
2411 /* first we see if this has been defined already, due to a forward reference*/
2412 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2414 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2416 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2417 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2418 VMS_Symbol_type_list
= spnt
;
2422 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2423 spnt
->next
= VMS_Symbol_type_list
;
2424 VMS_Symbol_type_list
= spnt
;
2426 spnt
->dbx_type
= i1
; /* and save the type */
2428 /* for structs and unions, do a partial parse, otherwise we sometimes get
2429 * circular definitions that are impossible to resolve. We read enough info
2430 * so that any reference to this type has enough info to be resolved
2432 pnt
= str
+ 1; /* point to character past equal sign */
2433 if ((*pnt
== 'u') || (*pnt
== 's'))
2436 if ((*pnt
<= '9') && (*pnt
>= '0'))
2438 if (type_check ("void"))
2439 { /* this is the void symbol */
2441 spnt
->advanced
= VOID
;
2444 if (type_check ("unknown type"))
2445 { /* this is the void symbol */
2447 spnt
->advanced
= UNKNOWN
;
2450 printf ("gcc-as warning(debugger output):");
2451 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2452 return 1; /* do not know what this is */
2454 /* now define this module*/
2455 pnt
= str
+ 1; /* point to character past equal sign */
2459 spnt
->advanced
= BASIC
;
2460 if (type_check ("int"))
2462 spnt
->VMS_type
= DBG_S_C_SLINT
;
2463 spnt
->data_size
= 4;
2465 else if (type_check ("long int"))
2467 spnt
->VMS_type
= DBG_S_C_SLINT
;
2468 spnt
->data_size
= 4;
2470 else if (type_check ("unsigned int"))
2472 spnt
->VMS_type
= DBG_S_C_ULINT
;
2473 spnt
->data_size
= 4;
2475 else if (type_check ("long unsigned int"))
2477 spnt
->VMS_type
= DBG_S_C_ULINT
;
2478 spnt
->data_size
= 4;
2480 else if (type_check ("short int"))
2482 spnt
->VMS_type
= DBG_S_C_SSINT
;
2483 spnt
->data_size
= 2;
2485 else if (type_check ("short unsigned int"))
2487 spnt
->VMS_type
= DBG_S_C_USINT
;
2488 spnt
->data_size
= 2;
2490 else if (type_check ("char"))
2492 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2493 spnt
->data_size
= 1;
2495 else if (type_check ("signed char"))
2497 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2498 spnt
->data_size
= 1;
2500 else if (type_check ("unsigned char"))
2502 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2503 spnt
->data_size
= 1;
2505 else if (type_check ("float"))
2507 spnt
->VMS_type
= DBG_S_C_REAL4
;
2508 spnt
->data_size
= 4;
2510 else if (type_check ("double"))
2512 spnt
->VMS_type
= DBG_S_C_REAL8
;
2513 spnt
->data_size
= 8;
2515 pnt1
= (char *) strchr (str
, ';') + 1;
2520 spnt
->advanced
= STRUCT
;
2522 spnt
->advanced
= UNION
;
2523 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2524 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2525 if (forward_reference (pnt
))
2527 spnt
->struc_numb
= -1;
2530 spnt
->struc_numb
= ++structure_count
;
2532 pnt
= get_struct_name (str
);
2533 VMS_Def_Struct (spnt
->struc_numb
);
2535 while (fpnt
!= (struct forward_ref
*) NULL
)
2537 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2539 fpnt
->resolved
= 'Y';
2540 VMS_Set_Struct (fpnt
->struc_numb
);
2541 VMS_Store_Struct (spnt
->struc_numb
);
2545 VMS_Set_Struct (spnt
->struc_numb
);
2547 Local
[i
++] = 11 + strlen (pnt
);
2548 Local
[i
++] = DBG_S_C_STRUCT_START
;
2550 for (i1
= 0; i1
< 4; i1
++)
2552 Local
[i
++] = strlen (pnt
);
2554 while (*pnt2
!= '\0')
2555 Local
[i
++] = *pnt2
++;
2556 i2
= spnt
->data_size
* 8; /* number of bits */
2557 pnt2
= (char *) &i2
;
2558 for (i1
= 0; i1
< 4; i1
++)
2559 Local
[i
++] = *pnt2
++;
2560 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2562 if (pnt
!= symbol_name
)
2564 pnt
+= strlen (pnt
);
2566 }; /* replace colon for later */
2567 while (*++pnt1
!= ';')
2569 pnt
= (char *) strchr (pnt1
, ':');
2572 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2573 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2574 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2575 if ((dtype
== 1) && (i3
!= 32))
2578 push (19 + strlen (pnt2
), 1);
2580 push (1 + strlen (pnt2
), 4);
2581 push (strlen (pnt2
), 1);
2582 while (*pnt2
!= '\0')
2584 push (i3
, 2); /* size of bitfield */
2587 push (i2
, 4); /* start position */
2588 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2593 Local
[i
++] = 7 + strlen (pnt2
);
2594 spnt1
= find_symbol (dtype
);
2595 /* check if this is a forward reference */
2596 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2597 Local
[i
++] = spnt1
->VMS_type
;
2599 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2600 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2602 for (i1
= 0; i1
< 4; i1
++)
2603 Local
[i
++] = *pnt
++;
2604 Local
[i
++] = strlen (pnt2
);
2605 while (*pnt2
!= '\0')
2606 Local
[i
++] = *pnt2
++;
2607 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2609 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2610 generate_suffix (spnt1
, dtype
);
2611 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2612 generate_suffix (spnt1
, 0);
2616 Local
[i
++] = 0x01; /* length byte */
2617 Local
[i
++] = DBG_S_C_STRUCT_END
;
2618 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2622 spnt
->advanced
= ENUM
;
2623 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2624 spnt
->struc_numb
= ++structure_count
;
2625 spnt
->data_size
= 4;
2626 VMS_Def_Struct (spnt
->struc_numb
);
2628 while (fpnt
!= (struct forward_ref
*) NULL
)
2630 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2632 fpnt
->resolved
= 'Y';
2633 VMS_Set_Struct (fpnt
->struc_numb
);
2634 VMS_Store_Struct (spnt
->struc_numb
);
2638 VMS_Set_Struct (spnt
->struc_numb
);
2640 Local
[i
++] = 3 + strlen (symbol_name
);
2641 Local
[i
++] = DBG_S_C_ENUM_START
;
2643 Local
[i
++] = strlen (symbol_name
);
2645 while (*pnt2
!= '\0')
2646 Local
[i
++] = *pnt2
++;
2647 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2649 while (*++pnt
!= ';')
2651 pnt1
= (char *) strchr (pnt
, ':');
2653 pnt1
= cvt_integer (pnt1
, &i1
);
2654 Local
[i
++] = 7 + strlen (pnt
);
2655 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2657 pnt2
= (char *) &i1
;
2658 for (i2
= 0; i2
< 4; i2
++)
2659 Local
[i
++] = *pnt2
++;
2660 Local
[i
++] = strlen (pnt
);
2662 while (*pnt
!= '\0')
2663 Local
[i
++] = *pnt
++;
2664 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2666 pnt
= pnt1
; /* Skip final semicolon */
2668 Local
[i
++] = 0x01; /* len byte */
2669 Local
[i
++] = DBG_S_C_ENUM_END
;
2670 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2675 spnt
->advanced
= ARRAY
;
2676 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2677 pnt
= (char *) strchr (pnt
, ';');
2678 if (pnt
== (char *) NULL
)
2680 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2681 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2682 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2685 spnt
->advanced
= FUNCTION
;
2686 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2687 /* this masquerades as a basic type*/
2688 spnt
->data_size
= 4;
2689 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2692 spnt
->advanced
= POINTER
;
2693 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2694 spnt
->data_size
= 4;
2695 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2696 pnt
= (char *) strchr (str
+ 1, '=');
2697 if ((pnt
!= (char *) NULL
))
2698 if (VMS_typedef_parse (pnt
) == 1)
2702 spnt
->advanced
= UNKNOWN
;
2704 printf ("gcc-as warning(debugger output):");
2705 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2706 return 1; /* unable to decipher */
2708 /* this removes the evidence of the definition so that the outer levels of
2709 parsing do not have to worry about it */
2711 while (*pnt1
!= '\0')
2719 * This is the root routine that parses the stabs entries for definitions.
2720 * it calls VMS_typedef_parse, which can in turn call itself.
2721 * We need to be careful, since sometimes there are forward references to
2722 * other symbol types, and these cannot be resolved until we have completed
2733 int incomplete
, i
, pass
, incom1
;
2734 struct VMS_DBG_Symbol
*spnt
;
2735 struct VMS_Symbol
*vsp
;
2736 struct forward_ref
*fpnt
;
2742 incom1
= incomplete
;
2744 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2747 * Deal with STAB symbols
2749 if (S_IS_DEBUG (sp
))
2752 * Dispatch on STAB type
2754 switch (S_GET_RAW_TYPE (sp
))
2762 case N_FUN
: /*sometimes these contain typedefs*/
2763 str
= S_GET_NAME (sp
);
2765 pnt
= (char *) strchr (str
, ':');
2766 if (pnt
== (char *) NULL
)
2770 pnt2
= (char *) strchr (pnt1
, '=');
2771 if (pnt2
== (char *) NULL
)
2773 *pnt
= ':'; /* replace colon */
2775 }; /* no symbol here */
2776 incomplete
+= VMS_typedef_parse (pnt2
);
2777 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2783 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2784 /* repeat until all refs resolved if possible */
2785 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2786 if (incomplete
!= 0)
2788 printf ("gcc-as warning(debugger output):");
2789 printf ("Unable to resolve %d circular references.\n", incomplete
);
2793 while (fpnt
!= (struct forward_ref
*) NULL
)
2795 if (fpnt
->resolved
!= 'Y')
2797 if (find_symbol (fpnt
->dbx_type
) !=
2798 (struct VMS_DBG_Symbol
*) NULL
)
2800 printf ("gcc-as warning(debugger output):");
2801 printf ("Forward reference error, dbx type %d\n",
2806 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2807 pnt2
= (char *) strchr (&fixit
[1], '=');
2808 VMS_typedef_parse (pnt2
);
2815 Define_Local_Symbols (s1
, s2
)
2819 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2821 if (symbolP1
== (symbolS
*) NULL
)
2823 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2825 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2826 if (*pnt
== 'F' || *pnt
== 'f') break;
2829 * Deal with STAB symbols
2831 if (S_IS_DEBUG (symbolP1
))
2834 * Dispatch on STAB type
2836 switch (S_GET_RAW_TYPE (symbolP1
))
2840 VMS_local_stab_Parse (symbolP1
);
2843 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
2851 /* This function crawls the symbol chain searching for local symbols that need
2852 * to be described to the debugger. When we enter a new scope with a "{", it
2853 * creates a new "block", which helps the debugger keep track of which scope
2854 * we are currently in.
2858 Define_Routine (symbolP
, Level
)
2868 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
2870 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2872 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2873 if (*pnt
== 'F' || *pnt
== 'f') break;
2876 * Deal with STAB symbols
2878 if (S_IS_DEBUG (symbolP1
))
2881 * Dispatch on STAB type
2883 switch (S_GET_RAW_TYPE (symbolP1
))
2888 sprintf (str
, "$%d", rcount
++);
2889 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
2891 Offset
= S_GET_VALUE (symbolP1
);
2892 Define_Local_Symbols (sstart
, symbolP1
);
2894 Define_Routine (symbolP1
, Level
+ 1);
2896 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
2905 /* we end up here if there were no brackets in this function. Define
2907 Define_Local_Symbols (sstart
, (symbolS
*) 0);
2913 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
2915 symbolS
*Curr_Routine
;
2918 Current_Routine
= Curr_Routine
;
2919 Text_Psect
= Txt_Psect
;
2920 Define_Routine (symbolP
, 0);
2927 #include <sys/types.h>
2930 /* Manufacure a VMS like time on a unix based system. */
2931 get_VMS_time_on_unix (char *Now
)
2936 pnt
= ctime (&timeb
);
2942 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
2945 #endif /* not HO_VMS */
2947 * Write the MHD (Module Header) records
2950 Write_VMS_MHD_Records ()
2952 register char *cp
, *cp1
;
2959 char Module_Name
[256];
2963 * We are writing a module header record
2965 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
2967 * ***************************
2968 * *MAIN MODULE HEADER RECORD*
2969 * ***************************
2971 * Store record type and header type
2973 PUT_CHAR (OBJ_S_C_HDR
);
2974 PUT_CHAR (MHD_S_C_MHD
);
2976 * Structure level is 0
2978 PUT_CHAR (OBJ_S_C_STRLVL
);
2980 * Maximum record size is size of the object record buffer
2982 PUT_SHORT (sizeof (Object_Record_Buffer
));
2984 * Get module name (the FILENAME part of the object file)
2990 if ((*cp
== ']') || (*cp
== '>') ||
2991 (*cp
== ':') || (*cp
== '/'))
2997 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3001 * Limit it to 31 characters and store in the object record
3003 while (--cp1
>= Module_Name
)
3006 if (strlen (Module_Name
) > 31)
3009 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3010 Module_Name
[31] = 0;
3012 PUT_COUNTED_STRING (Module_Name
);
3014 * Module Version is "V1.0"
3016 PUT_COUNTED_STRING ("V1.0");
3018 * Creation time is "now" (17 chars of time string)
3021 get_VMS_time_on_unix (&Now
[0]);
3023 Descriptor
.Size
= 17;
3024 Descriptor
.Ptr
= Now
;
3025 sys$
asctim (0, &Descriptor
, 0, 0);
3027 for (i
= 0; i
< 17; i
++)
3030 * Patch time is "never" (17 zeros)
3032 for (i
= 0; i
< 17; i
++)
3037 Flush_VMS_Object_Record_Buffer ();
3039 * *************************
3040 * *LANGUAGE PROCESSOR NAME*
3041 * *************************
3043 * Store record type and header type
3045 PUT_CHAR (OBJ_S_C_HDR
);
3046 PUT_CHAR (MHD_S_C_LNM
);
3048 * Store language processor name and version
3049 * (not a counted string!)
3051 cp
= compiler_version_string
;
3057 cp
= strchr (&version_string
, '.');
3067 Flush_VMS_Object_Record_Buffer ();
3072 * Write the EOM (End Of Module) record
3075 Write_VMS_EOM_Record (Psect
, Offset
)
3080 * We are writing an end-of-module record
3082 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3086 PUT_CHAR (OBJ_S_C_EOM
);
3088 * Store the error severity (0)
3092 * Store the entry point, if it exists
3097 * Store the entry point Psect
3101 * Store the entry point Psect offset
3108 Flush_VMS_Object_Record_Buffer ();
3112 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3118 register unsigned char *p
= ptr
;
3119 register unsigned char *end
= p
+ strlen (ptr
);
3120 register unsigned char c
;
3121 register int hash
= 0;
3126 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3132 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3135 VMS_Case_Hack_Symbol (In
, Out
)
3145 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3147 int Case_Hack_Bits
= 0;
3149 static char Hex_Table
[16] =
3150 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3153 * Kill any leading "_"
3155 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3158 new_name
= Out
; /* save this for later*/
3160 #if barfoo /* Dead code */
3161 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3165 /* We may need to truncate the symbol, save the hash for later*/
3166 if (strlen (In
) > 23)
3167 result
= hash_string (In
);
3169 * Is there a Psect Attribute to skip??
3171 if (HAS_PSECT_ATTRIBUTES (In
))
3176 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3179 if ((In
[0] == '$') && (In
[1] == '$'))
3189 /* if (strlen(In) > 31 && flagseen['+'])
3190 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3192 * Do the case conversion
3194 i
= 23; /* Maximum of 23 chars */
3195 while (*In
&& (--i
>= 0))
3197 Case_Hack_Bits
<<= 1;
3200 if ((destructor
== 1) && (i
== 21))
3202 switch (vms_name_mapping
)
3207 Case_Hack_Bits
|= 1;
3209 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3212 case 3: *Out
++ = *In
++;
3218 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3224 * If we saw a dollar sign, we don't do case hacking
3226 if (flagseen
['h'] || Saw_Dollar
)
3230 * If we have more than 23 characters and everything is lowercase
3231 * we can insert the full 31 characters
3236 * We have more than 23 characters
3237 * If we must add the case hack, then we have truncated the str
3241 if (Case_Hack_Bits
== 0)
3244 * And so far they are all lower case:
3245 * Check up to 8 more characters
3246 * and ensure that they are lowercase
3248 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3249 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3255 if ((i
== 8) || (In
[i
] == 0))
3258 * They are: Copy up to 31 characters
3259 * to the output string
3262 while ((--i
>= 0) && (*In
))
3263 switch (vms_name_mapping
){
3264 case 0: *Out
++ = islower(*In
) ?
3268 case 3: *Out
++ = *In
++;
3270 case 2: *Out
++ = isupper(*In
) ?
3279 * If there were any uppercase characters in the name we
3280 * take on the case hacking string
3283 /* Old behavior for regular GNU-C compiler */
3286 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3291 for (i
= 0; i
< 6; i
++)
3293 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3294 Case_Hack_Bits
>>= 4;
3300 Out
= pnt
; /*Cut back to 23 characters maximum */
3302 for (i
= 0; i
< 7; i
++)
3304 init
= result
& 0x01f;
3306 *Out
++ = '0' + init
;
3308 *Out
++ = 'A' + init
- 10;
3309 result
= result
>> 5;
3317 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3318 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3323 * Scan a symbol name for a psect attribute specification
3325 #define GLOBALSYMBOL_BIT 0x10000
3326 #define GLOBALVALUE_BIT 0x20000
3330 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3332 int *Attribute_Pointer
;
3343 {"PIC", GPS_S_M_PIC
},
3344 {"LIB", GPS_S_M_LIB
},
3345 {"OVR", GPS_S_M_OVR
},
3346 {"REL", GPS_S_M_REL
},
3347 {"GBL", GPS_S_M_GBL
},
3348 {"SHR", GPS_S_M_SHR
},
3349 {"EXE", GPS_S_M_EXE
},
3351 {"WRT", GPS_S_M_WRT
},
3352 {"VEC", GPS_S_M_VEC
},
3353 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3354 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3364 * Check for a PSECT attribute list
3366 if (!HAS_PSECT_ATTRIBUTES (Name
))
3367 return; /* If not, return */
3369 * Skip the attribute list indicator
3371 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3373 * Process the attributes ("_" separated, "$" terminated)
3375 while (*Name
!= '$')
3378 * Assume not negating
3384 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3387 * We are negating (and skip the NO)
3393 * Find the token delimiter
3396 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3399 * Look for the token in the attribute list
3401 for (i
= 0; Attributes
[i
].Name
; i
++)
3404 * If the strings match, set/clear the attr.
3406 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3412 *Attribute_Pointer
&=
3413 ~Attributes
[i
].Value
;
3415 *Attribute_Pointer
|=
3416 Attributes
[i
].Value
;
3424 * Now skip the attribute
3438 * Define a global symbol
3441 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3449 * We are writing a GSD record
3451 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3453 * If the buffer is empty we must insert the GSD record type
3455 if (Object_Record_Offset
== 0)
3456 PUT_CHAR (OBJ_S_C_GSD
);
3458 * We are writing a Global symbol definition subrecord
3460 if (Psect_Number
<= 255)
3462 PUT_CHAR (GSD_S_C_SYM
);
3466 PUT_CHAR (GSD_S_C_SYMW
);
3469 * Data type is undefined
3473 * Switch on Definition/Reference
3475 if ((Defined
& 1) != 0)
3479 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3480 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3482 if ((Defined
& 2) == 0)
3484 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3488 PUT_SHORT (GSY_S_M_DEF
);
3493 if (Psect_Number
<= 255)
3495 PUT_CHAR (Psect_Number
);
3499 PUT_SHORT (Psect_Number
);
3504 PUT_LONG (Psect_Offset
);
3510 * Flags = "RELOCATABLE" for regular symbol,
3511 * = "" for globalvalue (Defined & 2 == 1)
3513 if ((Defined
& 2) == 0)
3515 PUT_SHORT (GSY_S_M_REL
);
3523 * Finally, the global symbol name
3525 VMS_Case_Hack_Symbol (Name
, Local
);
3526 PUT_COUNTED_STRING (Local
);
3528 * Flush the buffer if it is more than 75% full
3530 if (Object_Record_Offset
>
3531 (sizeof (Object_Record_Buffer
) * 3 / 4))
3532 Flush_VMS_Object_Record_Buffer ();
3540 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3544 struct VMS_Symbol
*vsp
;
3547 int Psect_Attributes
;
3550 * Generate the appropriate PSECT flags given the PSECT type
3552 if (strcmp (Type
, "COMMON") == 0)
3555 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3557 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3558 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3560 else if (strcmp (Type
, "CONST") == 0)
3563 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3565 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3566 GPS_S_M_SHR
| GPS_S_M_RD
);
3568 else if (strcmp (Type
, "DATA") == 0)
3571 * The Data psects are PIC,REL,RD,WRT
3574 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3576 else if (strcmp (Type
, "TEXT") == 0)
3579 * The Text psects are PIC,REL,SHR,EXE,RD
3582 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3583 GPS_S_M_EXE
| GPS_S_M_RD
);
3588 * Error: Unknown psect type
3590 error ("Unknown VMS psect type");
3593 * Modify the psect attributes according to any attribute string
3595 if (HAS_PSECT_ATTRIBUTES (Name
))
3596 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3598 * Check for globalref/def/val.
3600 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3603 * globalvalue symbols were generated before. This code
3604 * prevents unsightly psect buildup, and makes sure that
3605 * fixup references are emitted correctly.
3607 vsp
->Psect_Index
= -1; /* to catch errors */
3608 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3609 return 1; /* decrement psect counter */
3612 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3614 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3616 case N_UNDF
| N_EXT
:
3617 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3618 vsp
->Psect_Offset
, 0);
3619 vsp
->Psect_Index
= -1;
3620 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3621 return 1; /* return and indicate no psect */
3622 case N_DATA
| N_EXT
:
3623 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3624 vsp
->Psect_Offset
, 1);
3625 /* In this case we still generate the psect */
3629 char Error_Line
[256];
3630 sprintf (Error_Line
, "Globalsymbol attribute for"
3631 " symbol %s was unexpected.\n", Name
);
3638 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3640 * We are writing a GSD record
3642 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3644 * If the buffer is empty we must insert the GSD record type
3646 if (Object_Record_Offset
== 0)
3647 PUT_CHAR (OBJ_S_C_GSD
);
3649 * We are writing a PSECT definition subrecord
3651 PUT_CHAR (GSD_S_C_PSC
);
3653 * Psects are always LONGWORD aligned
3657 * Specify the psect attributes
3659 PUT_SHORT (Psect_Attributes
);
3661 * Specify the allocation
3665 * Finally, the psect name
3667 VMS_Case_Hack_Symbol (Name
, Local
);
3668 PUT_COUNTED_STRING (Local
);
3670 * Flush the buffer if it is more than 75% full
3672 if (Object_Record_Offset
>
3673 (sizeof (Object_Record_Buffer
) * 3 / 4))
3674 Flush_VMS_Object_Record_Buffer ();
3680 * Given the pointer to a symbol we calculate how big the data at the
3681 * symbol is. We do this by looking for the next symbol (local or
3682 * global) which will indicate the start of another datum.
3685 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3686 register struct symbol
*sp
;
3689 register struct symbol
*sp1
, *Next_Symbol
;
3692 * Find the next symbol
3693 * it delimits this datum
3696 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3699 * The data type must match
3701 if (S_GET_TYPE (sp1
) != N_DATA
)
3704 * The symbol must be AFTER this symbol
3706 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3709 * We ignore THIS symbol
3714 * If there is already a candidate selected for the
3715 * next symbol, see if we are a better candidate
3720 * We are a better candidate if we are "closer"
3723 if (S_GET_VALUE (sp1
) >
3724 S_GET_VALUE (Next_Symbol
))
3727 * Win: Make this the candidate
3734 * This is the 1st candidate
3740 * Calculate its size
3742 return (Next_Symbol
?
3743 (S_GET_VALUE (Next_Symbol
) -
3745 (End_Of_Data
- S_GET_VALUE (sp
)));
3749 * Check symbol names for the Psect hack with a globalvalue, and then
3750 * generate globalvalues for those that have it.
3753 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3758 register symbolS
*sp
;
3759 char *stripped_name
, *Name
;
3761 int Psect_Attributes
;
3765 * Scan the symbol table for globalvalues, and emit def/ref when
3766 * required. These will be caught again later and converted to
3769 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3772 * See if this is something we want to look at.
3774 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3775 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3778 * See if this has globalvalue specification.
3780 Name
= S_GET_NAME (sp
);
3782 if (!HAS_PSECT_ATTRIBUTES (Name
))
3785 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3786 strcpy (stripped_name
, Name
);
3787 Psect_Attributes
= 0;
3788 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3790 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3792 switch (S_GET_RAW_TYPE (sp
))
3794 case N_UNDF
| N_EXT
:
3795 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3797 case N_DATA
| N_EXT
:
3798 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3800 error ("Invalid data type for globalvalue");
3803 memcpy (&globalvalue
, Data_Segment
+ S_GET_VALUE (sp
) -
3805 /* Three times for good luck. The linker seems to get confused
3806 if there are fewer than three */
3807 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3808 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3809 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3812 printf (" Invalid globalvalue of %s\n", stripped_name
);
3816 free (stripped_name
); /* clean up */
3823 * Define a procedure entry pt/mask
3826 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3835 * We are writing a GSD record
3837 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3839 * If the buffer is empty we must insert the GSD record type
3841 if (Object_Record_Offset
== 0)
3842 PUT_CHAR (OBJ_S_C_GSD
);
3844 * We are writing a Procedure Entry Pt/Mask subrecord
3846 if (Psect_Number
<= 255)
3848 PUT_CHAR (GSD_S_C_EPM
);
3852 PUT_CHAR (GSD_S_C_EPMW
);
3855 * Data type is undefined
3859 * Flags = "RELOCATABLE" and "DEFINED"
3861 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3865 if (Psect_Number
<= 255)
3867 PUT_CHAR (Psect_Number
);
3871 PUT_SHORT (Psect_Number
);
3876 PUT_LONG (Psect_Offset
);
3880 PUT_SHORT (Entry_Mask
);
3882 * Finally, the global symbol name
3884 VMS_Case_Hack_Symbol (Name
, Local
);
3885 PUT_COUNTED_STRING (Local
);
3887 * Flush the buffer if it is more than 75% full
3889 if (Object_Record_Offset
>
3890 (sizeof (Object_Record_Buffer
) * 3 / 4))
3891 Flush_VMS_Object_Record_Buffer ();
3896 * Set the current location counter to a particular Psect and Offset
3899 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
3905 * We are writing a "Record_Type" record
3907 Set_VMS_Object_File_Record (Record_Type
);
3909 * If the buffer is empty we must insert the record type
3911 if (Object_Record_Offset
== 0)
3912 PUT_CHAR (Record_Type
);
3914 * Stack the Psect base + Longword Offset
3916 if (Psect_Index
< 255)
3918 PUT_CHAR (TIR_S_C_STA_PL
);
3919 PUT_CHAR (Psect_Index
);
3923 PUT_CHAR (TIR_S_C_STA_WPL
);
3924 PUT_SHORT (Psect_Index
);
3928 * Set relocation base
3930 PUT_CHAR (TIR_S_C_CTL_SETRB
);
3932 * Flush the buffer if it is more than 75% full
3934 if (Object_Record_Offset
>
3935 (sizeof (Object_Record_Buffer
) * 3 / 4))
3936 Flush_VMS_Object_Record_Buffer ();
3941 * Store repeated immediate data in current Psect
3944 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
3946 register char *Pointer
;
3952 * Ignore zero bytes/words/longwords
3954 if ((Size
== sizeof (char)) && (*Pointer
== 0))
3956 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
3958 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
3961 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
3962 * then we do it manually
3966 while (--Repeat_Count
>= 0)
3967 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
3971 * We are writing a "Record_Type" record
3973 Set_VMS_Object_File_Record (Record_Type
);
3975 * If the buffer is empty we must insert record type
3977 if (Object_Record_Offset
== 0)
3978 PUT_CHAR (Record_Type
);
3980 * Stack the repeat count
3982 PUT_CHAR (TIR_S_C_STA_LW
);
3983 PUT_LONG (Repeat_Count
);
3985 * And now the command and its data
3987 PUT_CHAR (TIR_S_C_STO_RIVB
);
3990 PUT_CHAR (*Pointer
++);
3992 * Flush the buffer if it is more than 75% full
3994 if (Object_Record_Offset
>
3995 (sizeof (Object_Record_Buffer
) * 3 / 4))
3996 Flush_VMS_Object_Record_Buffer ();
4001 * Store a Position Independent Reference
4004 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4005 Psect
, Psect_Offset
, Record_Type
)
4006 struct symbol
*Symbol
;
4013 register struct VMS_Symbol
*vsp
=
4014 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4018 * We are writing a "Record_Type" record
4020 Set_VMS_Object_File_Record (Record_Type
);
4022 * If the buffer is empty we must insert record type
4024 if (Object_Record_Offset
== 0)
4025 PUT_CHAR (Record_Type
);
4027 * Set to the appropriate offset in the Psect
4032 * For a Code reference we need to fix the operand
4033 * specifier as well (so back up 1 byte)
4035 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4040 * For a Data reference we just store HERE
4042 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4045 * Make sure we are still generating a "Record Type" record
4047 if (Object_Record_Offset
== 0)
4048 PUT_CHAR (Record_Type
);
4050 * Dispatch on symbol type (so we can stack its value)
4052 switch (S_GET_RAW_TYPE (Symbol
))
4057 #ifdef NOT_VAX_11_C_COMPATIBLE
4058 case N_UNDF
| N_EXT
:
4059 case N_DATA
| N_EXT
:
4060 #endif /* NOT_VAX_11_C_COMPATIBLE */
4062 case N_TEXT
| N_EXT
:
4064 * Get the symbol name (case hacked)
4066 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4068 * Stack the global symbol value
4070 PUT_CHAR (TIR_S_C_STA_GBL
);
4071 PUT_COUNTED_STRING (Local
);
4075 * Stack the longword offset
4077 PUT_CHAR (TIR_S_C_STA_LW
);
4080 * Add the two, leaving the result on the stack
4082 PUT_CHAR (TIR_S_C_OPR_ADD
);
4086 * Uninitialized local data
4090 * Stack the Psect (+offset)
4092 if (vsp
->Psect_Index
< 255)
4094 PUT_CHAR (TIR_S_C_STA_PL
);
4095 PUT_CHAR (vsp
->Psect_Index
);
4099 PUT_CHAR (TIR_S_C_STA_WPL
);
4100 PUT_SHORT (vsp
->Psect_Index
);
4102 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4109 * Stack the Psect (+offset)
4111 if (vsp
->Psect_Index
< 255)
4113 PUT_CHAR (TIR_S_C_STA_PL
);
4114 PUT_CHAR (vsp
->Psect_Index
);
4118 PUT_CHAR (TIR_S_C_STA_WPL
);
4119 PUT_SHORT (vsp
->Psect_Index
);
4121 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4124 * Initialized local or global data
4127 #ifndef NOT_VAX_11_C_COMPATIBLE
4128 case N_UNDF
| N_EXT
:
4129 case N_DATA
| N_EXT
:
4130 #endif /* NOT_VAX_11_C_COMPATIBLE */
4132 * Stack the Psect (+offset)
4134 if (vsp
->Psect_Index
< 255)
4136 PUT_CHAR (TIR_S_C_STA_PL
);
4137 PUT_CHAR (vsp
->Psect_Index
);
4141 PUT_CHAR (TIR_S_C_STA_WPL
);
4142 PUT_SHORT (vsp
->Psect_Index
);
4144 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4148 * Store either a code or data reference
4150 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4152 * Flush the buffer if it is more than 75% full
4154 if (Object_Record_Offset
>
4155 (sizeof (Object_Record_Buffer
) * 3 / 4))
4156 Flush_VMS_Object_Record_Buffer ();
4161 * Check in the text area for an indirect pc-relative reference
4162 * and fix it up with addressing mode 0xff [PC indirect]
4164 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4165 * PIC CODE GENERATING FIXUP ROUTINE.
4168 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4171 register fragS
*fragP
;
4172 struct frag
*text_frag_root
;
4175 * The addressing mode byte is 1 byte before the address
4179 * Is it in THIS frag??
4181 if ((Offset
< fragP
->fr_address
) ||
4182 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4185 * We need to search for the fragment containing this
4188 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4190 if ((Offset
>= fragP
->fr_address
) &&
4191 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4195 * If we couldn't find the frag, things are BAD!!
4198 error ("Couldn't find fixup fragment when checking for indirect reference");
4201 * Check for indirect PC relative addressing mode
4203 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4205 static char Address_Mode
= 0xff;
4208 * Yes: Store the indirect mode back into the image
4209 * to fix up the damage done by STO_PICR
4211 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4212 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4219 * This is a hacked _doprnt() for VAX-11 "C". It understands that
4220 * it is ONLY called by as_fatal(Format, Args) with a pointer to the
4221 * "Args" argument. From this we can make it all work right!
4223 #if !defined(eunice) && defined(HO_VMS)
4224 _doprnt (Format
, a
, f
)
4229 int Nargs
= ((int *) a
)[-2]; /* This understands as_fatal() */
4234 fprintf (f
, "_doprnt error on \"%s\"!!", Format
);
4237 fprintf (f
, Format
);
4240 fprintf (f
, Format
, a
[0]);
4243 fprintf (f
, Format
, a
[0], a
[1]);
4246 fprintf (f
, Format
, a
[0], a
[1], a
[2]);
4249 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3]);
4252 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4]);
4255 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
4258 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6]);
4261 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7]);
4264 fprintf (f
, Format
, a
[0], a
[1], a
[2], a
[3], a
[4], a
[5], a
[6], a
[7], a
[8]);
4273 * If the procedure "main()" exists we have to add the instruction
4274 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4276 VMS_Check_For_Main ()
4278 register symbolS
*symbolP
;
4279 #ifdef HACK_DEC_C_STARTUP /* JF */
4280 register struct frchain
*frchainP
;
4281 register fragS
*fragP
;
4282 register fragS
**prev_fragPP
;
4283 register struct fix
*fixP
;
4284 register fragS
*New_Frag
;
4286 #endif /* HACK_DEC_C_STARTUP */
4288 symbolP
= (struct symbol
*) symbol_find ("_main");
4289 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4290 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4292 #ifdef HACK_DEC_C_STARTUP
4297 * Remember the entry point symbol
4299 Entry_Point_Symbol
= symbolP
;
4300 #ifdef HACK_DEC_C_STARTUP
4305 * Scan all the fragment chains for the one with "_main"
4306 * (Actually we know the fragment from the symbol, but we need
4307 * the previous fragment so we can change its pointer)
4309 frchainP
= frchain_root
;
4313 * Scan all the fragments in this chain, remembering
4314 * the "previous fragment"
4316 prev_fragPP
= &frchainP
->frch_root
;
4317 fragP
= frchainP
->frch_root
;
4318 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4321 * Is this the fragment?
4323 if (fragP
== symbolP
->sy_frag
)
4326 * Yes: Modify the fragment by replacing
4327 * it with a new fragment.
4329 New_Frag
= (fragS
*)
4330 xmalloc (sizeof (*New_Frag
) +
4335 * The fragments are the same except
4336 * that the "fixed" area is larger
4339 New_Frag
->fr_fix
+= 6;
4341 * Copy the literal data opening a hole
4342 * 2 bytes after "_main" (i.e. just after
4343 * the entry mask). Into which we place
4344 * the JSB instruction.
4346 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4347 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4348 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4349 New_Frag
->fr_literal
[3] = 0xef;
4350 New_Frag
->fr_literal
[4] = 0;
4351 New_Frag
->fr_literal
[5] = 0;
4352 New_Frag
->fr_literal
[6] = 0;
4353 New_Frag
->fr_literal
[7] = 0;
4354 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4355 New_Frag
->fr_literal
[i
+ 6] =
4356 fragP
->fr_literal
[i
];
4358 * Now replace the old fragment with the
4359 * newly generated one.
4361 *prev_fragPP
= New_Frag
;
4363 * Remember the entry point symbol
4365 Entry_Point_Symbol
= symbolP
;
4367 * Scan the text area fixup structures
4368 * as offsets in the fragment may have
4371 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4374 * Look for references to this
4377 if (fixP
->fx_frag
== fragP
)
4380 * Change the fragment
4383 fixP
->fx_frag
= New_Frag
;
4385 * If the offset is after
4386 * the entry mask we need
4387 * to account for the JSB
4388 * instruction we just
4391 if (fixP
->fx_where
>= 2)
4392 fixP
->fx_where
+= 6;
4396 * Scan the symbols as offsets in the
4397 * fragment may have changed
4399 for (symbolP
= symbol_rootP
;
4401 symbolP
= symbol_next (symbolP
))
4404 * Look for references to this
4407 if (symbolP
->sy_frag
== fragP
)
4410 * Change the fragment
4413 symbolP
->sy_frag
= New_Frag
;
4415 * If the offset is after
4416 * the entry mask we need
4417 * to account for the JSB
4418 * instruction we just
4421 if (S_GET_VALUE (symbolP
) >= 2)
4422 S_GET_VALUE (symbolP
) += 6;
4426 * Make a symbol reference to
4427 * "_c$main_args" so we can get
4428 * its address inserted into the
4431 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4432 S_GET_NAME (symbolP
) = "_c$main_args";
4433 S_SET_TYPE (symbolP
, N_UNDF
);
4434 S_GET_OTHER (symbolP
) = 0;
4435 S_GET_DESC (symbolP
) = 0;
4436 S_GET_VALUE (symbolP
) = 0;
4437 symbolP
->sy_name_offset
= 0;
4438 symbolP
->sy_number
= 0;
4439 symbolP
->sy_frag
= New_Frag
;
4440 symbolP
->sy_forward
= 0;
4441 /* this actually inserts at the beginning of the list */
4442 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4444 symbol_rootP
= symbolP
;
4446 * Generate a text fixup structure
4447 * to get "_c$main_args" stored into the
4450 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4451 fixP
->fx_frag
= New_Frag
;
4453 fixP
->fx_addsy
= symbolP
;
4455 fixP
->fx_offset
= 0;
4456 fixP
->fx_size
= sizeof (long);
4458 fixP
->fx_next
= text_fix_root
;
4459 text_fix_root
= fixP
;
4461 * Now make sure we exit from the loop
4467 * Try the next fragment
4469 prev_fragPP
= &fragP
->fr_next
;
4470 fragP
= fragP
->fr_next
;
4473 * Try the next fragment chain
4476 frchainP
= frchainP
->frch_next
;
4479 #endif /* HACK_DEC_C_STARTUP */
4484 * Write a VAX/VMS object file (everything else has been done!)
4486 VMS_write_object_file (text_siz
, data_siz
, text_frag_root
, data_frag_root
)
4489 struct frag
*text_frag_root
;
4490 struct frag
*data_frag_root
;
4492 register fragS
*fragP
;
4493 register symbolS
*symbolP
;
4494 register symbolS
*sp
;
4495 register struct fix
*fixP
;
4496 register struct VMS_Symbol
*vsp
;
4498 int Local_Initialized_Data_Size
= 0;
4500 int Psect_Number
= 0; /* Psect Index Number */
4501 int Text_Psect
= -1; /* Text Psect Index */
4502 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4503 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4506 * Create the VMS object file
4508 Create_VMS_Object_File ();
4510 * Write the module header records
4512 Write_VMS_MHD_Records ();
4515 * Store the Data segment:
4517 * Since this is REALLY hard to do any other way,
4518 * we actually manufacture the data segment and
4519 * the store the appropriate values out of it.
4520 * We need to generate this early, so that globalvalues
4521 * can be properly emitted.
4526 * Allocate the data segment
4528 Data_Segment
= (char *) xmalloc (data_siz
);
4530 * Run through the data fragments, filling in the segment
4532 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4534 register long int count
;
4535 register char *fill_literal
;
4536 register long int fill_size
;
4539 i
= fragP
->fr_address
- text_siz
;
4541 memcpy (Data_Segment
+ i
,
4546 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4547 fill_size
= fragP
->fr_var
;
4548 for (count
= fragP
->fr_offset
; count
; count
--)
4551 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4559 * Generate the VMS object file records
4560 * 1st GSD then TIR records
4563 /******* Global Symbol Dictionary *******/
4565 * Emit globalvalues now. We must do this before the text psect
4566 * is defined, or we will get linker warnings about multiply defined
4567 * symbols. All of the globalvalues "reference" psect 0, although
4568 * it really does not have anything to do with it.
4570 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4572 * Define the Text Psect
4574 Text_Psect
= Psect_Number
++;
4575 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4577 * Define the BSS Psect
4579 if (local_bss_counter
> 0)
4581 Bss_Psect
= Psect_Number
++;
4582 VMS_Psect_Spec ("$uninitialized_data", local_bss_counter
, "DATA",
4585 #ifndef gxx_bug_fixed
4587 * The g++ compiler does not write out external references to vtables
4588 * correctly. Check for this and holler if we see it happening.
4589 * If that compiler bug is ever fixed we can remove this.
4591 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4594 * Dispatch on symbol type
4596 switch (S_GET_RAW_TYPE (sp
)) {
4602 * Make a GSD global symbol reference
4605 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4607 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4608 as_warn("g++ wrote an extern reference to %s as a routine.",
4610 as_warn("I will fix it, but I hope that it was not really a routine");
4617 #endif /* gxx_bug_fixed */
4619 * Now scan the symbols and emit the appropriate GSD records
4621 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4624 * Dispatch on symbol type
4626 switch (S_GET_RAW_TYPE (sp
))
4629 * Global uninitialized data
4631 case N_UNDF
| N_EXT
:
4633 * Make a VMS data symbol entry
4635 vsp
= (struct VMS_Symbol
*)
4636 xmalloc (sizeof (*vsp
));
4638 vsp
->Size
= S_GET_VALUE (sp
);
4639 vsp
->Psect_Index
= Psect_Number
++;
4640 vsp
->Psect_Offset
= 0;
4641 vsp
->Next
= VMS_Symbols
;
4643 sp
->sy_number
= (int) vsp
;
4645 * Make the psect for this data
4647 if (S_GET_OTHER (sp
))
4648 Globalref
= VMS_Psect_Spec (
4654 Globalref
= VMS_Psect_Spec (
4661 #ifdef NOT_VAX_11_C_COMPATIBLE
4663 * Place a global symbol at the
4664 * beginning of the Psect
4666 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4670 #endif /* NOT_VAX_11_C_COMPATIBLE */
4673 * Local uninitialized data
4677 * Make a VMS data symbol entry
4679 vsp
= (struct VMS_Symbol
*)
4680 xmalloc (sizeof (*vsp
));
4683 vsp
->Psect_Index
= Bss_Psect
;
4686 bss_address_frag
.fr_address
;
4687 vsp
->Next
= VMS_Symbols
;
4689 sp
->sy_number
= (int) vsp
;
4692 * Global initialized data
4694 case N_DATA
| N_EXT
:
4696 * Make a VMS data symbol entry
4698 vsp
= (struct VMS_Symbol
*)
4699 xmalloc (sizeof (*vsp
));
4701 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4702 text_siz
+ data_siz
);
4703 vsp
->Psect_Index
= Psect_Number
++;
4704 vsp
->Psect_Offset
= 0;
4705 vsp
->Next
= VMS_Symbols
;
4707 sp
->sy_number
= (int) vsp
;
4711 if (S_GET_OTHER (sp
))
4712 Globalref
= VMS_Psect_Spec (
4718 Globalref
= VMS_Psect_Spec (
4725 #ifdef NOT_VAX_11_C_COMPATIBLE
4727 * Place a global symbol at the
4728 * beginning of the Psect
4730 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4734 #endif /* NOT_VAX_11_C_COMPATIBLE */
4737 * Local initialized data
4741 * Make a VMS data symbol entry
4743 vsp
= (struct VMS_Symbol
*)
4744 xmalloc (sizeof (*vsp
));
4747 VMS_Initialized_Data_Size (sp
,
4748 text_siz
+ data_siz
);
4749 vsp
->Psect_Index
= Data_Psect
;
4751 Local_Initialized_Data_Size
;
4752 Local_Initialized_Data_Size
+= vsp
->Size
;
4753 vsp
->Next
= VMS_Symbols
;
4755 sp
->sy_number
= (int) vsp
;
4758 * Global Text definition
4760 case N_TEXT
| N_EXT
:
4762 unsigned short Entry_Mask
;
4765 * Get the entry mask
4767 fragP
= sp
->sy_frag
;
4768 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4769 ((fragP
->fr_literal
[1] & 0xff)
4772 * Define the Procedure entry pt.
4774 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4781 * Local Text definition
4785 * Make a VMS data symbol entry
4787 if (Text_Psect
!= -1)
4789 vsp
= (struct VMS_Symbol
*)
4790 xmalloc (sizeof (*vsp
));
4793 vsp
->Psect_Index
= Text_Psect
;
4794 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4795 vsp
->Next
= VMS_Symbols
;
4797 sp
->sy_number
= (int) vsp
;
4805 * Make a GSD global symbol reference
4808 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4818 * Ignore STAB symbols
4819 * Including .stabs emitted by g++
4821 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4826 if (S_GET_TYPE (sp
) != 22)
4827 printf (" ERROR, unknown type (%d)\n",
4833 * Define the Data Psect
4835 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4840 Data_Psect
= Psect_Number
++;
4841 VMS_Psect_Spec ("$data",
4842 Local_Initialized_Data_Size
,
4845 * Scan the VMS symbols and fill in the data psect
4847 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4850 * Only look for undefined psects
4852 if (vsp
->Psect_Index
< 0)
4855 * And only initialized data
4857 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4858 vsp
->Psect_Index
= Data_Psect
;
4863 /******* Text Information and Relocation Records *******/
4865 * Write the text segment data
4870 * Scan the text fragments
4872 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4875 * Stop if we get to the data fragments
4877 if (fragP
== data_frag_root
)
4880 * Ignore fragments with no data
4882 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4885 * Go the the appropriate offset in the
4888 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4890 * Store the "fixed" part
4893 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4897 * Store the "variable" part
4899 if (fragP
->fr_var
&& fragP
->fr_offset
)
4900 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4907 * Now we go through the text segment fixups and
4908 * generate TIR records to fix up addresses within
4911 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4914 * We DO handle the case of "Symbol - Symbol" as
4915 * long as it is in the same segment.
4917 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4922 * They need to be in the same segment
4924 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4925 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4926 error ("Fixup data addsy and subsy didn't have the same type");
4928 * And they need to be in one that we
4929 * can check the psect on
4931 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4932 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4933 error ("Fixup data addsy and subsy didn't have an appropriate type");
4935 * This had better not be PC relative!
4938 error ("Fixup data was erroneously \"pcrel\"");
4940 * Subtract their values to get the
4943 i
= S_GET_VALUE (fixP
->fx_addsy
) -
4944 S_GET_VALUE (fixP
->fx_subsy
);
4946 * Now generate the fixup object records
4947 * Set the psect and store the data
4949 VMS_Set_Psect (Text_Psect
,
4951 fixP
->fx_frag
->fr_address
,
4953 VMS_Store_Immediate_Data (&i
,
4962 * Size will HAVE to be "long"
4964 if (fixP
->fx_size
!= sizeof (long))
4965 error ("Fixup datum was not a longword");
4967 * Symbol must be "added" (if it is ever
4969 * fix this assumption)
4971 if (fixP
->fx_addsy
== 0)
4972 error ("Fixup datum was not \"fixP->fx_addsy\"");
4974 * Store the symbol value in a PIC fashion
4976 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4981 fixP
->fx_frag
->fr_address
,
4984 * Check for indirect address reference,
4985 * which has to be fixed up (as the linker
4986 * will screw it up with TIR_S_C_STO_PICR).
4989 VMS_Fix_Indirect_Reference (Text_Psect
,
4991 fixP
->fx_frag
->fr_address
,
4997 * Store the Data segment:
4999 * Since this is REALLY hard to do any other way,
5000 * we actually manufacture the data segment and
5001 * the store the appropriate values out of it.
5002 * The segment was manufactured before, now we just
5003 * dump it into the appropriate psects.
5009 * Now we can run through all the data symbols
5010 * and store the data
5012 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5015 * Ignore anything other than data symbols
5017 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5020 * Set the Psect + Offset
5022 VMS_Set_Psect (vsp
->Psect_Index
,
5028 VMS_Store_Immediate_Data (Data_Segment
+
5029 S_GET_VALUE (vsp
->Symbol
) -
5035 * Now we go through the data segment fixups and
5036 * generate TIR records to fix up addresses within
5039 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5042 * Find the symbol for the containing datum
5044 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5047 * Only bother with Data symbols
5050 if (S_GET_TYPE (sp
) != N_DATA
)
5053 * Ignore symbol if After fixup
5055 if (S_GET_VALUE (sp
) >
5057 fixP
->fx_frag
->fr_address
))
5060 * See if the datum is here
5062 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5064 fixP
->fx_frag
->fr_address
))
5067 * We DO handle the case of "Symbol - Symbol" as
5068 * long as it is in the same segment.
5070 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5075 * They need to be in the same segment
5077 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5078 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5079 error ("Fixup data addsy and subsy didn't have the same type");
5081 * And they need to be in one that we
5082 * can check the psect on
5084 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5085 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5086 error ("Fixup data addsy and subsy didn't have an appropriate type");
5088 * This had better not be PC relative!
5091 error ("Fixup data was erroneously \"pcrel\"");
5093 * Subtract their values to get the
5096 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5097 S_GET_VALUE (fixP
->fx_subsy
);
5099 * Now generate the fixup object records
5100 * Set the psect and store the data
5102 VMS_Set_Psect (vsp
->Psect_Index
,
5103 fixP
->fx_frag
->fr_address
+
5105 S_GET_VALUE (vsp
->Symbol
) +
5108 VMS_Store_Immediate_Data (&i
,
5117 * Size will HAVE to be "long"
5119 if (fixP
->fx_size
!= sizeof (long))
5120 error ("Fixup datum was not a longword");
5122 * Symbol must be "added" (if it is ever
5124 * fix this assumption)
5126 if (fixP
->fx_addsy
== 0)
5127 error ("Fixup datum was not \"fixP->fx_addsy\"");
5129 * Store the symbol value in a PIC fashion
5131 VMS_Store_PIC_Symbol_Reference (
5136 fixP
->fx_frag
->fr_address
+
5138 S_GET_VALUE (vsp
->Symbol
) +
5151 * Write the Traceback Begin Module record
5153 VMS_TBT_Module_Begin ();
5155 * Scan the symbols and write out the routines
5156 * (this makes the assumption that symbols are in
5157 * order of ascending text segment offset)
5160 struct symbol
*Current_Routine
= 0;
5161 int Current_Line_Number
= 0;
5162 int Current_Offset
= -1;
5163 struct input_file
*Current_File
;
5165 /* Output debugging info for global variables and static variables that are not
5166 * specific to one routine. We also need to examine all stabs directives, to
5167 * find the definitions to all of the advanced data types, and this is done by
5168 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5169 * the object file, since there can be forward references in the stabs
5170 * directives. When through with parsing, the text of the stabs directive
5171 * is altered, with the definitions removed, so that later passes will see
5172 * directives as they would be written if the type were already defined.
5174 * We also look for files and include files, and make a list of them. We
5175 * examine the source file numbers to establish the actual lines that code was
5176 * generated from, and then generate offsets.
5179 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5182 * Deal with STAB symbols
5184 if (S_IS_DEBUG (symbolP
))
5187 * Dispatch on STAB type
5189 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5192 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5193 Current_File
->max_line
= S_GET_DESC (symbolP
);
5194 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5195 Current_File
->min_line
= S_GET_DESC (symbolP
);
5198 Current_File
= find_file (symbolP
);
5199 Current_File
->flag
= 1;
5200 Current_File
->min_line
= 1;
5203 Current_File
= find_file (symbolP
);
5206 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5209 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5211 case N_FUN
: /* For static constant symbols */
5213 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5219 /* now we take a quick sweep through the files and assign offsets
5220 to each one. This will essentially be the starting line number to the
5221 debugger for each file. Output the info for the debugger to specify the
5222 files, and then tell it how many lines to use */
5224 int File_Number
= 0;
5225 int Debugger_Offset
= 0;
5227 Current_File
= file_root
;
5228 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5230 if (Current_File
== (struct input_file
*) NULL
)
5232 if (Current_File
->max_line
== 0)
5234 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5237 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5240 /* show a few extra lines at the start of the region selected */
5241 if (Current_File
->min_line
> 2)
5242 Current_File
->min_line
-= 2;
5243 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5244 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5245 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5246 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5249 Current_File
->file_number
= ++File_Number
;
5250 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5251 Current_File
->file_number
);
5252 if (!file_available
)
5254 Current_File
->file_number
= 0;
5259 VMS_TBT_Source_Lines (Current_File
->file_number
,
5260 Current_File
->min_line
,
5261 Current_File
->max_line
- Current_File
->min_line
+ 1);
5264 Current_File
= (struct input_file
*) NULL
;
5266 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5269 * Deal with text symbols
5271 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5274 * Ignore symbols starting with "L",
5275 * as they are local symbols
5277 if (*S_GET_NAME (symbolP
) == 'L')
5280 * If there is a routine start defined,
5283 if (Current_Routine
)
5288 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5291 * Store the routine begin traceback info
5293 if (Text_Psect
!= -1)
5295 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5296 Current_Routine
= symbolP
;
5298 /* Output local symbols, i.e. all symbols that are associated with a specific
5299 * routine. We output them now so the debugger recognizes them as local to
5306 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5308 if (!S_IS_DEBUG (symbolP1
))
5310 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5312 pnt
= S_GET_NAME (symbolP
);
5313 pnt1
= S_GET_NAME (symbolP1
);
5316 while (*pnt
++ == *pnt1
++)
5319 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5320 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5323 if (symbolP1
!= (symbolS
*) NULL
)
5324 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5325 } /* local symbol block */
5332 * Deal with STAB symbols
5334 if (S_IS_DEBUG (symbolP
))
5337 * Dispatch on STAB type
5339 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5345 /* Offset the line into the correct portion
5347 if (Current_File
->file_number
== 0)
5349 /* Sometimes the same offset gets several source
5350 * lines assigned to it.
5351 * We should be selective about which lines
5352 * we allow, we should prefer lines that are
5353 * in the main source file when debugging
5354 * inline functions. */
5355 if ((Current_File
->file_number
!= 1) &&
5356 S_GET_VALUE (symbolP
) ==
5359 /* calculate actual debugger source line */
5360 S_GET_DESC (symbolP
)
5361 += Current_File
->offset
;
5363 * If this is the 1st N_SLINE, setup
5364 * PC/Line correlation. Otherwise
5365 * do the delta PC/Line. If the offset
5366 * for the line number is not +ve we need
5367 * to do another PC/Line correlation
5370 if (Current_Offset
== -1)
5372 VMS_TBT_Line_PC_Correlation (
5373 S_GET_DESC (symbolP
),
5374 S_GET_VALUE (symbolP
),
5380 if ((S_GET_DESC (symbolP
) -
5381 Current_Line_Number
) <= 0)
5384 * Line delta is not +ve, we
5385 * need to close the line and
5386 * start a new PC/Line
5389 VMS_TBT_Line_PC_Correlation (0,
5390 S_GET_VALUE (symbolP
) -
5394 VMS_TBT_Line_PC_Correlation (
5395 S_GET_DESC (symbolP
),
5396 S_GET_VALUE (symbolP
),
5403 * Line delta is +ve, all is well
5405 VMS_TBT_Line_PC_Correlation (
5406 S_GET_DESC (symbolP
) -
5407 Current_Line_Number
,
5408 S_GET_VALUE (symbolP
) -
5415 * Update the current line/PC
5417 Current_Line_Number
= S_GET_DESC (symbolP
);
5418 Current_Offset
= S_GET_VALUE (symbolP
);
5428 * Remember that we had a source file
5429 * and emit the source file debugger
5433 find_file (symbolP
);
5435 /* We need to make sure that we are really in the actual source file when
5436 * we compute the maximum line number. Otherwise the debugger gets really
5440 find_file (symbolP
);
5446 * If there is a routine start defined,
5447 * terminate it (and the line numbers)
5449 if (Current_Routine
)
5452 * Terminate the line numbers
5454 VMS_TBT_Line_PC_Correlation (0,
5455 text_siz
- S_GET_VALUE (Current_Routine
),
5459 * Terminate the routine
5461 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5465 * Write the Traceback End Module TBT record
5467 VMS_TBT_Module_End ();
5470 * Write the End Of Module record
5472 if (Entry_Point_Symbol
== 0)
5473 Write_VMS_EOM_Record (-1, 0);
5475 Write_VMS_EOM_Record (Text_Psect
,
5476 S_GET_VALUE (Entry_Point_Symbol
));
5479 * All done, close the object file
5481 Close_VMS_Object_File ();
5484 /* end of obj-vms.c */