1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
28 /* What we do if there is a goof. */
29 #define error as_fatal
31 #ifdef HO_VMS /* These are of no use if we are cross assembling. */
32 #include <fab.h> /* Define File Access Block */
33 #include <nam.h> /* Define NAM Block */
34 #include <xab.h> /* Define XAB - all different types*/
37 * Version string of the compiler that produced the code we are
38 * assembling. (And this assembler, if we do not have compiler info.)
40 char *compiler_version_string
;
42 /* Flag that determines how we map names. This takes several values, and
43 * is set with the -h switch. A value of zero implies names should be
44 * upper case, and the presence of the -h switch inhibits the case hack.
45 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
46 * A value of 2 (set with -h2) implies names should be
47 * all lower case, with no case hack. A value of 3 (set with -h3) implies
48 * that case should be preserved. */
50 /* If the -+ switch is given, then the hash is appended to any name that is
51 * longer than 31 characters, irregardless of the setting of the -h switch.
54 char vms_name_mapping
= 0;
57 extern char *strchr ();
59 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
62 * We augment the "gas" symbol structure with this
66 struct VMS_Symbol
*Next
;
67 struct symbol
*Symbol
;
72 struct VMS_Symbol
*VMS_Symbols
= 0;
74 /* We need this to keep track of the various input files, so that we can
75 * give the debugger the correct source line.
80 struct input_file
*next
;
81 struct input_file
*same_file_fpnt
;
91 static struct input_file
*file_root
= (struct input_file
*) NULL
;
94 static struct input_file
*find_file
PARAMS ((symbolS
*));
97 * This enum is used to keep track of the various types of variables that
103 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, 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 indicate that we are making the last attempt to
171 parse the stabs, and that we should define as much as we can, and ignore
174 static int final_pass
;
176 /* This variable is used to keep track of the current structure number
177 * for a given variable. If this is < 0, that means that the structure
178 * has not yet been defined to the debugger. This is still cool, since
179 * the VMS object language has ways of fixing things up after the fact,
180 * so we just make a note of this, and generate fixups at the end.
182 static int struct_number
;
186 * Variable descriptors are used tell the debugger the data types of certain
187 * more complicated variables (basically anything involving a structure,
188 * union, enum, array or pointer). Some non-pointer variables of the
189 * basic types that the debugger knows about do not require a variable
192 * Since it is impossible to have a variable descriptor longer than 128
193 * bytes by virtue of the way that the VMS object language is set up,
194 * it makes not sense to make the arrays any longer than this, or worrying
195 * about dynamic sizing of the array.
197 * These are the arrays and counters that we use to build a variable
201 #define MAX_DEBUG_RECORD 128
202 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
203 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
204 static int Lpnt
; /* index into Local */
205 static int Apoint
; /* index into Asuffix */
206 static char overflow
; /* flag to indicate we have written too much*/
207 static int total_len
; /* used to calculate the total length of variable
208 descriptor plus array descriptor - used for len byte*/
210 /* Flag if we have told user about finding global constants in the text
212 static gave_compiler_message
= 0;
214 /* A pointer to the current routine that we are working on. */
216 static symbolS
*Current_Routine
;
218 /* The psect number for $code a.k.a. the text section. */
220 static int Text_Psect
;
224 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
226 static int VMS_Object_File_FD
; /* File Descriptor for object file */
227 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
228 static int Object_Record_Offset
;/* Offset to end of data */
229 static int Current_Object_Record_Type
; /* Type of record in above */
232 * Macros for moving data around. Must work on big-endian systems.
234 #ifdef HO_VMS /* These are more efficient for VMS->VMS systems */
235 #define COPY_LONG(dest,val) {*(long *) dest = val; }
236 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
238 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
239 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
242 * Macros for placing data into the object record buffer
245 #define PUT_LONG(val) \
246 { md_number_to_chars(Object_Record_Buffer + \
247 Object_Record_Offset, val, 4); \
248 Object_Record_Offset += 4; }
250 #define PUT_SHORT(val) \
251 { md_number_to_chars(Object_Record_Buffer + \
252 Object_Record_Offset, val, 2); \
253 Object_Record_Offset += 2; }
255 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
257 #define PUT_COUNTED_STRING(cp) {\
258 register char *p = cp; \
259 PUT_CHAR(strlen(p)); \
260 while (*p) PUT_CHAR(*p++);}
263 * Macro for determining if a Name has psect attributes attached
266 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
267 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
269 #define HAS_PSECT_ATTRIBUTES(Name) \
270 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
271 PSECT_ATTRIBUTES_STRING, \
272 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
275 /* in: segT out: N_TYPE bits */
276 const short seg_N_TYPE
[] =
282 N_UNDF
, /* unknown */
286 N_UNDF
, /* bignum/flonum */
287 N_UNDF
, /* difference */
291 N_REGISTER
, /* register */
294 const segT N_TYPE_seg
[N_TYPE
+ 2] =
295 { /* N_TYPE == 0x1E = 32-2 */
296 SEG_UNKNOWN
, /* N_UNDF == 0 */
298 SEG_ABSOLUTE
, /* N_ABS == 2 */
300 SEG_TEXT
, /* N_TEXT == 4 */
302 SEG_DATA
, /* N_DATA == 6 */
304 SEG_BSS
, /* N_BSS == 8 */
306 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
307 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
308 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
309 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
314 /* The following code defines the special types of pseudo-ops that we
325 temp
= get_absolute_expression ();
326 subseg_new (SEG_DATA
, (subsegT
) temp
);
328 demand_empty_rest_of_line ();
334 * Handle .stabX directives, which used to be open-coded.
335 * So much creeping featurism overloaded the semantics that we decided
336 * to put all .stabX thinking in one place. Here.
338 * We try to make any .stabX directive legal. Other people's AS will often
339 * do assembly-time consistency checks: eg assigning meaning to n_type bits
340 * and "protecting" you from setting them to certain values. (They also zero
341 * certain bits before emitting symbols. Tut tut.)
343 * If an expression is not absolute we either gripe or use the relocation
344 * information. Other people's assemblers silently forget information they
345 * don't need and invent information they need that you didn't supply.
347 * .stabX directives always make a symbol table entry. It may be junk if
348 * the rest of your .stabX directive is malformed.
356 #endif /* NO_LISTING */
358 register symbolS
*symbolP
= 0;
359 register char *string
;
362 int goof
; /* TRUE if we have aborted. */
366 * Enter with input_line_pointer pointing past .stabX and any following
369 goof
= 0; /* JF who forgot this?? */
372 string
= demand_copy_C_string (&length
);
374 if (*input_line_pointer
== ',')
375 input_line_pointer
++;
378 as_bad ("I need a comma after symbol's name");
386 * Input_line_pointer->after ','. String->symbol name.
390 symbolP
= symbol_new (string
,
397 S_SET_NAME (symbolP
, NULL
); /* .stabd feature. */
398 S_SET_VALUE (symbolP
, obstack_next_free (&frags
) - frag_now
->fr_literal
);
399 symbolP
->sy_frag
= frag_now
;
403 symbolP
->sy_frag
= &zero_address_frag
;
407 symbolP
->sy_frag
= &zero_address_frag
;
415 if (get_absolute_expression_and_terminator (&longint
) == ',')
416 symbolP
->sy_symbol
.n_type
= saved_type
= longint
;
419 as_bad ("I want a comma after the n_type expression");
421 input_line_pointer
--; /* Backup over a non-',' char. */
427 if (get_absolute_expression_and_terminator (&longint
) == ',')
428 S_SET_OTHER (symbolP
, longint
);
431 as_bad ("I want a comma after the n_other expression");
433 input_line_pointer
--; /* Backup over a non-',' char. */
439 S_SET_DESC (symbolP
, get_absolute_expression ());
440 if (what
== 's' || what
== 'n')
442 if (*input_line_pointer
!= ',')
444 as_bad ("I want a comma after the n_desc expression");
449 input_line_pointer
++;
454 if ((!goof
) && (what
== 's' || what
== 'n'))
456 pseudo_set (symbolP
);
457 symbolP
->sy_symbol
.n_type
= saved_type
;
461 if (listing
&& !goof
)
463 if (symbolP
->sy_symbol
.n_type
== N_SLINE
)
466 listing_source_line(symbolP
->sy_symbol
.n_desc
);
468 else if (symbolP
->sy_symbol
.n_type
== N_SO
469 || symbolP
->sy_symbol
.n_type
== N_SOL
)
471 listing_source_file(string
);
477 ignore_rest_of_line ();
479 demand_empty_rest_of_line ();
480 } /* obj_aout_stab() */
482 const pseudo_typeS obj_pseudo_table
[] =
484 {"stabd", obj_aout_stab
, 'd'},/* stabs */
485 {"stabn", obj_aout_stab
, 'n'},/* stabs */
486 {"stabs", obj_aout_stab
, 's'},/* stabs */
487 {"const", s_const
, 0},
490 }; /* obj_pseudo_table */
493 vms_resolve_symbol_redef (sym
)
497 * If the new symbol is .comm AND it has a size of zero,
498 * we ignore it (i.e. the old symbol overrides it)
500 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)) &&
501 ((obstack_next_free (&frags
) - frag_now
->fr_literal
) == 0))
503 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
508 * If the old symbol is .comm and it has a size of zero,
509 * we override it with the new symbol value.
511 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
512 && (S_GET_VALUE(sym
) == 0))
514 as_warn ("compiler redefined zero-size common symbol `%s'",
516 sym
->sy_frag
= frag_now
;
517 S_GET_OTHER(sym
) = const_flag
;
518 S_SET_VALUE(sym
, obstack_next_free(& frags
) - frag_now
->fr_literal
);
519 /* Keep N_EXT bit. */
520 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
529 obj_read_begin_hook ()
532 } /* obj_read_begin_hook() */
535 obj_crawl_symbol_chain (headers
)
536 object_headers
*headers
;
540 int symbol_number
= 0;
542 /* JF deal with forward references first... */
543 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
545 if (symbolP
->sy_forward
)
547 S_SET_VALUE (symbolP
, S_GET_VALUE (symbolP
)
548 + S_GET_VALUE (symbolP
->sy_forward
)
549 + symbolP
->sy_forward
->sy_frag
->fr_address
);
550 symbolP
->sy_forward
= 0;
551 } /* if it has a forward reference */
552 } /* walk the symbol chain */
554 { /* crawl symbol table */
555 register int symbol_number
= 0;
558 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
559 while ((symbolP
= *symbolPP
) != NULL
)
561 S_GET_VALUE (symbolP
) += symbolP
->sy_frag
->fr_address
;
563 /* OK, here is how we decide which symbols go out into the
564 brave new symtab. Symbols that do are:
566 * symbols with no name (stabd's?)
567 * symbols with debug info in their N_TYPE
569 Symbols that don't are:
570 * symbols that are registers
571 * symbols with \1 as their 3rd character (numeric labels)
572 * "local labels" as defined by S_LOCAL_NAME(name)
573 if the -L switch was passed to gas.
575 All other symbols are output. We complain if a deleted
576 symbol was marked external. */
579 if (!S_IS_REGISTER (symbolP
))
581 symbolP
->sy_name_offset
= 0;
582 symbolPP
= &(symbol_next (symbolP
));
586 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
588 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
591 } /* if this symbol should be in the output */
592 } /* for each symbol */
594 H_SET_STRING_SIZE (headers
, string_byte_count
);
595 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
596 } /* crawl symbol table */
598 } /* obj_crawl_symbol_chain() */
601 /****** VMS OBJECT FILE HACKING ROUTINES *******/
605 * Create the VMS object file
608 Create_VMS_Object_File ()
610 #if defined(eunice) || !defined(HO_VMS)
611 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
613 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
614 "mbc=16", "deq=64", "fop=tef", "shr=nil");
619 if (VMS_Object_File_FD
< 0)
621 char Error_Line
[256];
623 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
628 * Initialize object file hacking variables
630 Object_Record_Offset
= 0;
631 Current_Object_Record_Type
= -1;
636 * Flush the object record buffer to the object file
639 Flush_VMS_Object_Record_Buffer ()
645 * If the buffer is empty, we are done
647 if (Object_Record_Offset
== 0)
650 * Write the data to the file
652 #ifndef HO_VMS /* For cross-assembly purposes. */
653 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
654 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
655 #endif /* not HO_VMS */
656 i
= write (VMS_Object_File_FD
,
657 Object_Record_Buffer
,
658 Object_Record_Offset
);
659 if (i
!= Object_Record_Offset
)
660 error ("I/O error writing VMS object file");
661 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
663 /* pad it if needed */
665 if (Object_Record_Offset
& 1 != 0)
666 write (VMS_Object_File_FD
, &zero
, 1);
667 #endif /* not HO_VMS */
669 * The buffer is now empty
671 Object_Record_Offset
= 0;
676 * Declare a particular type of object file record
679 Set_VMS_Object_File_Record (Type
)
683 * If the type matches, we are done
685 if (Type
== Current_Object_Record_Type
)
688 * Otherwise: flush the buffer
690 Flush_VMS_Object_Record_Buffer ();
694 Current_Object_Record_Type
= Type
;
700 * Close the VMS Object file
703 Close_VMS_Object_File ()
705 short int m_one
= -1;
706 #ifndef HO_VMS /* For cross-assembly purposes. */
707 /* Write a 0xffff into the file, which means "End of File" */
708 write (VMS_Object_File_FD
, &m_one
, 2);
709 #endif /* not HO_VMS */
710 close (VMS_Object_File_FD
);
715 * Store immediate data in current Psect
718 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
726 * We are writing a "Record_Type" record
728 Set_VMS_Object_File_Record (Record_Type
);
730 * We can only store 128 bytes at a time
735 * Store a maximum of 128 bytes
737 i
= (Size
> 128) ? 128 : Size
;
740 * If we cannot accommodate this record, flush the
743 if ((Object_Record_Offset
+ i
+ 1) >=
744 sizeof (Object_Record_Buffer
))
745 Flush_VMS_Object_Record_Buffer ();
747 * If the buffer is empty we must insert record type
749 if (Object_Record_Offset
== 0)
750 PUT_CHAR (Record_Type
);
754 PUT_CHAR (-i
& 0xff);
759 PUT_CHAR (*Pointer
++);
761 * Flush the buffer if it is more than 75% full
763 if (Object_Record_Offset
>
764 (sizeof (Object_Record_Buffer
) * 3 / 4))
765 Flush_VMS_Object_Record_Buffer ();
770 * Make a data reference
773 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
780 * We are writing a "Record_Type" record
782 Set_VMS_Object_File_Record (Record_Type
);
784 * If the buffer is empty we must insert the record type
786 if (Object_Record_Offset
== 0)
787 PUT_CHAR (Record_Type
);
789 * Stack the Psect base + Longword Offset
793 if (Psect_Index
> 127)
795 PUT_CHAR (TIR_S_C_STA_WPL
);
796 PUT_SHORT (Psect_Index
);
801 PUT_CHAR (TIR_S_C_STA_PL
);
802 PUT_CHAR (Psect_Index
);
810 PUT_CHAR (TIR_S_C_STA_WPL
);
811 PUT_SHORT (Psect_Index
);
814 else if (Offset
> 127)
816 PUT_CHAR (TIR_S_C_STA_WPW
);
817 PUT_SHORT (Psect_Index
);
822 PUT_CHAR (TIR_S_C_STA_WPB
);
823 PUT_SHORT (Psect_Index
);
828 * Set relocation base
830 PUT_CHAR (TIR_S_C_STO_PIDR
);
832 * Flush the buffer if it is more than 75% full
834 if (Object_Record_Offset
>
835 (sizeof (Object_Record_Buffer
) * 3 / 4))
836 Flush_VMS_Object_Record_Buffer ();
840 * Make a debugger reference to a struct, union or enum.
843 VMS_Store_Struct (Struct_Index
)
847 * We are writing a "OBJ_S_C_DBG" record
849 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
851 * If the buffer is empty we must insert the record type
853 if (Object_Record_Offset
== 0)
854 PUT_CHAR (OBJ_S_C_DBG
);
855 PUT_CHAR (TIR_S_C_STA_UW
);
856 PUT_SHORT (Struct_Index
);
857 PUT_CHAR (TIR_S_C_CTL_STKDL
);
858 PUT_CHAR (TIR_S_C_STO_L
);
860 * Flush the buffer if it is more than 75% full
862 if (Object_Record_Offset
>
863 (sizeof (Object_Record_Buffer
) * 3 / 4))
864 Flush_VMS_Object_Record_Buffer ();
868 * Make a debugger reference to partially define a struct, union or enum.
871 VMS_Def_Struct (Struct_Index
)
875 * We are writing a "OBJ_S_C_DBG" record
877 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
879 * If the buffer is empty we must insert the record type
881 if (Object_Record_Offset
== 0)
882 PUT_CHAR (OBJ_S_C_DBG
);
883 PUT_CHAR (TIR_S_C_STA_UW
);
884 PUT_SHORT (Struct_Index
);
885 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
887 * Flush the buffer if it is more than 75% full
889 if (Object_Record_Offset
>
890 (sizeof (Object_Record_Buffer
) * 3 / 4))
891 Flush_VMS_Object_Record_Buffer ();
895 VMS_Set_Struct (Struct_Index
)
897 { /* see previous functions for comments */
898 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
899 if (Object_Record_Offset
== 0)
900 PUT_CHAR (OBJ_S_C_DBG
);
901 PUT_CHAR (TIR_S_C_STA_UW
);
902 PUT_SHORT (Struct_Index
);
903 PUT_CHAR (TIR_S_C_CTL_STLOC
);
904 if (Object_Record_Offset
>
905 (sizeof (Object_Record_Buffer
) * 3 / 4))
906 Flush_VMS_Object_Record_Buffer ();
910 * Write the Traceback Module Begin record
913 VMS_TBT_Module_Begin ()
915 register char *cp
, *cp1
;
917 char Module_Name
[256];
921 * Get module name (the FILENAME part of the object file)
927 if ((*cp
== ']') || (*cp
== '>') ||
928 (*cp
== ':') || (*cp
== '/'))
934 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
938 * Limit it to 31 characters
940 while (--cp1
>= Module_Name
)
943 if (strlen (Module_Name
) > 31)
946 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
950 * Arrange to store the data locally (leave room for size byte)
956 *cp
++ = DST_S_C_MODBEG
;
962 * Language type == "C"
964 COPY_LONG (cp
, DST_S_C_C
);
967 * Store the module name
969 *cp
++ = strlen (Module_Name
);
974 * Now we can store the record size
979 * Put it into the object record
981 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
986 * Write the Traceback Module End record
989 VMS_TBT_Module_End ()
997 Local
[1] = DST_S_C_MODEND
;
999 * Put it into the object record
1001 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
1006 * Write the Traceback Routine Begin record
1009 VMS_TBT_Routine_Begin (symbolP
, Psect
)
1010 struct symbol
*symbolP
;
1013 register char *cp
, *cp1
;
1020 * Strip the leading "_" from the name
1022 Name
= S_GET_NAME (symbolP
);
1026 * Get the text psect offset
1028 Offset
= S_GET_VALUE (symbolP
);
1030 * Calculate the record size
1032 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1040 Local
[1] = DST_S_C_RTNBEG
;
1046 * Store the data so far
1048 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1050 * Make sure we are still generating a OBJ_S_C_TBT record
1052 if (Object_Record_Offset
== 0)
1053 PUT_CHAR (OBJ_S_C_TBT
);
1055 * Now get the symbol address
1057 PUT_CHAR (TIR_S_C_STA_WPL
);
1061 * Store the data reference
1063 PUT_CHAR (TIR_S_C_STO_PIDR
);
1065 * Store the counted string as data
1069 Size
= strlen (cp1
) + 1;
1073 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1078 * Write the Traceback Routine End record
1079 * We *must* search the symbol table to find the next routine, since
1080 * the assember has a way of reassembling the symbol table OUT OF ORDER
1081 * Thus the next routine in the symbol list is not necessarily the
1082 * next one in memory. For debugging to work correctly we must know the
1083 * size of the routine.
1086 VMS_TBT_Routine_End (Max_Size
, sp
)
1091 int Size
= 0x7fffffff;
1095 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1097 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1099 if (*S_GET_NAME (symbolP
) == 'L')
1101 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
1102 (S_GET_VALUE (symbolP
) < Size
))
1103 Size
= S_GET_VALUE (symbolP
);
1104 /* check if gcc_compiled. has size of zero */
1105 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
1107 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1108 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1109 Size
= S_GET_VALUE (symbolP
);
1113 if (Size
== 0x7fffffff)
1115 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
1123 Local
[1] = DST_S_C_RTNEND
;
1131 COPY_LONG (&Local
[3], Size
);
1135 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1139 * Write the Traceback Block End record
1142 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1143 struct symbol
*symbolP
;
1147 register char *cp
, *cp1
;
1154 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1160 * Begin Block - We simulate with a phony routine
1162 Local
[1] = DST_S_C_BLKBEG
;
1168 * Store the data so far
1170 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1172 * Make sure we are still generating a OBJ_S_C_DBG record
1174 if (Object_Record_Offset
== 0)
1175 PUT_CHAR (OBJ_S_C_DBG
);
1177 * Now get the symbol address
1179 PUT_CHAR (TIR_S_C_STA_WPL
);
1182 * Get the text psect offset
1184 Offset
= S_GET_VALUE (symbolP
);
1187 * Store the data reference
1189 PUT_CHAR (TIR_S_C_STO_PIDR
);
1191 * Store the counted string as data
1195 Size
= strlen (cp1
) + 1;
1199 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1204 * Write the Traceback Block End record
1207 VMS_TBT_Block_End (Size
)
1213 * End block - simulate with a phony end routine
1216 Local
[1] = DST_S_C_BLKEND
;
1217 COPY_LONG (&Local
[3], Size
);
1222 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1228 * Write a Line number / PC correlation record
1231 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1241 * If not delta, set our PC/Line number correlation
1248 Local
[0] = 1 + 1 + 2 + 1 + 4;
1250 * Line Number/PC correlation
1252 Local
[1] = DST_S_C_LINE_NUM
;
1256 Local
[2] = DST_S_C_SET_LINE_NUM
;
1257 COPY_SHORT (&Local
[3], Line_Number
- 1);
1261 Local
[5] = DST_S_C_SET_ABS_PC
;
1262 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1264 * Make sure we are still generating a OBJ_S_C_TBT record
1266 if (Object_Record_Offset
== 0)
1267 PUT_CHAR (OBJ_S_C_TBT
);
1270 PUT_CHAR (TIR_S_C_STA_PL
);
1275 PUT_CHAR (TIR_S_C_STA_WPL
);
1279 PUT_CHAR (TIR_S_C_STO_PIDR
);
1281 * Do a PC offset of 0 to register the line number
1284 Local
[1] = DST_S_C_LINE_NUM
;
1285 Local
[2] = 0; /* Increment PC by 0 and register line # */
1286 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1291 * If Delta is negative, terminate the line numbers
1295 Local
[0] = 1 + 1 + 4;
1296 Local
[1] = DST_S_C_LINE_NUM
;
1297 Local
[2] = DST_S_C_TERM_L
;
1298 COPY_LONG (&Local
[3], Offset
);
1299 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1306 * Do a PC/Line delta
1309 *cp
++ = DST_S_C_LINE_NUM
;
1310 if (Line_Number
> 1)
1313 * We need to increment the line number
1315 if (Line_Number
- 1 <= 255)
1317 *cp
++ = DST_S_C_INCR_LINUM
;
1318 *cp
++ = Line_Number
- 1;
1322 *cp
++ = DST_S_C_INCR_LINUM_W
;
1323 COPY_SHORT (cp
, Line_Number
- 1);
1324 cp
+= sizeof (short);
1336 if (Offset
< 0x10000)
1338 *cp
++ = DST_S_C_DELTA_PC_W
;
1339 COPY_SHORT (cp
, Offset
);
1340 cp
+= sizeof (short);
1344 *cp
++ = DST_S_C_DELTA_PC_L
;
1345 COPY_LONG (cp
, Offset
);
1346 cp
+= sizeof (long);
1349 Local
[0] = cp
- (Local
+ 1);
1350 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1356 * Describe a source file to the debugger
1359 VMS_TBT_Source_File (Filename
, ID_Number
)
1363 register char *cp
, *cp1
;
1366 #ifndef HO_VMS /* Used for cross-assembly */
1367 i
= strlen (Filename
);
1369 static struct FAB Fab
;
1370 static struct NAM Nam
;
1371 static struct XABDAT Date_Xab
;
1372 static struct XABFHC File_Header_Xab
;
1373 char Es_String
[255], Rs_String
[255];
1378 Fab
.fab$b_bid
= FAB$C_BID
;
1379 Fab
.fab$b_bln
= sizeof (Fab
);
1380 Fab
.fab$l_nam
= (&Nam
);
1381 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1383 * Setup the Nam block so we can find out the FULL name
1384 * of the source file.
1386 Nam
.nam$b_bid
= NAM$C_BID
;
1387 Nam
.nam$b_bln
= sizeof (Nam
);
1388 Nam
.nam$l_rsa
= Rs_String
;
1389 Nam
.nam$b_rss
= sizeof (Rs_String
);
1390 Nam
.nam$l_esa
= Es_String
;
1391 Nam
.nam$b_ess
= sizeof (Es_String
);
1393 * Setup the Date and File Header Xabs
1395 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1396 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1397 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1398 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1399 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1401 * Get the file information
1403 Fab
.fab$l_fna
= Filename
;
1404 Fab
.fab$b_fns
= strlen (Filename
);
1405 Status
= sys$
open (&Fab
);
1408 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1414 * Calculate the size of the resultant string
1421 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1423 * Source declaration
1425 Local
[1] = DST_S_C_SOURCE
;
1427 * Make formfeeds count as source records
1429 Local
[2] = DST_S_C_SRC_FORMFEED
;
1431 * Declare source file
1433 Local
[3] = DST_S_C_SRC_DECLFILE
;
1434 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1443 COPY_SHORT (cp
, ID_Number
);
1444 cp
+= sizeof (short);
1447 * Creation Date. Unknown, so we fill with zeroes.
1450 cp
+= sizeof (long);
1452 cp
+= sizeof (long);
1457 cp
+= sizeof (long);
1462 cp
+= sizeof (short);
1472 #else /* Use this code when assembling for VMS on a VMS system */
1476 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1477 cp
+= sizeof (long);
1478 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1479 cp
+= sizeof (long);
1483 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1484 cp
+= sizeof (long);
1488 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1489 cp
+= sizeof (short);
1493 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1503 * Library module name (none)
1509 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1515 * Give the number of source lines to the debugger
1518 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1520 int Starting_Line_Number
;
1521 int Number_Of_Lines
;
1529 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1531 * Source declaration
1533 Local
[1] = DST_S_C_SOURCE
;
1538 *cp
++ = DST_S_C_SRC_SETFILE
;
1542 COPY_SHORT (cp
, ID_Number
);
1543 cp
+= sizeof (short);
1547 *cp
++ = DST_S_C_SRC_SETREC_L
;
1548 COPY_LONG (cp
, Starting_Line_Number
);
1549 cp
+= sizeof (long);
1553 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1554 COPY_SHORT (cp
, Number_Of_Lines
);
1555 cp
+= sizeof (short);
1559 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1565 /* This routine locates a file in the list of files. If an entry does not
1566 * exist, one is created. For include files, a new entry is always created
1567 * such that inline functions can be properly debugged. */
1568 static struct input_file
*
1572 struct input_file
*same_file
;
1573 struct input_file
*fpnt
;
1574 same_file
= (struct input_file
*) NULL
;
1575 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1577 if (fpnt
== (struct input_file
*) NULL
)
1579 if (fpnt
->spnt
== sp
)
1582 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1584 if (fpnt
== (struct input_file
*) NULL
)
1586 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1588 if (fpnt
->flag
== 1)
1594 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1595 if (file_root
== (struct input_file
*) NULL
)
1599 struct input_file
*fpnt1
;
1600 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1603 fpnt
->next
= (struct input_file
*) NULL
;
1604 fpnt
->name
= S_GET_NAME (sp
);
1605 fpnt
->min_line
= 0x7fffffff;
1609 fpnt
->file_number
= 0;
1611 fpnt
->same_file_fpnt
= same_file
;
1616 * The following functions and definitions are used to generate object records
1617 * that will describe program variables to the VMS debugger.
1619 * This file contains many of the routines needed to output debugging info into
1620 * the object file that the VMS debugger needs to understand symbols. These
1621 * routines are called very late in the assembly process, and thus we can be
1622 * fairly lax about changing things, since the GSD and the TIR sections have
1623 * already been output.
1627 /* This routine converts a number string into an integer, and stops when it
1628 * sees an invalid character the return value is the address of the character
1629 * just past the last character read. No error is generated.
1632 cvt_integer (str
, rtn
)
1637 neg
= *str
== '-' ? ++str
, -1 : 1;
1638 ival
= 0; /* first get the number of the type for dbx */
1639 while ((*str
<= '9') && (*str
>= '0'))
1640 ival
= 10 * ival
+ *str
++ - '0';
1645 /* this routine fixes the names that are generated by C++, ".this" is a good
1646 * example. The period does not work for the debugger, since it looks like
1647 * the syntax for a structure element, and thus it gets mightily confused
1649 * We also use this to strip the PsectAttribute hack from the name before we
1650 * write a debugger record */
1658 * Kill any leading "_"
1663 * Is there a Psect Attribute to skip??
1665 if (HAS_PSECT_ATTRIBUTES (pnt
))
1670 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1673 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1681 /* Here we fix the .this -> $this conversion */
1682 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1690 /* When defining a structure, this routine is called to find the name of
1691 * the actual structure. It is assumed that str points to the equal sign
1692 * in the definition, and it moves backward until it finds the start of the
1693 * name. If it finds a 0, then it knows that this structure def is in the
1694 * outermost level, and thus symbol_name points to the symbol name.
1697 get_struct_name (str
)
1702 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1707 while ((*pnt
!= ';') && (*pnt
!= '='))
1711 while ((*pnt
< '0') || (*pnt
> '9'))
1713 while ((*pnt
>= '0') && (*pnt
<= '9'))
1718 /* search symbol list for type number dbx_type. Return a pointer to struct */
1719 static struct VMS_DBG_Symbol
*
1720 find_symbol (dbx_type
)
1723 struct VMS_DBG_Symbol
*spnt
;
1724 spnt
= VMS_Symbol_type_list
;
1725 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1727 if (spnt
->dbx_type
== dbx_type
)
1731 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1732 return 0; /*Dunno what this is*/
1733 if(spnt
->advanced
== ALIAS
)
1734 return find_symbol(spnt
->type2
);
1739 /* this routine puts info into either Local or Asuffix, depending on the sign
1740 * of size. The reason is that it is easier to build the variable descriptor
1741 * backwards, while the array descriptor is best built forwards. In the end
1742 * they get put together, if there is not a struct/union/enum along the way
1761 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1765 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1768 Apoint
= MAX_DEBUG_RECORD
- 1;
1771 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1776 /* this routine generates the array descriptor for a given array */
1778 array_suffix (spnt2
)
1779 struct VMS_DBG_Symbol
*spnt2
;
1781 struct VMS_DBG_Symbol
*spnt
;
1782 struct VMS_DBG_Symbol
*spnt1
;
1788 while (spnt
->advanced
!= ARRAY
)
1790 spnt
= find_symbol (spnt
->type2
);
1791 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1797 while (spnt1
->advanced
== ARRAY
)
1800 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1801 spnt1
= find_symbol (spnt1
->type2
);
1803 total_size
= total_size
* spnt1
->data_size
;
1804 push (spnt1
->data_size
, 2);
1805 if (spnt1
->VMS_type
== 0xa3)
1808 push (spnt1
->VMS_type
, 1);
1810 for (i
= 0; i
< 6; i
++)
1814 push (total_size
, 4);
1817 while (spnt1
->advanced
== ARRAY
)
1819 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1820 spnt1
= find_symbol (spnt1
->type2
);
1823 while (spnt1
->advanced
== ARRAY
)
1825 push (spnt1
->index_min
, 4);
1826 push (spnt1
->index_max
, 4);
1827 spnt1
= find_symbol (spnt1
->type2
);
1831 /* this routine generates the start of a variable descriptor based upon
1832 * a struct/union/enum that has yet to be defined. We define this spot as
1833 * a new location, and save four bytes for the address. When the struct is
1834 * finally defined, then we can go back and plug in the correct address
1837 new_forward_ref (dbx_type
)
1840 struct forward_ref
*fpnt
;
1841 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1842 fpnt
->next
= f_ref_root
;
1844 fpnt
->dbx_type
= dbx_type
;
1845 fpnt
->struc_numb
= ++structure_count
;
1846 fpnt
->resolved
= 'N';
1849 push (total_len
, -2);
1850 struct_number
= -fpnt
->struc_numb
;
1853 /* this routine generates the variable descriptor used to describe non-basic
1854 * variables. It calls itself recursively until it gets to the bottom of it
1855 * all, and then builds the descriptor backwards. It is easiest to do it this
1856 *way since we must periodically write length bytes, and it is easiest if we know
1857 *the value when it is time to write it.
1860 gen1 (spnt
, array_suffix_len
)
1861 struct VMS_DBG_Symbol
*spnt
;
1862 int array_suffix_len
;
1864 struct VMS_DBG_Symbol
*spnt1
;
1866 switch (spnt
->advanced
)
1869 push (DBG_S_C_VOID
, -1);
1871 push (total_len
, -2);
1875 if (array_suffix_len
== 0)
1877 push (spnt
->VMS_type
, -1);
1878 push (DBG_S_C_BASIC
, -1);
1880 push (total_len
, -2);
1890 struct_number
= spnt
->struc_numb
;
1891 if (struct_number
< 0)
1893 new_forward_ref (spnt
->dbx_type
);
1896 push (DBG_S_C_STRUCT
, -1);
1898 push (total_len
, -2);
1901 spnt1
= find_symbol (spnt
->type2
);
1903 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1904 new_forward_ref (spnt
->type2
);
1906 i
= gen1 (spnt1
, 0);
1908 { /* (*void) is a special case, do not put pointer suffix*/
1909 push (DBG_S_C_POINTER
, -1);
1911 push (total_len
, -2);
1916 while (spnt1
->advanced
== ARRAY
)
1918 spnt1
= find_symbol (spnt1
->type2
);
1919 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1921 printf ("gcc-as warning(debugger output):");
1922 printf ("Forward reference error, dbx type %d\n",
1927 /* It is too late to generate forward references, so the user gets a message.
1928 * This should only happen on a compiler error */
1929 i
= gen1 (spnt1
, 1);
1931 array_suffix (spnt
);
1932 array_suffix_len
= Apoint
- i
;
1933 switch (spnt1
->advanced
)
1941 push (total_len
, -2);
1944 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1946 total_len
+= array_suffix_len
+ 8;
1947 push (total_len
, -2);
1951 /* This generates a suffix for a variable. If it is not a defined type yet,
1952 * then dbx_type contains the type we are expecting so we can generate a
1953 * forward reference. This calls gen1 to build most of the descriptor, and
1954 * then it puts the icing on at the end. It then dumps whatever is needed
1955 * to get a complete descriptor (i.e. struct reference, array suffix ).
1958 generate_suffix (spnt
, dbx_type
)
1959 struct VMS_DBG_Symbol
*spnt
;
1964 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1965 struct VMS_DBG_Symbol
*spnt1
;
1967 Lpnt
= MAX_DEBUG_RECORD
- 1;
1971 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1972 new_forward_ref (dbx_type
);
1975 if (spnt
->VMS_type
!= 0xa3)
1976 return 0; /* no suffix needed */
1981 push (total_len
, -1);
1982 /* if the variable descriptor overflows the record, output a descriptor for
1983 * a pointer to void.
1985 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1987 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1988 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1992 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1993 Local
[i
++] = Local
[++Lpnt
];
1995 /* we use this for a reference to a structure that has already been defined */
1996 if (struct_number
> 0)
1998 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2000 VMS_Store_Struct (struct_number
);
2002 /* we use this for a forward reference to a structure that has yet to be
2003 *defined. We store four bytes of zero to make room for the actual address once
2006 if (struct_number
< 0)
2008 struct_number
= -struct_number
;
2009 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2011 VMS_Def_Struct (struct_number
);
2012 for (i
= 0; i
< 4; i
++)
2014 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2019 Local
[Lpnt
++] = Asuffix
[i
++];
2021 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2025 /* This routine generates a symbol definition for a C sybmol for the debugger.
2026 * It takes a psect and offset for global symbols - if psect < 0, then this is
2027 * a local variable and the offset is relative to FP. In this case it can
2028 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2031 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2032 struct VMS_DBG_Symbol
*spnt
;
2042 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
2044 { /* this is a local variable, referenced to SP */
2045 maxlen
= 7 + strlen (Name_pnt
);
2046 Local
[i
++] = maxlen
;
2047 Local
[i
++] = spnt
->VMS_type
;
2049 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
2051 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
2052 COPY_LONG (&Local
[i
], Offset
);
2057 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
2058 Local
[i
++] = 7 + strlen (Name_pnt
);
2059 Local
[i
++] = spnt
->VMS_type
;
2061 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2063 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2065 Local
[i
++] = strlen (Name_pnt
);
2066 while (*Name_pnt
!= '\0')
2067 Local
[i
++] = *Name_pnt
++;
2068 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2069 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2070 generate_suffix (spnt
, 0);
2074 /* This routine parses the stabs entries in order to make the definition
2075 * for the debugger of local symbols and function parameters
2078 VMS_local_stab_Parse (sp
)
2084 struct VMS_DBG_Symbol
*spnt
;
2085 struct VMS_Symbol
*vsp
;
2089 str
= S_GET_NAME (sp
);
2090 pnt
= (char *) strchr (str
, ':');
2091 if (pnt
== (char *) NULL
)
2092 return; /* no colon present */
2093 pnt1
= pnt
++; /* save this for later, and skip colon */
2095 return 0; /* ignore static constants */
2096 /* there is one little catch that we must be aware of. Sometimes function
2097 * parameters are optimized into registers, and the compiler, in its infiite
2098 * wisdom outputs stabs records for *both*. In general we want to use the
2099 * register if it is present, so we must search the rest of the symbols for
2100 * this function to see if this parameter is assigned to a register.
2108 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2110 if (!S_IS_DEBUG (sp1
))
2112 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2114 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2115 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2117 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2119 str1
= S_GET_NAME (sp1
); /* and get the name */
2121 while (*pnt2
!= ':')
2128 if ((*str1
!= ':') || (*pnt2
!= ':'))
2130 return; /* they are the same! lets skip this one */
2132 /* first find the dbx symbol type from list, and then find VMS type */
2133 pnt
++; /* skip p in case no register */
2136 pnt
= cvt_integer (pnt
, &dbx_type
);
2137 spnt
= find_symbol (dbx_type
);
2138 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2139 return 0; /*Dunno what this is*/
2141 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2142 *pnt1
= ':'; /* and restore the string */
2146 /* This routine parses a stabs entry to find the information required to define
2147 * a variable. It is used for global and static variables.
2148 * Basically we need to know the address of the symbol. With older versions
2149 * of the compiler, const symbols are
2150 * treated differently, in that if they are global they are written into the
2151 * text psect. The global symbol entry for such a const is actually written
2152 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2153 * of psects, we must search the entry points as well. static consts are even
2154 * harder, since they are never assigned a memory address. The compiler passes
2155 * a stab to tell us the value, but I am not sure what to do with it.
2159 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2162 int type1
, type2
, Text_Psect
;
2168 struct VMS_DBG_Symbol
*spnt
;
2169 struct VMS_Symbol
*vsp
;
2173 str
= S_GET_NAME (sp
);
2174 pnt
= (char *) strchr (str
, ':');
2175 if (pnt
== (char *) NULL
)
2176 return; /* no colon present */
2177 pnt1
= pnt
; /* save this for later*/
2179 if (*pnt
== expected_type
)
2181 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2182 spnt
= find_symbol (dbx_type
);
2183 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2184 return 0; /*Dunno what this is*/
2185 /* now we need to search the symbol table to find the psect and offset for
2190 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2192 pnt
= S_GET_NAME (vsp
->Symbol
);
2193 if (pnt
!= (char *) NULL
)
2195 /* make sure name is the same, and make sure correct symbol type */
2196 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2197 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2198 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2202 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2204 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2205 *pnt1
= ':'; /* and restore the string */
2208 /* the symbol was not in the symbol list, but it may be an "entry point"
2209 if it was a constant */
2210 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2213 * Dispatch on STAB type
2215 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2217 pnt
= S_GET_NAME (sp1
);
2220 if (strcmp (pnt
, str
) == 0)
2222 if (!gave_compiler_message
&& expected_type
== 'G')
2224 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2225 printf ("global constant(s) in the text psect. These will not be available to\n");
2226 printf ("other modules, since this is not the correct way to handle this. You\n");
2227 printf ("have two options: 1) get a patched compiler that does not put global\n");
2228 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2229 printf ("definitions of global variables in your source module(s). Don't say\n");
2230 printf ("I didn't warn you!");
2231 gave_compiler_message
= 1;
2233 VMS_DBG_record (spnt
,
2238 *S_GET_NAME (sp1
) = 'L';
2239 /* fool assembler to not output this
2240 * as a routine in the TBT */
2245 *pnt1
= ':'; /* and restore the string */
2250 VMS_GSYM_Parse (sp
, Text_Psect
)
2253 { /* Global variables */
2254 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2259 VMS_LCSYM_Parse (sp
, Text_Psect
)
2262 { /* Static symbols - uninitialized */
2263 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2267 VMS_STSYM_Parse (sp
, Text_Psect
)
2270 { /* Static symbols - initialized */
2271 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2275 /* for register symbols, we must figure out what range of addresses within the
2276 * psect are valid. We will use the brackets in the stab directives to give us
2277 * guidance as to the PC range that this variable is in scope. I am still not
2278 * completely comfortable with this but as I learn more, I seem to get a better
2279 * handle on what is going on.
2283 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2284 symbolS
*sp
, *Current_Routine
;
2291 struct VMS_DBG_Symbol
*spnt
;
2296 int Min_Offset
= -1; /* min PC of validity */
2297 int Max_Offset
= 0; /* max PC of validity */
2299 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2302 * Dispatch on STAB type
2304 switch (S_GET_RAW_TYPE (symbolP
))
2308 Min_Offset
= S_GET_VALUE (symbolP
);
2313 S_GET_VALUE (symbolP
) - 1;
2316 if ((Min_Offset
!= -1) && (bcnt
== 0))
2318 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2320 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2321 if (*pnt
== 'F' || *pnt
== 'f') break;
2324 /* check to see that the addresses were defined. If not, then there were no
2325 * brackets in the function, and we must try to search for the next function
2326 * Since functions can be in any order, we should search all of the symbol list
2327 * to find the correct ending address. */
2328 if (Min_Offset
== -1)
2330 int Max_Source_Offset
;
2332 Min_Offset
= S_GET_VALUE (sp
);
2333 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2336 * Dispatch on STAB type
2338 This_Offset
= S_GET_VALUE (symbolP
);
2339 switch (S_GET_RAW_TYPE (symbolP
))
2341 case N_TEXT
| N_EXT
:
2342 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2343 Max_Offset
= This_Offset
;
2346 if (This_Offset
> Max_Source_Offset
)
2347 Max_Source_Offset
= This_Offset
;
2350 /* if this is the last routine, then we use the PC of the last source line
2351 * as a marker of the max PC for which this reg is valid */
2352 if (Max_Offset
== 0x7fffffff)
2353 Max_Offset
= Max_Source_Offset
;
2356 str
= S_GET_NAME (sp
);
2357 pnt
= (char *) strchr (str
, ':');
2358 if (pnt
== (char *) NULL
)
2359 return; /* no colon present */
2360 pnt1
= pnt
; /* save this for later*/
2364 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2365 spnt
= find_symbol (dbx_type
);
2366 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2367 return 0; /*Dunno what this is yet*/
2369 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2370 maxlen
= 25 + strlen (pnt
);
2371 Local
[i
++] = maxlen
;
2372 Local
[i
++] = spnt
->VMS_type
;
2374 Local
[i
++] = strlen (pnt
) + 1;
2378 Local
[i
++] = strlen (pnt
);
2379 while (*pnt
!= '\0')
2380 Local
[i
++] = *pnt
++;
2386 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2388 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2389 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2391 Local
[i
++] = S_GET_VALUE (sp
);
2395 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2397 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2398 generate_suffix (spnt
, 0);
2401 /* this function examines a structure definition, checking all of the elements
2402 * to make sure that all of them are fully defined. The only thing that we
2403 * kick out are arrays of undefined structs, since we do not know how big
2404 * they are. All others we can handle with a normal forward reference.
2407 forward_reference (pnt
)
2411 struct VMS_DBG_Symbol
*spnt
;
2412 struct VMS_DBG_Symbol
*spnt1
;
2413 pnt
= cvt_integer (pnt
+ 1, &i
);
2415 return 0; /* no forward references */
2418 pnt
= (char *) strchr (pnt
, ':');
2419 pnt
= cvt_integer (pnt
+ 1, &i
);
2420 spnt
= find_symbol (i
);
2421 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2422 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2425 spnt1
= find_symbol (spnt
->type2
);
2426 if ((spnt
->advanced
== ARRAY
) &&
2427 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2429 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2434 pnt
= cvt_integer (pnt
+ 1, &i
);
2435 pnt
= cvt_integer (pnt
+ 1, &i
);
2436 } while (*++pnt
!= ';');
2437 return 0; /* no forward refences found */
2440 /* Used to check a single element of a structure on the final pass*/
2443 final_forward_reference (spnt
)
2444 struct VMS_DBG_Symbol
* spnt
;
2446 struct VMS_DBG_Symbol
* spnt1
;
2447 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2448 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2449 spnt1
= find_symbol(spnt
->type2
);
2450 if((spnt
->advanced
== ARRAY
) &&
2451 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2452 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2456 return 0; /* no forward refences found */
2459 /* This routine parses the stabs directives to find any definitions of dbx type
2460 * numbers. It makes a note of all of them, creating a structure element
2461 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2462 * debugger that describes the struct/union/enum, so that further references
2463 * to these data types will be by number
2464 * We have to process pointers right away, since there can be references
2465 * to them later in the same stabs directive. We cannot have forward
2466 * references to pointers, (but we can have a forward reference to a pointer to
2467 * a structure/enum/union) and this is why we process them immediately.
2468 * After we process the pointer, then we search for defs that are nested even
2470 * 8/15/92: We have to process arrays right away too, because there can
2471 * be multiple references to identical array types in one structure
2472 * definition, and only the first one has the definition. (We tend to
2473 * parse from the back going forward.
2476 VMS_typedef_parse (str
)
2484 struct forward_ref
*fpnt
;
2486 int convert_integer
;
2487 struct VMS_DBG_Symbol
*spnt
;
2488 struct VMS_DBG_Symbol
*spnt1
;
2489 /* check for any nested def's */
2490 pnt
= (char *) strchr (str
+ 1, '=');
2491 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2492 && (str
[1] != 'a' || str
[2] != 'r'))
2493 if (VMS_typedef_parse (pnt
) == 1)
2495 /* now find dbx_type of entry */
2498 { /* check for static constants */
2499 *str
= '\0'; /* for now we ignore them */
2502 while ((*pnt
<= '9') && (*pnt
>= '0'))
2504 pnt
++; /* and get back to the number */
2505 cvt_integer (pnt
, &i1
);
2506 spnt
= find_symbol (i1
);
2507 /* first we see if this has been defined already, due to a forward reference*/
2508 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2510 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2512 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2513 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2514 VMS_Symbol_type_list
= spnt
;
2518 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2519 spnt
->next
= VMS_Symbol_type_list
;
2520 VMS_Symbol_type_list
= spnt
;
2522 spnt
->dbx_type
= i1
; /* and save the type */
2524 /* for structs and unions, do a partial parse, otherwise we sometimes get
2525 * circular definitions that are impossible to resolve. We read enough info
2526 * so that any reference to this type has enough info to be resolved
2528 pnt
= str
+ 1; /* point to character past equal sign */
2529 if ((*pnt
== 'u') || (*pnt
== 's'))
2532 if ((*pnt
<= '9') && (*pnt
>= '0'))
2534 if (type_check ("void"))
2535 { /* this is the void symbol */
2537 spnt
->advanced
= VOID
;
2540 if (type_check ("unknown type"))
2541 { /* this is the void symbol */
2543 spnt
->advanced
= UNKNOWN
;
2546 pnt1
= cvt_integer(pnt
,&i1
);
2547 if(i1
!= spnt
->dbx_type
)
2549 spnt
->advanced
= ALIAS
;
2554 printf ("gcc-as warning(debugger output):");
2555 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2556 return 1; /* do not know what this is */
2558 /* now define this module*/
2559 pnt
= str
+ 1; /* point to character past equal sign */
2563 spnt
->advanced
= BASIC
;
2564 if (type_check ("int"))
2566 spnt
->VMS_type
= DBG_S_C_SLINT
;
2567 spnt
->data_size
= 4;
2569 else if (type_check ("long int"))
2571 spnt
->VMS_type
= DBG_S_C_SLINT
;
2572 spnt
->data_size
= 4;
2574 else if (type_check ("unsigned int"))
2576 spnt
->VMS_type
= DBG_S_C_ULINT
;
2577 spnt
->data_size
= 4;
2579 else if (type_check ("long unsigned int"))
2581 spnt
->VMS_type
= DBG_S_C_ULINT
;
2582 spnt
->data_size
= 4;
2584 else if (type_check ("short int"))
2586 spnt
->VMS_type
= DBG_S_C_SSINT
;
2587 spnt
->data_size
= 2;
2589 else if (type_check ("short unsigned int"))
2591 spnt
->VMS_type
= DBG_S_C_USINT
;
2592 spnt
->data_size
= 2;
2594 else if (type_check ("char"))
2596 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2597 spnt
->data_size
= 1;
2599 else if (type_check ("signed char"))
2601 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2602 spnt
->data_size
= 1;
2604 else if (type_check ("unsigned char"))
2606 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2607 spnt
->data_size
= 1;
2609 else if (type_check ("float"))
2611 spnt
->VMS_type
= DBG_S_C_REAL4
;
2612 spnt
->data_size
= 4;
2614 else if (type_check ("double"))
2616 spnt
->VMS_type
= DBG_S_C_REAL8
;
2617 spnt
->data_size
= 8;
2619 pnt1
= (char *) strchr (str
, ';') + 1;
2624 spnt
->advanced
= STRUCT
;
2626 spnt
->advanced
= UNION
;
2627 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2628 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2629 if (!final_pass
&& forward_reference(pnt
))
2631 spnt
->struc_numb
= -1;
2634 spnt
->struc_numb
= ++structure_count
;
2636 pnt
= get_struct_name (str
);
2637 VMS_Def_Struct (spnt
->struc_numb
);
2639 while (fpnt
!= (struct forward_ref
*) NULL
)
2641 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2643 fpnt
->resolved
= 'Y';
2644 VMS_Set_Struct (fpnt
->struc_numb
);
2645 VMS_Store_Struct (spnt
->struc_numb
);
2649 VMS_Set_Struct (spnt
->struc_numb
);
2651 Local
[i
++] = 11 + strlen (pnt
);
2652 Local
[i
++] = DBG_S_C_STRUCT_START
;
2654 for (i1
= 0; i1
< 4; i1
++)
2656 Local
[i
++] = strlen (pnt
);
2658 while (*pnt2
!= '\0')
2659 Local
[i
++] = *pnt2
++;
2660 i2
= spnt
->data_size
* 8; /* number of bits */
2661 COPY_LONG(&Local
[i
], i2
);
2663 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2665 if (pnt
!= symbol_name
)
2667 pnt
+= strlen (pnt
);
2669 }; /* replace colon for later */
2670 while (*++pnt1
!= ';')
2672 pnt
= (char *) strchr (pnt1
, ':');
2675 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2676 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2677 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2678 if ((dtype
== 1) && (i3
!= 32))
2681 push (19 + strlen (pnt2
), 1);
2683 push (1 + strlen (pnt2
), 4);
2684 push (strlen (pnt2
), 1);
2685 while (*pnt2
!= '\0')
2687 push (i3
, 2); /* size of bitfield */
2690 push (i2
, 4); /* start position */
2691 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2696 Local
[i
++] = 7 + strlen (pnt2
);
2697 spnt1
= find_symbol (dtype
);
2698 /* check if this is a forward reference */
2699 if(final_pass
&& final_forward_reference(spnt1
))
2701 printf("gcc-as warning(debugger output):");
2702 printf("structure element %s has undefined type\n",pnt2
);
2706 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2707 Local
[i
++] = spnt1
->VMS_type
;
2709 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2710 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2711 COPY_LONG (&Local
[i
], i2
);
2713 Local
[i
++] = strlen (pnt2
);
2714 while (*pnt2
!= '\0')
2715 Local
[i
++] = *pnt2
++;
2716 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2718 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2719 generate_suffix (spnt1
, dtype
);
2720 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2721 generate_suffix (spnt1
, 0);
2725 Local
[i
++] = 0x01; /* length byte */
2726 Local
[i
++] = DBG_S_C_STRUCT_END
;
2727 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2731 spnt
->advanced
= ENUM
;
2732 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2733 spnt
->struc_numb
= ++structure_count
;
2734 spnt
->data_size
= 4;
2735 VMS_Def_Struct (spnt
->struc_numb
);
2737 while (fpnt
!= (struct forward_ref
*) NULL
)
2739 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2741 fpnt
->resolved
= 'Y';
2742 VMS_Set_Struct (fpnt
->struc_numb
);
2743 VMS_Store_Struct (spnt
->struc_numb
);
2747 VMS_Set_Struct (spnt
->struc_numb
);
2749 Local
[i
++] = 3 + strlen (symbol_name
);
2750 Local
[i
++] = DBG_S_C_ENUM_START
;
2752 Local
[i
++] = strlen (symbol_name
);
2754 while (*pnt2
!= '\0')
2755 Local
[i
++] = *pnt2
++;
2756 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2758 while (*++pnt
!= ';')
2760 pnt1
= (char *) strchr (pnt
, ':');
2762 pnt1
= cvt_integer (pnt1
, &i1
);
2763 Local
[i
++] = 7 + strlen (pnt
);
2764 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2766 COPY_LONG (&Local
[i
], i1
);
2768 Local
[i
++] = strlen (pnt
);
2770 while (*pnt
!= '\0')
2771 Local
[i
++] = *pnt
++;
2772 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2774 pnt
= pnt1
; /* Skip final semicolon */
2776 Local
[i
++] = 0x01; /* len byte */
2777 Local
[i
++] = DBG_S_C_ENUM_END
;
2778 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2783 spnt
->advanced
= ARRAY
;
2784 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2785 pnt
= (char *) strchr (pnt
, ';');
2786 if (pnt
== (char *) NULL
)
2788 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2789 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2790 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2791 pnt
=(char*)strchr(str
+1,'=');
2792 if((pnt
!= (char*) NULL
))
2793 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2796 spnt
->advanced
= FUNCTION
;
2797 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2798 /* this masquerades as a basic type*/
2799 spnt
->data_size
= 4;
2800 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2803 spnt
->advanced
= POINTER
;
2804 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2805 spnt
->data_size
= 4;
2806 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2807 pnt
= (char *) strchr (str
+ 1, '=');
2808 if ((pnt
!= (char *) NULL
))
2809 if (VMS_typedef_parse (pnt
) == 1)
2813 spnt
->advanced
= UNKNOWN
;
2815 printf ("gcc-as warning(debugger output):");
2816 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2817 return 1; /* unable to decipher */
2819 /* this removes the evidence of the definition so that the outer levels of
2820 parsing do not have to worry about it */
2822 while (*pnt1
!= '\0')
2830 * This is the root routine that parses the stabs entries for definitions.
2831 * it calls VMS_typedef_parse, which can in turn call itself.
2832 * We need to be careful, since sometimes there are forward references to
2833 * other symbol types, and these cannot be resolved until we have completed
2836 * Also check and see if we are using continuation stabs, if we are, then
2837 * paste together the entire contents of the stab before we pass it to
2838 * VMS_typedef_parse.
2847 char *parse_buffer
= 0;
2849 int incomplete
, i
, pass
, incom1
;
2850 struct VMS_DBG_Symbol
*spnt
;
2851 struct VMS_Symbol
*vsp
;
2852 struct forward_ref
*fpnt
;
2859 incom1
= incomplete
;
2861 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2864 * Deal with STAB symbols
2866 if (S_IS_DEBUG (sp
))
2869 * Dispatch on STAB type
2871 switch (S_GET_RAW_TYPE (sp
))
2879 case N_FUN
: /*sometimes these contain typedefs*/
2880 str
= S_GET_NAME (sp
);
2882 pnt
= str
+ strlen(str
) -1;
2883 if (*pnt
== '?') /* Continuation stab. */
2889 tlen
+= strlen(str
) - 1;
2890 spnext
= symbol_next (spnext
);
2891 str
= S_GET_NAME (spnext
);
2892 pnt
= str
+ strlen(str
) - 1;
2893 } while (*pnt
== '?');
2894 tlen
+= strlen(str
);
2895 parse_buffer
= (char *) malloc (tlen
+ 1);
2896 strcpy(parse_buffer
, S_GET_NAME (sp
));
2897 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2901 spnext
= symbol_next (spnext
);
2902 str
= S_GET_NAME (spnext
);
2903 strcat (pnt2
, S_GET_NAME (spnext
));
2904 pnt2
+= strlen(str
) - 1;
2905 *str
= '\0'; /* Erase this string */
2906 if (*pnt2
!= '?') break;
2912 pnt
= (char *) strchr (str
, ':');
2913 if (pnt
!= (char *) NULL
)
2917 pnt2
= (char *) strchr (pnt1
, '=');
2918 if (pnt2
!= (char *) NULL
)
2919 incomplete
+= VMS_typedef_parse (pnt2
);
2921 /* At this point the parse buffer should just contain name:nn.
2922 If it does not, then we are in real trouble. Anyway,
2923 this is always shorter than the original line. */
2924 strcpy(S_GET_NAME (sp
), parse_buffer
);
2925 free (parse_buffer
);
2928 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2935 /* Make one last pass, if needed, and define whatever we can that is left */
2936 if(final_pass
== 0 && incomplete
== incom1
)
2939 incom1
++; /* Force one last pass through */
2941 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2942 /* repeat until all refs resolved if possible */
2943 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2944 if (incomplete
!= 0)
2946 printf ("gcc-as warning(debugger output):");
2947 printf ("Unable to resolve %d circular references.\n", incomplete
);
2951 while (fpnt
!= (struct forward_ref
*) NULL
)
2953 if (fpnt
->resolved
!= 'Y')
2955 if (find_symbol (fpnt
->dbx_type
) !=
2956 (struct VMS_DBG_Symbol
*) NULL
)
2958 printf ("gcc-as warning(debugger output):");
2959 printf ("Forward reference error, dbx type %d\n",
2964 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2965 pnt2
= (char *) strchr (&fixit
[1], '=');
2966 VMS_typedef_parse (pnt2
);
2973 Define_Local_Symbols (s1
, s2
)
2977 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2979 if (symbolP1
== (symbolS
*) NULL
)
2981 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2983 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2984 if (*pnt
== 'F' || *pnt
== 'f') break;
2987 * Deal with STAB symbols
2989 if (S_IS_DEBUG (symbolP1
))
2992 * Dispatch on STAB type
2994 switch (S_GET_RAW_TYPE (symbolP1
))
2998 VMS_local_stab_Parse (symbolP1
);
3001 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
3009 /* This function crawls the symbol chain searching for local symbols that need
3010 * to be described to the debugger. When we enter a new scope with a "{", it
3011 * creates a new "block", which helps the debugger keep track of which scope
3012 * we are currently in.
3016 Define_Routine (symbolP
, Level
)
3026 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
3028 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3030 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3031 if (*pnt
== 'F' || *pnt
== 'f') break;
3034 * Deal with STAB symbols
3036 if (S_IS_DEBUG (symbolP1
))
3039 * Dispatch on STAB type
3041 switch (S_GET_RAW_TYPE (symbolP1
))
3046 sprintf (str
, "$%d", rcount
++);
3047 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3049 Offset
= S_GET_VALUE (symbolP1
);
3050 Define_Local_Symbols (sstart
, symbolP1
);
3052 Define_Routine (symbolP1
, Level
+ 1);
3054 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3063 /* we end up here if there were no brackets in this function. Define
3065 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3071 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3073 symbolS
*Curr_Routine
;
3076 Current_Routine
= Curr_Routine
;
3077 Text_Psect
= Txt_Psect
;
3078 Define_Routine (symbolP
, 0);
3085 #include <sys/types.h>
3088 /* Manufacure a VMS like time on a unix based system. */
3089 get_VMS_time_on_unix (Now
)
3095 pnt
= ctime (&timeb
);
3101 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3104 #endif /* not HO_VMS */
3106 * Write the MHD (Module Header) records
3109 Write_VMS_MHD_Records ()
3111 register char *cp
, *cp1
;
3118 char Module_Name
[256];
3122 * We are writing a module header record
3124 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3126 * ***************************
3127 * *MAIN MODULE HEADER RECORD*
3128 * ***************************
3130 * Store record type and header type
3132 PUT_CHAR (OBJ_S_C_HDR
);
3133 PUT_CHAR (MHD_S_C_MHD
);
3135 * Structure level is 0
3137 PUT_CHAR (OBJ_S_C_STRLVL
);
3139 * Maximum record size is size of the object record buffer
3141 PUT_SHORT (sizeof (Object_Record_Buffer
));
3143 * Get module name (the FILENAME part of the object file)
3149 if ((*cp
== ']') || (*cp
== '>') ||
3150 (*cp
== ':') || (*cp
== '/'))
3156 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3160 * Limit it to 31 characters and store in the object record
3162 while (--cp1
>= Module_Name
)
3165 if (strlen (Module_Name
) > 31)
3168 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3169 Module_Name
[31] = 0;
3171 PUT_COUNTED_STRING (Module_Name
);
3173 * Module Version is "V1.0"
3175 PUT_COUNTED_STRING ("V1.0");
3177 * Creation time is "now" (17 chars of time string)
3180 get_VMS_time_on_unix (&Now
[0]);
3182 Descriptor
.Size
= 17;
3183 Descriptor
.Ptr
= Now
;
3184 sys$
asctim (0, &Descriptor
, 0, 0);
3186 for (i
= 0; i
< 17; i
++)
3189 * Patch time is "never" (17 zeros)
3191 for (i
= 0; i
< 17; i
++)
3196 Flush_VMS_Object_Record_Buffer ();
3198 * *************************
3199 * *LANGUAGE PROCESSOR NAME*
3200 * *************************
3202 * Store record type and header type
3204 PUT_CHAR (OBJ_S_C_HDR
);
3205 PUT_CHAR (MHD_S_C_LNM
);
3207 * Store language processor name and version
3208 * (not a counted string!)
3210 cp
= compiler_version_string
;
3216 cp
= strchr (GAS_VERSION
, '.');
3226 Flush_VMS_Object_Record_Buffer ();
3231 * Write the EOM (End Of Module) record
3234 Write_VMS_EOM_Record (Psect
, Offset
)
3239 * We are writing an end-of-module record
3241 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3245 PUT_CHAR (OBJ_S_C_EOM
);
3247 * Store the error severity (0)
3251 * Store the entry point, if it exists
3256 * Store the entry point Psect
3260 * Store the entry point Psect offset
3267 Flush_VMS_Object_Record_Buffer ();
3271 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3277 register unsigned char *p
= ptr
;
3278 register unsigned char *end
= p
+ strlen (ptr
);
3279 register unsigned char c
;
3280 register int hash
= 0;
3285 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3291 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3294 VMS_Case_Hack_Symbol (In
, Out
)
3304 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3306 int Case_Hack_Bits
= 0;
3308 static char Hex_Table
[16] =
3309 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3312 * Kill any leading "_"
3314 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3317 new_name
= Out
; /* save this for later*/
3319 #if barfoo /* Dead code */
3320 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3324 /* We may need to truncate the symbol, save the hash for later*/
3325 if (strlen (In
) > 23)
3326 result
= hash_string (In
);
3328 * Is there a Psect Attribute to skip??
3330 if (HAS_PSECT_ATTRIBUTES (In
))
3335 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3338 if ((In
[0] == '$') && (In
[1] == '$'))
3348 /* if (strlen(In) > 31 && flagseen['+'])
3349 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3351 * Do the case conversion
3353 i
= 23; /* Maximum of 23 chars */
3354 while (*In
&& (--i
>= 0))
3356 Case_Hack_Bits
<<= 1;
3359 if ((destructor
== 1) && (i
== 21))
3361 switch (vms_name_mapping
)
3366 Case_Hack_Bits
|= 1;
3368 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3371 case 3: *Out
++ = *In
++;
3377 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3383 * If we saw a dollar sign, we don't do case hacking
3385 if (flagseen
['h'] || Saw_Dollar
)
3389 * If we have more than 23 characters and everything is lowercase
3390 * we can insert the full 31 characters
3395 * We have more than 23 characters
3396 * If we must add the case hack, then we have truncated the str
3400 if (Case_Hack_Bits
== 0)
3403 * And so far they are all lower case:
3404 * Check up to 8 more characters
3405 * and ensure that they are lowercase
3407 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3408 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3414 if ((i
== 8) || (In
[i
] == 0))
3417 * They are: Copy up to 31 characters
3418 * to the output string
3421 while ((--i
>= 0) && (*In
))
3422 switch (vms_name_mapping
){
3423 case 0: *Out
++ = islower(*In
) ?
3427 case 3: *Out
++ = *In
++;
3429 case 2: *Out
++ = isupper(*In
) ?
3438 * If there were any uppercase characters in the name we
3439 * take on the case hacking string
3442 /* Old behavior for regular GNU-C compiler */
3445 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3450 for (i
= 0; i
< 6; i
++)
3452 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3453 Case_Hack_Bits
>>= 4;
3459 Out
= pnt
; /*Cut back to 23 characters maximum */
3461 for (i
= 0; i
< 7; i
++)
3463 init
= result
& 0x01f;
3465 *Out
++ = '0' + init
;
3467 *Out
++ = 'A' + init
- 10;
3468 result
= result
>> 5;
3476 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3477 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3482 * Scan a symbol name for a psect attribute specification
3484 #define GLOBALSYMBOL_BIT 0x10000
3485 #define GLOBALVALUE_BIT 0x20000
3489 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3491 int *Attribute_Pointer
;
3502 {"PIC", GPS_S_M_PIC
},
3503 {"LIB", GPS_S_M_LIB
},
3504 {"OVR", GPS_S_M_OVR
},
3505 {"REL", GPS_S_M_REL
},
3506 {"GBL", GPS_S_M_GBL
},
3507 {"SHR", GPS_S_M_SHR
},
3508 {"EXE", GPS_S_M_EXE
},
3510 {"WRT", GPS_S_M_WRT
},
3511 {"VEC", GPS_S_M_VEC
},
3512 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3513 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3523 * Check for a PSECT attribute list
3525 if (!HAS_PSECT_ATTRIBUTES (Name
))
3526 return; /* If not, return */
3528 * Skip the attribute list indicator
3530 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3532 * Process the attributes ("_" separated, "$" terminated)
3534 while (*Name
!= '$')
3537 * Assume not negating
3543 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3546 * We are negating (and skip the NO)
3552 * Find the token delimiter
3555 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3558 * Look for the token in the attribute list
3560 for (i
= 0; Attributes
[i
].Name
; i
++)
3563 * If the strings match, set/clear the attr.
3565 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3571 *Attribute_Pointer
&=
3572 ~Attributes
[i
].Value
;
3574 *Attribute_Pointer
|=
3575 Attributes
[i
].Value
;
3583 * Now skip the attribute
3597 * Define a global symbol
3600 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3608 * We are writing a GSD record
3610 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3612 * If the buffer is empty we must insert the GSD record type
3614 if (Object_Record_Offset
== 0)
3615 PUT_CHAR (OBJ_S_C_GSD
);
3617 * We are writing a Global symbol definition subrecord
3619 if (Psect_Number
<= 255)
3621 PUT_CHAR (GSD_S_C_SYM
);
3625 PUT_CHAR (GSD_S_C_SYMW
);
3628 * Data type is undefined
3632 * Switch on Definition/Reference
3634 if ((Defined
& 1) != 0)
3638 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3639 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3641 if ((Defined
& 2) == 0)
3643 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3647 PUT_SHORT (GSY_S_M_DEF
);
3652 if (Psect_Number
<= 255)
3654 PUT_CHAR (Psect_Number
);
3658 PUT_SHORT (Psect_Number
);
3663 PUT_LONG (Psect_Offset
);
3669 * Flags = "RELOCATABLE" for regular symbol,
3670 * = "" for globalvalue (Defined & 2 == 1)
3672 if ((Defined
& 2) == 0)
3674 PUT_SHORT (GSY_S_M_REL
);
3682 * Finally, the global symbol name
3684 VMS_Case_Hack_Symbol (Name
, Local
);
3685 PUT_COUNTED_STRING (Local
);
3687 * Flush the buffer if it is more than 75% full
3689 if (Object_Record_Offset
>
3690 (sizeof (Object_Record_Buffer
) * 3 / 4))
3691 Flush_VMS_Object_Record_Buffer ();
3699 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3703 struct VMS_Symbol
*vsp
;
3706 int Psect_Attributes
;
3709 * Generate the appropriate PSECT flags given the PSECT type
3711 if (strcmp (Type
, "COMMON") == 0)
3714 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3716 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3717 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3719 else if (strcmp (Type
, "CONST") == 0)
3722 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3724 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3725 GPS_S_M_SHR
| GPS_S_M_RD
);
3727 else if (strcmp (Type
, "DATA") == 0)
3730 * The Data psects are PIC,REL,RD,WRT
3733 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3735 else if (strcmp (Type
, "TEXT") == 0)
3738 * The Text psects are PIC,REL,SHR,EXE,RD
3741 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3742 GPS_S_M_EXE
| GPS_S_M_RD
);
3747 * Error: Unknown psect type
3749 error ("Unknown VMS psect type");
3752 * Modify the psect attributes according to any attribute string
3754 if (HAS_PSECT_ATTRIBUTES (Name
))
3755 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3757 * Check for globalref/def/val.
3759 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3762 * globalvalue symbols were generated before. This code
3763 * prevents unsightly psect buildup, and makes sure that
3764 * fixup references are emitted correctly.
3766 vsp
->Psect_Index
= -1; /* to catch errors */
3767 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3768 return 1; /* decrement psect counter */
3771 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3773 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3775 case N_UNDF
| N_EXT
:
3776 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3777 vsp
->Psect_Offset
, 0);
3778 vsp
->Psect_Index
= -1;
3779 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3780 return 1; /* return and indicate no psect */
3781 case N_DATA
| N_EXT
:
3782 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3783 vsp
->Psect_Offset
, 1);
3784 /* In this case we still generate the psect */
3788 char Error_Line
[256];
3789 sprintf (Error_Line
,
3790 "Globalsymbol attribute for symbol %s was unexpected.\n",
3798 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3800 * We are writing a GSD record
3802 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3804 * If the buffer is empty we must insert the GSD record type
3806 if (Object_Record_Offset
== 0)
3807 PUT_CHAR (OBJ_S_C_GSD
);
3809 * We are writing a PSECT definition subrecord
3811 PUT_CHAR (GSD_S_C_PSC
);
3813 * Psects are always LONGWORD aligned
3817 * Specify the psect attributes
3819 PUT_SHORT (Psect_Attributes
);
3821 * Specify the allocation
3825 * Finally, the psect name
3827 VMS_Case_Hack_Symbol (Name
, Local
);
3828 PUT_COUNTED_STRING (Local
);
3830 * Flush the buffer if it is more than 75% full
3832 if (Object_Record_Offset
>
3833 (sizeof (Object_Record_Buffer
) * 3 / 4))
3834 Flush_VMS_Object_Record_Buffer ();
3840 * Given the pointer to a symbol we calculate how big the data at the
3841 * symbol is. We do this by looking for the next symbol (local or
3842 * global) which will indicate the start of another datum.
3845 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3846 register struct symbol
*sp
;
3849 register struct symbol
*sp1
, *Next_Symbol
;
3852 * Find the next symbol
3853 * it delimits this datum
3856 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3859 * The data type must match
3861 if (S_GET_TYPE (sp1
) != N_DATA
)
3864 * The symbol must be AFTER this symbol
3866 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3869 * We ignore THIS symbol
3874 * If there is already a candidate selected for the
3875 * next symbol, see if we are a better candidate
3880 * We are a better candidate if we are "closer"
3883 if (S_GET_VALUE (sp1
) >
3884 S_GET_VALUE (Next_Symbol
))
3887 * Win: Make this the candidate
3894 * This is the 1st candidate
3900 * Calculate its size
3902 return (Next_Symbol
?
3903 (S_GET_VALUE (Next_Symbol
) -
3905 (End_Of_Data
- S_GET_VALUE (sp
)));
3909 * Check symbol names for the Psect hack with a globalvalue, and then
3910 * generate globalvalues for those that have it.
3913 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3918 register symbolS
*sp
;
3919 char *stripped_name
, *Name
;
3921 int Psect_Attributes
;
3925 * Scan the symbol table for globalvalues, and emit def/ref when
3926 * required. These will be caught again later and converted to
3929 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3932 * See if this is something we want to look at.
3934 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3935 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3938 * See if this has globalvalue specification.
3940 Name
= S_GET_NAME (sp
);
3942 if (!HAS_PSECT_ATTRIBUTES (Name
))
3945 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3946 strcpy (stripped_name
, Name
);
3947 Psect_Attributes
= 0;
3948 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3950 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3952 switch (S_GET_RAW_TYPE (sp
))
3954 case N_UNDF
| N_EXT
:
3955 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3957 case N_DATA
| N_EXT
:
3958 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3960 error ("Invalid data type for globalvalue");
3961 globalvalue
= md_chars_to_number (Data_Segment
+
3962 S_GET_VALUE (sp
) - text_siz
, Size
);
3963 /* Three times for good luck. The linker seems to get confused
3964 if there are fewer than three */
3965 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3966 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3967 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3970 printf (" Invalid globalvalue of %s\n", stripped_name
);
3974 free (stripped_name
); /* clean up */
3981 * Define a procedure entry pt/mask
3984 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3993 * We are writing a GSD record
3995 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3997 * If the buffer is empty we must insert the GSD record type
3999 if (Object_Record_Offset
== 0)
4000 PUT_CHAR (OBJ_S_C_GSD
);
4002 * We are writing a Procedure Entry Pt/Mask subrecord
4004 if (Psect_Number
<= 255)
4006 PUT_CHAR (GSD_S_C_EPM
);
4010 PUT_CHAR (GSD_S_C_EPMW
);
4013 * Data type is undefined
4017 * Flags = "RELOCATABLE" and "DEFINED"
4019 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4023 if (Psect_Number
<= 255)
4025 PUT_CHAR (Psect_Number
);
4029 PUT_SHORT (Psect_Number
);
4034 PUT_LONG (Psect_Offset
);
4038 PUT_SHORT (Entry_Mask
);
4040 * Finally, the global symbol name
4042 VMS_Case_Hack_Symbol (Name
, Local
);
4043 PUT_COUNTED_STRING (Local
);
4045 * Flush the buffer if it is more than 75% full
4047 if (Object_Record_Offset
>
4048 (sizeof (Object_Record_Buffer
) * 3 / 4))
4049 Flush_VMS_Object_Record_Buffer ();
4054 * Set the current location counter to a particular Psect and Offset
4057 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4063 * We are writing a "Record_Type" record
4065 Set_VMS_Object_File_Record (Record_Type
);
4067 * If the buffer is empty we must insert the record type
4069 if (Object_Record_Offset
== 0)
4070 PUT_CHAR (Record_Type
);
4072 * Stack the Psect base + Longword Offset
4074 if (Psect_Index
< 255)
4076 PUT_CHAR (TIR_S_C_STA_PL
);
4077 PUT_CHAR (Psect_Index
);
4081 PUT_CHAR (TIR_S_C_STA_WPL
);
4082 PUT_SHORT (Psect_Index
);
4086 * Set relocation base
4088 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4090 * Flush the buffer if it is more than 75% full
4092 if (Object_Record_Offset
>
4093 (sizeof (Object_Record_Buffer
) * 3 / 4))
4094 Flush_VMS_Object_Record_Buffer ();
4099 * Store repeated immediate data in current Psect
4102 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4104 register char *Pointer
;
4110 * Ignore zero bytes/words/longwords
4112 if ((Size
== sizeof (char)) && (*Pointer
== 0))
4114 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
4116 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
4119 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4120 * then we do it manually
4124 while (--Repeat_Count
>= 0)
4125 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4129 * We are writing a "Record_Type" record
4131 Set_VMS_Object_File_Record (Record_Type
);
4133 * If the buffer is empty we must insert record type
4135 if (Object_Record_Offset
== 0)
4136 PUT_CHAR (Record_Type
);
4138 * Stack the repeat count
4140 PUT_CHAR (TIR_S_C_STA_LW
);
4141 PUT_LONG (Repeat_Count
);
4143 * And now the command and its data
4145 PUT_CHAR (TIR_S_C_STO_RIVB
);
4148 PUT_CHAR (*Pointer
++);
4150 * Flush the buffer if it is more than 75% full
4152 if (Object_Record_Offset
>
4153 (sizeof (Object_Record_Buffer
) * 3 / 4))
4154 Flush_VMS_Object_Record_Buffer ();
4159 * Store a Position Independent Reference
4162 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4163 Psect
, Psect_Offset
, Record_Type
)
4164 struct symbol
*Symbol
;
4171 register struct VMS_Symbol
*vsp
=
4172 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4176 * We are writing a "Record_Type" record
4178 Set_VMS_Object_File_Record (Record_Type
);
4180 * If the buffer is empty we must insert record type
4182 if (Object_Record_Offset
== 0)
4183 PUT_CHAR (Record_Type
);
4185 * Set to the appropriate offset in the Psect
4190 * For a Code reference we need to fix the operand
4191 * specifier as well (so back up 1 byte)
4193 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4198 * For a Data reference we just store HERE
4200 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4203 * Make sure we are still generating a "Record Type" record
4205 if (Object_Record_Offset
== 0)
4206 PUT_CHAR (Record_Type
);
4208 * Dispatch on symbol type (so we can stack its value)
4210 switch (S_GET_RAW_TYPE (Symbol
))
4215 #ifdef NOT_VAX_11_C_COMPATIBLE
4216 case N_UNDF
| N_EXT
:
4217 case N_DATA
| N_EXT
:
4218 #endif /* NOT_VAX_11_C_COMPATIBLE */
4220 case N_TEXT
| N_EXT
:
4222 * Get the symbol name (case hacked)
4224 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4226 * Stack the global symbol value
4228 PUT_CHAR (TIR_S_C_STA_GBL
);
4229 PUT_COUNTED_STRING (Local
);
4233 * Stack the longword offset
4235 PUT_CHAR (TIR_S_C_STA_LW
);
4238 * Add the two, leaving the result on the stack
4240 PUT_CHAR (TIR_S_C_OPR_ADD
);
4244 * Uninitialized local data
4248 * Stack the Psect (+offset)
4250 if (vsp
->Psect_Index
< 255)
4252 PUT_CHAR (TIR_S_C_STA_PL
);
4253 PUT_CHAR (vsp
->Psect_Index
);
4257 PUT_CHAR (TIR_S_C_STA_WPL
);
4258 PUT_SHORT (vsp
->Psect_Index
);
4260 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4267 * Stack the Psect (+offset)
4269 if (vsp
->Psect_Index
< 255)
4271 PUT_CHAR (TIR_S_C_STA_PL
);
4272 PUT_CHAR (vsp
->Psect_Index
);
4276 PUT_CHAR (TIR_S_C_STA_WPL
);
4277 PUT_SHORT (vsp
->Psect_Index
);
4279 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4282 * Initialized local or global data
4285 #ifndef NOT_VAX_11_C_COMPATIBLE
4286 case N_UNDF
| N_EXT
:
4287 case N_DATA
| N_EXT
:
4288 #endif /* NOT_VAX_11_C_COMPATIBLE */
4290 * Stack the Psect (+offset)
4292 if (vsp
->Psect_Index
< 255)
4294 PUT_CHAR (TIR_S_C_STA_PL
);
4295 PUT_CHAR (vsp
->Psect_Index
);
4299 PUT_CHAR (TIR_S_C_STA_WPL
);
4300 PUT_SHORT (vsp
->Psect_Index
);
4302 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4306 * Store either a code or data reference
4308 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4310 * Flush the buffer if it is more than 75% full
4312 if (Object_Record_Offset
>
4313 (sizeof (Object_Record_Buffer
) * 3 / 4))
4314 Flush_VMS_Object_Record_Buffer ();
4319 * Check in the text area for an indirect pc-relative reference
4320 * and fix it up with addressing mode 0xff [PC indirect]
4322 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4323 * PIC CODE GENERATING FIXUP ROUTINE.
4326 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4329 register fragS
*fragP
;
4330 struct frag
*text_frag_root
;
4333 * The addressing mode byte is 1 byte before the address
4337 * Is it in THIS frag??
4339 if ((Offset
< fragP
->fr_address
) ||
4340 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4343 * We need to search for the fragment containing this
4346 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4348 if ((Offset
>= fragP
->fr_address
) &&
4349 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4353 * If we couldn't find the frag, things are BAD!!
4356 error ("Couldn't find fixup fragment when checking for indirect reference");
4359 * Check for indirect PC relative addressing mode
4361 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4363 static char Address_Mode
= 0xff;
4366 * Yes: Store the indirect mode back into the image
4367 * to fix up the damage done by STO_PICR
4369 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4370 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4375 * If the procedure "main()" exists we have to add the instruction
4376 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4378 VMS_Check_For_Main ()
4380 register symbolS
*symbolP
;
4381 #ifdef HACK_DEC_C_STARTUP /* JF */
4382 register struct frchain
*frchainP
;
4383 register fragS
*fragP
;
4384 register fragS
**prev_fragPP
;
4385 register struct fix
*fixP
;
4386 register fragS
*New_Frag
;
4388 #endif /* HACK_DEC_C_STARTUP */
4390 symbolP
= (struct symbol
*) symbol_find ("_main");
4391 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4392 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4394 #ifdef HACK_DEC_C_STARTUP
4399 * Remember the entry point symbol
4401 Entry_Point_Symbol
= symbolP
;
4402 #ifdef HACK_DEC_C_STARTUP
4407 * Scan all the fragment chains for the one with "_main"
4408 * (Actually we know the fragment from the symbol, but we need
4409 * the previous fragment so we can change its pointer)
4411 frchainP
= frchain_root
;
4415 * Scan all the fragments in this chain, remembering
4416 * the "previous fragment"
4418 prev_fragPP
= &frchainP
->frch_root
;
4419 fragP
= frchainP
->frch_root
;
4420 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4423 * Is this the fragment?
4425 if (fragP
== symbolP
->sy_frag
)
4428 * Yes: Modify the fragment by replacing
4429 * it with a new fragment.
4431 New_Frag
= (fragS
*)
4432 xmalloc (sizeof (*New_Frag
) +
4437 * The fragments are the same except
4438 * that the "fixed" area is larger
4441 New_Frag
->fr_fix
+= 6;
4443 * Copy the literal data opening a hole
4444 * 2 bytes after "_main" (i.e. just after
4445 * the entry mask). Into which we place
4446 * the JSB instruction.
4448 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4449 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4450 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4451 New_Frag
->fr_literal
[3] = 0xef;
4452 New_Frag
->fr_literal
[4] = 0;
4453 New_Frag
->fr_literal
[5] = 0;
4454 New_Frag
->fr_literal
[6] = 0;
4455 New_Frag
->fr_literal
[7] = 0;
4456 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4457 New_Frag
->fr_literal
[i
+ 6] =
4458 fragP
->fr_literal
[i
];
4460 * Now replace the old fragment with the
4461 * newly generated one.
4463 *prev_fragPP
= New_Frag
;
4465 * Remember the entry point symbol
4467 Entry_Point_Symbol
= symbolP
;
4469 * Scan the text area fixup structures
4470 * as offsets in the fragment may have
4473 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4476 * Look for references to this
4479 if (fixP
->fx_frag
== fragP
)
4482 * Change the fragment
4485 fixP
->fx_frag
= New_Frag
;
4487 * If the offset is after
4488 * the entry mask we need
4489 * to account for the JSB
4490 * instruction we just
4493 if (fixP
->fx_where
>= 2)
4494 fixP
->fx_where
+= 6;
4498 * Scan the symbols as offsets in the
4499 * fragment may have changed
4501 for (symbolP
= symbol_rootP
;
4503 symbolP
= symbol_next (symbolP
))
4506 * Look for references to this
4509 if (symbolP
->sy_frag
== fragP
)
4512 * Change the fragment
4515 symbolP
->sy_frag
= New_Frag
;
4517 * If the offset is after
4518 * the entry mask we need
4519 * to account for the JSB
4520 * instruction we just
4523 if (S_GET_VALUE (symbolP
) >= 2)
4524 S_GET_VALUE (symbolP
) += 6;
4528 * Make a symbol reference to
4529 * "_c$main_args" so we can get
4530 * its address inserted into the
4533 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4534 S_GET_NAME (symbolP
) = "_c$main_args";
4535 S_SET_TYPE (symbolP
, N_UNDF
);
4536 S_GET_OTHER (symbolP
) = 0;
4537 S_GET_DESC (symbolP
) = 0;
4538 S_GET_VALUE (symbolP
) = 0;
4539 symbolP
->sy_name_offset
= 0;
4540 symbolP
->sy_number
= 0;
4541 symbolP
->sy_frag
= New_Frag
;
4542 symbolP
->sy_forward
= 0;
4543 /* this actually inserts at the beginning of the list */
4544 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4546 symbol_rootP
= symbolP
;
4548 * Generate a text fixup structure
4549 * to get "_c$main_args" stored into the
4552 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4553 fixP
->fx_frag
= New_Frag
;
4555 fixP
->fx_addsy
= symbolP
;
4557 fixP
->fx_offset
= 0;
4558 fixP
->fx_size
= sizeof (long);
4560 fixP
->fx_next
= text_fix_root
;
4561 text_fix_root
= fixP
;
4563 * Now make sure we exit from the loop
4569 * Try the next fragment
4571 prev_fragPP
= &fragP
->fr_next
;
4572 fragP
= fragP
->fr_next
;
4575 * Try the next fragment chain
4578 frchainP
= frchainP
->frch_next
;
4581 #endif /* HACK_DEC_C_STARTUP */
4586 * Write a VAX/VMS object file (everything else has been done!)
4588 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4593 struct frag
*text_frag_root
;
4594 struct frag
*data_frag_root
;
4596 register fragS
*fragP
;
4597 register symbolS
*symbolP
;
4598 register symbolS
*sp
;
4599 register struct fix
*fixP
;
4600 register struct VMS_Symbol
*vsp
;
4602 int Local_Initialized_Data_Size
= 0;
4604 int Psect_Number
= 0; /* Psect Index Number */
4605 int Text_Psect
= -1; /* Text Psect Index */
4606 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4607 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4610 * Create the VMS object file
4612 Create_VMS_Object_File ();
4614 * Write the module header records
4616 Write_VMS_MHD_Records ();
4619 * Store the Data segment:
4621 * Since this is REALLY hard to do any other way,
4622 * we actually manufacture the data segment and
4623 * the store the appropriate values out of it.
4624 * We need to generate this early, so that globalvalues
4625 * can be properly emitted.
4630 * Allocate the data segment
4632 Data_Segment
= (char *) xmalloc (data_siz
);
4634 * Run through the data fragments, filling in the segment
4636 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4638 register long int count
;
4639 register char *fill_literal
;
4640 register long int fill_size
;
4643 i
= fragP
->fr_address
- text_siz
;
4645 memcpy (Data_Segment
+ i
,
4650 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4651 fill_size
= fragP
->fr_var
;
4652 for (count
= fragP
->fr_offset
; count
; count
--)
4655 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4663 * Generate the VMS object file records
4664 * 1st GSD then TIR records
4667 /******* Global Symbol Dictionary *******/
4669 * Emit globalvalues now. We must do this before the text psect
4670 * is defined, or we will get linker warnings about multiply defined
4671 * symbols. All of the globalvalues "reference" psect 0, although
4672 * it really does not have anything to do with it.
4674 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4676 * Define the Text Psect
4678 Text_Psect
= Psect_Number
++;
4679 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4681 * Define the BSS Psect
4685 Bss_Psect
= Psect_Number
++;
4686 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4688 #ifndef gxx_bug_fixed
4690 * The g++ compiler does not write out external references to vtables
4691 * correctly. Check for this and holler if we see it happening.
4692 * If that compiler bug is ever fixed we can remove this.
4694 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4697 * Dispatch on symbol type
4699 switch (S_GET_RAW_TYPE (sp
)) {
4705 * Make a GSD global symbol reference
4708 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4710 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4711 as_warn("g++ wrote an extern reference to %s as a routine.",
4713 as_warn("I will fix it, but I hope that it was not really a routine");
4720 #endif /* gxx_bug_fixed */
4722 * Now scan the symbols and emit the appropriate GSD records
4724 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4727 * Dispatch on symbol type
4729 switch (S_GET_RAW_TYPE (sp
))
4732 * Global uninitialized data
4734 case N_UNDF
| N_EXT
:
4736 * Make a VMS data symbol entry
4738 vsp
= (struct VMS_Symbol
*)
4739 xmalloc (sizeof (*vsp
));
4741 vsp
->Size
= S_GET_VALUE (sp
);
4742 vsp
->Psect_Index
= Psect_Number
++;
4743 vsp
->Psect_Offset
= 0;
4744 vsp
->Next
= VMS_Symbols
;
4746 sp
->sy_number
= (int) vsp
;
4748 * Make the psect for this data
4750 if (S_GET_OTHER (sp
))
4751 Globalref
= VMS_Psect_Spec (
4757 Globalref
= VMS_Psect_Spec (
4765 /* See if this is an external vtable. We want to help the linker find
4766 these things in libraries, so we make a symbol reference. This
4767 is not compatible with VAX-C usage for variables, but since vtables are
4768 only used internally by g++, we can get away with this hack. */
4770 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4771 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4776 #ifdef NOT_VAX_11_C_COMPATIBLE
4778 * Place a global symbol at the
4779 * beginning of the Psect
4781 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4785 #endif /* NOT_VAX_11_C_COMPATIBLE */
4788 * Local uninitialized data
4792 * Make a VMS data symbol entry
4794 vsp
= (struct VMS_Symbol
*)
4795 xmalloc (sizeof (*vsp
));
4798 vsp
->Psect_Index
= Bss_Psect
;
4801 bss_address_frag
.fr_address
;
4802 vsp
->Next
= VMS_Symbols
;
4804 sp
->sy_number
= (int) vsp
;
4807 * Global initialized data
4809 case N_DATA
| N_EXT
:
4811 * Make a VMS data symbol entry
4813 vsp
= (struct VMS_Symbol
*)
4814 xmalloc (sizeof (*vsp
));
4816 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4817 text_siz
+ data_siz
);
4818 vsp
->Psect_Index
= Psect_Number
++;
4819 vsp
->Psect_Offset
= 0;
4820 vsp
->Next
= VMS_Symbols
;
4822 sp
->sy_number
= (int) vsp
;
4826 if (S_GET_OTHER (sp
))
4827 Globalref
= VMS_Psect_Spec (
4833 Globalref
= VMS_Psect_Spec (
4841 /* See if this is an external vtable. We want to help the linker find
4842 these things in libraries, so we make a symbol definition. This
4843 is not compatible with VAX-C usage for variables, but since vtables are
4844 only used internally by g++, we can get away with this hack. */
4846 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4847 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4852 #ifdef NOT_VAX_11_C_COMPATIBLE
4854 * Place a global symbol at the
4855 * beginning of the Psect
4857 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4861 #endif /* NOT_VAX_11_C_COMPATIBLE */
4864 * Local initialized data
4868 * Make a VMS data symbol entry
4870 vsp
= (struct VMS_Symbol
*)
4871 xmalloc (sizeof (*vsp
));
4874 VMS_Initialized_Data_Size (sp
,
4875 text_siz
+ data_siz
);
4876 vsp
->Psect_Index
= Data_Psect
;
4878 Local_Initialized_Data_Size
;
4879 Local_Initialized_Data_Size
+= vsp
->Size
;
4880 vsp
->Next
= VMS_Symbols
;
4882 sp
->sy_number
= (int) vsp
;
4885 * Global Text definition
4887 case N_TEXT
| N_EXT
:
4889 unsigned short Entry_Mask
;
4892 * Get the entry mask
4894 fragP
= sp
->sy_frag
;
4895 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4896 ((fragP
->fr_literal
[1] & 0xff)
4899 * Define the Procedure entry pt.
4901 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4908 * Local Text definition
4912 * Make a VMS data symbol entry
4914 if (Text_Psect
!= -1)
4916 vsp
= (struct VMS_Symbol
*)
4917 xmalloc (sizeof (*vsp
));
4920 vsp
->Psect_Index
= Text_Psect
;
4921 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4922 vsp
->Next
= VMS_Symbols
;
4924 sp
->sy_number
= (int) vsp
;
4932 * Make a GSD global symbol reference
4935 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4945 * Ignore STAB symbols
4946 * Including .stabs emitted by g++
4948 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4953 if (S_GET_TYPE (sp
) != 22)
4954 printf (" ERROR, unknown type (%d)\n",
4960 * Define the Data Psect
4962 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4967 Data_Psect
= Psect_Number
++;
4968 VMS_Psect_Spec ("$data",
4969 Local_Initialized_Data_Size
,
4972 * Scan the VMS symbols and fill in the data psect
4974 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4977 * Only look for undefined psects
4979 if (vsp
->Psect_Index
< 0)
4982 * And only initialized data
4984 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4985 vsp
->Psect_Index
= Data_Psect
;
4990 /******* Text Information and Relocation Records *******/
4992 * Write the text segment data
4997 * Scan the text fragments
4999 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
5002 * Stop if we get to the data fragments
5004 if (fragP
== data_frag_root
)
5007 * Ignore fragments with no data
5009 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5012 * Go the the appropriate offset in the
5015 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5017 * Store the "fixed" part
5020 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5024 * Store the "variable" part
5026 if (fragP
->fr_var
&& fragP
->fr_offset
)
5027 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5034 * Now we go through the text segment fixups and
5035 * generate TIR records to fix up addresses within
5038 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5041 * We DO handle the case of "Symbol - Symbol" as
5042 * long as it is in the same segment.
5044 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5049 * They need to be in the same segment
5051 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5052 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5053 error ("Fixup data addsy and subsy didn't have the same type");
5055 * And they need to be in one that we
5056 * can check the psect on
5058 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5059 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5060 error ("Fixup data addsy and subsy didn't have an appropriate type");
5062 * This had better not be PC relative!
5065 error ("Fixup data was erroneously \"pcrel\"");
5067 * Subtract their values to get the
5070 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5071 S_GET_VALUE (fixP
->fx_subsy
);
5073 * Now generate the fixup object records
5074 * Set the psect and store the data
5076 VMS_Set_Psect (Text_Psect
,
5078 fixP
->fx_frag
->fr_address
,
5080 VMS_Store_Immediate_Data (&i
,
5089 * Size will HAVE to be "long"
5091 if (fixP
->fx_size
!= sizeof (long))
5092 error ("Fixup datum was not a longword");
5094 * Symbol must be "added" (if it is ever
5096 * fix this assumption)
5098 if (fixP
->fx_addsy
== 0)
5099 error ("Fixup datum was not \"fixP->fx_addsy\"");
5101 * Store the symbol value in a PIC fashion
5103 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5108 fixP
->fx_frag
->fr_address
,
5111 * Check for indirect address reference,
5112 * which has to be fixed up (as the linker
5113 * will screw it up with TIR_S_C_STO_PICR).
5116 VMS_Fix_Indirect_Reference (Text_Psect
,
5118 fixP
->fx_frag
->fr_address
,
5124 * Store the Data segment:
5126 * Since this is REALLY hard to do any other way,
5127 * we actually manufacture the data segment and
5128 * the store the appropriate values out of it.
5129 * The segment was manufactured before, now we just
5130 * dump it into the appropriate psects.
5136 * Now we can run through all the data symbols
5137 * and store the data
5139 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5142 * Ignore anything other than data symbols
5144 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5147 * Set the Psect + Offset
5149 VMS_Set_Psect (vsp
->Psect_Index
,
5155 VMS_Store_Immediate_Data (Data_Segment
+
5156 S_GET_VALUE (vsp
->Symbol
) -
5162 * Now we go through the data segment fixups and
5163 * generate TIR records to fix up addresses within
5166 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5169 * Find the symbol for the containing datum
5171 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5174 * Only bother with Data symbols
5177 if (S_GET_TYPE (sp
) != N_DATA
)
5180 * Ignore symbol if After fixup
5182 if (S_GET_VALUE (sp
) >
5184 fixP
->fx_frag
->fr_address
))
5187 * See if the datum is here
5189 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5191 fixP
->fx_frag
->fr_address
))
5194 * We DO handle the case of "Symbol - Symbol" as
5195 * long as it is in the same segment.
5197 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5202 * They need to be in the same segment
5204 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5205 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5206 error ("Fixup data addsy and subsy didn't have the same type");
5208 * And they need to be in one that we
5209 * can check the psect on
5211 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5212 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5213 error ("Fixup data addsy and subsy didn't have an appropriate type");
5215 * This had better not be PC relative!
5218 error ("Fixup data was erroneously \"pcrel\"");
5220 * Subtract their values to get the
5223 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5224 S_GET_VALUE (fixP
->fx_subsy
);
5226 * Now generate the fixup object records
5227 * Set the psect and store the data
5229 VMS_Set_Psect (vsp
->Psect_Index
,
5230 fixP
->fx_frag
->fr_address
+
5232 S_GET_VALUE (vsp
->Symbol
) +
5235 VMS_Store_Immediate_Data (&i
,
5244 * Size will HAVE to be "long"
5246 if (fixP
->fx_size
!= sizeof (long))
5247 error ("Fixup datum was not a longword");
5249 * Symbol must be "added" (if it is ever
5251 * fix this assumption)
5253 if (fixP
->fx_addsy
== 0)
5254 error ("Fixup datum was not \"fixP->fx_addsy\"");
5256 * Store the symbol value in a PIC fashion
5258 VMS_Store_PIC_Symbol_Reference (
5263 fixP
->fx_frag
->fr_address
+
5265 S_GET_VALUE (vsp
->Symbol
) +
5278 * Write the Traceback Begin Module record
5280 VMS_TBT_Module_Begin ();
5282 * Scan the symbols and write out the routines
5283 * (this makes the assumption that symbols are in
5284 * order of ascending text segment offset)
5287 struct symbol
*Current_Routine
= 0;
5288 int Current_Line_Number
= 0;
5289 int Current_Offset
= -1;
5290 struct input_file
*Current_File
;
5292 /* Output debugging info for global variables and static variables that are not
5293 * specific to one routine. We also need to examine all stabs directives, to
5294 * find the definitions to all of the advanced data types, and this is done by
5295 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5296 * the object file, since there can be forward references in the stabs
5297 * directives. When through with parsing, the text of the stabs directive
5298 * is altered, with the definitions removed, so that later passes will see
5299 * directives as they would be written if the type were already defined.
5301 * We also look for files and include files, and make a list of them. We
5302 * examine the source file numbers to establish the actual lines that code was
5303 * generated from, and then generate offsets.
5306 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5309 * Deal with STAB symbols
5311 if (S_IS_DEBUG (symbolP
))
5314 * Dispatch on STAB type
5316 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5319 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5320 Current_File
->max_line
= S_GET_DESC (symbolP
);
5321 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5322 Current_File
->min_line
= S_GET_DESC (symbolP
);
5325 Current_File
= find_file (symbolP
);
5326 Current_File
->flag
= 1;
5327 Current_File
->min_line
= 1;
5330 Current_File
= find_file (symbolP
);
5333 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5336 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5338 case N_FUN
: /* For static constant symbols */
5340 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5346 /* now we take a quick sweep through the files and assign offsets
5347 to each one. This will essentially be the starting line number to the
5348 debugger for each file. Output the info for the debugger to specify the
5349 files, and then tell it how many lines to use */
5351 int File_Number
= 0;
5352 int Debugger_Offset
= 0;
5354 Current_File
= file_root
;
5355 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5357 if (Current_File
== (struct input_file
*) NULL
)
5359 if (Current_File
->max_line
== 0)
5361 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5364 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5367 /* show a few extra lines at the start of the region selected */
5368 if (Current_File
->min_line
> 2)
5369 Current_File
->min_line
-= 2;
5370 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5371 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5372 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5373 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5376 Current_File
->file_number
= ++File_Number
;
5377 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5378 Current_File
->file_number
);
5379 if (!file_available
)
5381 Current_File
->file_number
= 0;
5386 VMS_TBT_Source_Lines (Current_File
->file_number
,
5387 Current_File
->min_line
,
5388 Current_File
->max_line
- Current_File
->min_line
+ 1);
5391 Current_File
= (struct input_file
*) NULL
;
5393 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5396 * Deal with text symbols
5398 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5401 * Ignore symbols starting with "L",
5402 * as they are local symbols
5404 if (*S_GET_NAME (symbolP
) == 'L')
5407 * If there is a routine start defined,
5410 if (Current_Routine
)
5415 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5418 * Store the routine begin traceback info
5420 if (Text_Psect
!= -1)
5422 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5423 Current_Routine
= symbolP
;
5425 /* Output local symbols, i.e. all symbols that are associated with a specific
5426 * routine. We output them now so the debugger recognizes them as local to
5433 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5435 if (!S_IS_DEBUG (symbolP1
))
5437 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5439 pnt
= S_GET_NAME (symbolP
);
5440 pnt1
= S_GET_NAME (symbolP1
);
5443 while (*pnt
++ == *pnt1
++)
5446 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5447 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5450 if (symbolP1
!= (symbolS
*) NULL
)
5451 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5452 } /* local symbol block */
5459 * Deal with STAB symbols
5461 if (S_IS_DEBUG (symbolP
))
5464 * Dispatch on STAB type
5466 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5472 /* Offset the line into the correct portion
5474 if (Current_File
->file_number
== 0)
5476 /* Sometimes the same offset gets several source
5477 * lines assigned to it.
5478 * We should be selective about which lines
5479 * we allow, we should prefer lines that are
5480 * in the main source file when debugging
5481 * inline functions. */
5482 if ((Current_File
->file_number
!= 1) &&
5483 S_GET_VALUE (symbolP
) ==
5486 /* calculate actual debugger source line */
5487 S_GET_DESC (symbolP
)
5488 += Current_File
->offset
;
5490 * If this is the 1st N_SLINE, setup
5491 * PC/Line correlation. Otherwise
5492 * do the delta PC/Line. If the offset
5493 * for the line number is not +ve we need
5494 * to do another PC/Line correlation
5497 if (Current_Offset
== -1)
5499 VMS_TBT_Line_PC_Correlation (
5500 S_GET_DESC (symbolP
),
5501 S_GET_VALUE (symbolP
),
5507 if ((S_GET_DESC (symbolP
) -
5508 Current_Line_Number
) <= 0)
5511 * Line delta is not +ve, we
5512 * need to close the line and
5513 * start a new PC/Line
5516 VMS_TBT_Line_PC_Correlation (0,
5517 S_GET_VALUE (symbolP
) -
5521 VMS_TBT_Line_PC_Correlation (
5522 S_GET_DESC (symbolP
),
5523 S_GET_VALUE (symbolP
),
5530 * Line delta is +ve, all is well
5532 VMS_TBT_Line_PC_Correlation (
5533 S_GET_DESC (symbolP
) -
5534 Current_Line_Number
,
5535 S_GET_VALUE (symbolP
) -
5542 * Update the current line/PC
5544 Current_Line_Number
= S_GET_DESC (symbolP
);
5545 Current_Offset
= S_GET_VALUE (symbolP
);
5555 * Remember that we had a source file
5556 * and emit the source file debugger
5560 find_file (symbolP
);
5562 /* We need to make sure that we are really in the actual source file when
5563 * we compute the maximum line number. Otherwise the debugger gets really
5567 find_file (symbolP
);
5573 * If there is a routine start defined,
5574 * terminate it (and the line numbers)
5576 if (Current_Routine
)
5579 * Terminate the line numbers
5581 VMS_TBT_Line_PC_Correlation (0,
5582 text_siz
- S_GET_VALUE (Current_Routine
),
5586 * Terminate the routine
5588 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5592 * Write the Traceback End Module TBT record
5594 VMS_TBT_Module_End ();
5597 * Write the End Of Module record
5599 if (Entry_Point_Symbol
== 0)
5600 Write_VMS_EOM_Record (-1, 0);
5602 Write_VMS_EOM_Record (Text_Psect
,
5603 S_GET_VALUE (Entry_Point_Symbol
));
5606 * All done, close the object file
5608 Close_VMS_Object_File ();
5611 /* end of obj-vms.c */