1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992, 1994 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
28 /* What we do if there is a goof. */
29 #define error as_fatal
31 #ifdef VMS /* These are of no use if we are cross assembling. */
32 #include <fab.h> /* Define File Access Block */
33 #include <nam.h> /* Define NAM Block */
34 #include <xab.h> /* Define XAB - all different types*/
37 * Version string of the compiler that produced the code we are
38 * assembling. (And this assembler, if we do not have compiler info.)
40 char *compiler_version_string
;
42 extern int flag_hash_long_names
; /* -+ */
43 extern int flag_one
; /* -1 */
44 extern int flag_show_after_trunc
; /* -H */
45 extern int flag_no_hash_mixed_case
; /* -h NUM */
47 /* Flag that determines how we map names. This takes several values, and
48 * is set with the -h switch. A value of zero implies names should be
49 * upper case, and the presence of the -h switch inhibits the case hack.
50 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
51 * A value of 2 (set with -h2) implies names should be
52 * all lower case, with no case hack. A value of 3 (set with -h3) implies
53 * that case should be preserved. */
55 /* If the -+ switch is given, then the hash is appended to any name that is
56 * longer than 31 characters, irregardless of the setting of the -h switch.
59 char vms_name_mapping
= 0;
62 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
65 * We augment the "gas" symbol structure with this
69 struct VMS_Symbol
*Next
;
70 struct symbol
*Symbol
;
75 struct VMS_Symbol
*VMS_Symbols
= 0;
77 /* We need this to keep track of the various input files, so that we can
78 * give the debugger the correct source line.
83 struct input_file
*next
;
84 struct input_file
*same_file_fpnt
;
94 static struct input_file
*file_root
= (struct input_file
*) NULL
;
97 static struct input_file
*find_file
PARAMS ((symbolS
*));
100 * This enum is used to keep track of the various types of variables that
106 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
110 * This structure contains the information from the stabs directives, and the
111 * information is filled in by VMS_typedef_parse. Everything that is needed
112 * to generate the debugging record for a given symbol is present here.
113 * This could be done more efficiently, using nested struct/unions, but for now
114 * I am happy that it works.
116 struct VMS_DBG_Symbol
118 struct VMS_DBG_Symbol
*next
;
119 /* description of what this is */
120 enum advanced_type advanced
;
121 /* this record is for this type */
123 /* For advanced types this is the type referred to. I.e., the type
124 a pointer points to, or the type of object that makes up an
127 /* Use this type when generating a variable def */
129 /* used for arrays - this will be present for all */
131 /* entries, but will be meaningless for non-arrays */
133 /* Size in bytes of the data type. For an array, this is the size
134 of one element in the array */
136 /* Number of the structure/union/enum - used for ref */
140 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
;
143 * We need this structure to keep track of forward references to
144 * struct/union/enum that have not been defined yet. When they are ultimately
145 * defined, then we can go back and generate the TIR commands to make a back
151 struct forward_ref
*next
;
157 struct forward_ref
*f_ref_root
=
158 {(struct forward_ref
*) NULL
};
161 * This routine is used to compare the names of certain types to various
162 * fixed types that are known by the debugger.
164 #define type_check(x) !strcmp( symbol_name , x )
167 * This variable is used to keep track of the name of the symbol we are
168 * working on while we are parsing the stabs directives.
170 static char *symbol_name
;
172 /* We use this counter to assign numbers to all of the structures, unions
173 * and enums that we define. When we actually declare a variable to the
174 * debugger, we can simply do it by number, rather than describing the
175 * whole thing each time.
178 static structure_count
= 0;
180 /* This variable is used to indicate that we are making the last attempt to
181 parse the stabs, and that we should define as much as we can, and ignore
184 static int final_pass
;
186 /* This variable is used to keep track of the current structure number
187 * for a given variable. If this is < 0, that means that the structure
188 * has not yet been defined to the debugger. This is still cool, since
189 * the VMS object language has ways of fixing things up after the fact,
190 * so we just make a note of this, and generate fixups at the end.
192 static int struct_number
;
194 /* This is used to distinguish between D_float and G_float for telling
195 the debugger about doubles. gcc outputs the same .stabs regardless
196 of whether -mg is used to select alternate doubles. */
198 static int vax_g_doubles
= 0;
202 * Variable descriptors are used tell the debugger the data types of certain
203 * more complicated variables (basically anything involving a structure,
204 * union, enum, array or pointer). Some non-pointer variables of the
205 * basic types that the debugger knows about do not require a variable
208 * Since it is impossible to have a variable descriptor longer than 128
209 * bytes by virtue of the way that the VMS object language is set up,
210 * it makes not sense to make the arrays any longer than this, or worrying
211 * about dynamic sizing of the array.
213 * These are the arrays and counters that we use to build a variable
217 #define MAX_DEBUG_RECORD 128
218 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
219 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
220 static int Lpnt
; /* index into Local */
221 static int Apoint
; /* index into Asuffix */
222 static char overflow
; /* flag to indicate we have written too much*/
223 static int total_len
; /* used to calculate the total length of variable
224 descriptor plus array descriptor - used for len byte*/
226 /* Flag if we have told user about finding global constants in the text
228 static gave_compiler_message
= 0;
230 /* A pointer to the current routine that we are working on. */
232 static symbolS
*Current_Routine
;
234 /* The psect number for $code a.k.a. the text section. */
236 static int Text_Psect
;
240 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
242 static int VMS_Object_File_FD
; /* File Descriptor for object file */
243 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
244 static int Object_Record_Offset
;/* Offset to end of data */
245 static int Current_Object_Record_Type
; /* Type of record in above */
248 * Macros for moving data around. Must work on big-endian systems.
250 #ifdef VMS /* These are more efficient for VMS->VMS systems */
251 #define COPY_LONG(dest,val) {*(long *) dest = val; }
252 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
254 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
255 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
258 * Macros for placing data into the object record buffer
261 #define PUT_LONG(val) \
262 { md_number_to_chars(Object_Record_Buffer + \
263 Object_Record_Offset, val, 4); \
264 Object_Record_Offset += 4; }
266 #define PUT_SHORT(val) \
267 { md_number_to_chars(Object_Record_Buffer + \
268 Object_Record_Offset, val, 2); \
269 Object_Record_Offset += 2; }
271 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
273 #define PUT_COUNTED_STRING(cp) {\
274 register char *p = cp; \
275 PUT_CHAR(strlen(p)); \
276 while (*p) PUT_CHAR(*p++);}
279 * Macro for determining if a Name has psect attributes attached
282 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
283 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
285 #define HAS_PSECT_ATTRIBUTES(Name) \
286 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
287 PSECT_ATTRIBUTES_STRING, \
288 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
291 /* in: segT out: N_TYPE bits */
292 const short seg_N_TYPE
[] =
298 N_UNDF
, /* unknown */
300 N_UNDF
, /* expression */
304 N_REGISTER
, /* register */
307 const segT N_TYPE_seg
[N_TYPE
+ 2] =
308 { /* N_TYPE == 0x1E = 32-2 */
309 SEG_UNKNOWN
, /* N_UNDF == 0 */
311 SEG_ABSOLUTE
, /* N_ABS == 2 */
313 SEG_TEXT
, /* N_TEXT == 4 */
315 SEG_DATA
, /* N_DATA == 6 */
317 SEG_BSS
, /* N_BSS == 8 */
319 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
320 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
321 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
322 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
327 /* The following code defines the special types of pseudo-ops that we
331 char const_flag
= IN_DEFAULT_SECTION
;
338 temp
= get_absolute_expression ();
339 subseg_set (SEG_DATA
, (subsegT
) temp
);
341 demand_empty_rest_of_line ();
344 const pseudo_typeS obj_pseudo_table
[] =
346 {"const", s_const
, 0},
348 }; /* obj_pseudo_table */
351 vms_resolve_symbol_redef (sym
)
355 * If the new symbol is .comm AND it has a size of zero,
356 * we ignore it (i.e. the old symbol overrides it)
358 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)
359 && frag_now_fix () == 0)
361 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
366 * If the old symbol is .comm and it has a size of zero,
367 * we override it with the new symbol value.
369 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
370 && (S_GET_VALUE(sym
) == 0))
372 as_warn ("compiler redefined zero-size common symbol `%s'",
374 sym
->sy_frag
= frag_now
;
375 S_SET_OTHER(sym
, const_flag
);
376 S_SET_VALUE(sym
, frag_now_fix ());
377 /* Keep N_EXT bit. */
378 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
385 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
386 dummy label(s) gcc inserts at the beginning of each file it generates.
387 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
388 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
391 vms_check_for_special_label (symbolP
)
394 /* Special labels only occur prior to explicit section directives. */
395 if ((const_flag
& IN_DEFAULT_SECTION
) != 0)
397 char *sym_name
= S_GET_NAME(symbolP
);
399 if (*sym_name
== '_')
402 if (!strcmp (sym_name
, "__vax_g_doubles"))
404 #if 0 /* not necessary */
405 else if (!strcmp (sym_name
, "__vax_d_doubles"))
408 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
409 else if (!strcmp (sym_name
, "gcc_compiled."))
411 else if (!strcmp (sym_name
, "__gnu_language_cplusplus"))
412 flag_hash_long_names
= 1;
419 obj_read_begin_hook ()
424 obj_crawl_symbol_chain (headers
)
425 object_headers
*headers
;
429 int symbol_number
= 0;
431 { /* crawl symbol table */
432 register int symbol_number
= 0;
435 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
436 while ((symbolP
= *symbolPP
) != NULL
)
438 resolve_symbol_value (symbolP
);
440 /* OK, here is how we decide which symbols go out into the
441 brave new symtab. Symbols that do are:
443 * symbols with no name (stabd's?)
444 * symbols with debug info in their N_TYPE
446 Symbols that don't are:
447 * symbols that are registers
448 * symbols with \1 as their 3rd character (numeric labels)
449 * "local labels" as defined by S_LOCAL_NAME(name)
450 if the -L switch was passed to gas.
452 All other symbols are output. We complain if a deleted
453 symbol was marked external. */
456 if (!S_IS_REGISTER (symbolP
))
458 symbolP
->sy_name_offset
= 0;
459 symbolPP
= &(symbol_next (symbolP
));
463 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
465 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
468 } /* if this symbol should be in the output */
469 } /* for each symbol */
471 H_SET_STRING_SIZE (headers
, string_byte_count
);
472 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
473 } /* crawl symbol table */
475 } /* obj_crawl_symbol_chain() */
478 /****** VMS OBJECT FILE HACKING ROUTINES *******/
482 * Create the VMS object file
485 Create_VMS_Object_File ()
487 #if defined(eunice) || !defined(VMS)
488 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
490 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
491 "mbc=16", "deq=64", "fop=tef", "shr=nil");
496 if (VMS_Object_File_FD
< 0)
497 as_fatal ("Couldn't create VMS object file \"%s\"", out_file_name
);
499 * Initialize object file hacking variables
501 Object_Record_Offset
= 0;
502 Current_Object_Record_Type
= -1;
507 * Flush the object record buffer to the object file
510 Flush_VMS_Object_Record_Buffer ()
516 * If the buffer is empty, we are done
518 if (Object_Record_Offset
== 0)
521 * Write the data to the file
523 #ifndef VMS /* For cross-assembly purposes. */
524 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
525 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
527 i
= write (VMS_Object_File_FD
,
528 Object_Record_Buffer
,
529 Object_Record_Offset
);
530 if (i
!= Object_Record_Offset
)
531 error ("I/O error writing VMS object file");
532 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
534 /* pad it if needed */
536 if (Object_Record_Offset
& 1 != 0)
537 write (VMS_Object_File_FD
, &zero
, 1);
540 * The buffer is now empty
542 Object_Record_Offset
= 0;
547 * Declare a particular type of object file record
550 Set_VMS_Object_File_Record (Type
)
554 * If the type matches, we are done
556 if (Type
== Current_Object_Record_Type
)
559 * Otherwise: flush the buffer
561 Flush_VMS_Object_Record_Buffer ();
565 Current_Object_Record_Type
= Type
;
571 * Close the VMS Object file
574 Close_VMS_Object_File ()
576 short int m_one
= -1;
577 /* @@ This should not be here!! The same would presumably be needed
578 if we were writing vax-bsd a.out files on a vms system. Put it
580 #ifndef VMS /* For cross-assembly purposes. */
581 /* Write a 0xffff into the file, which means "End of File" */
582 write (VMS_Object_File_FD
, &m_one
, 2);
584 close (VMS_Object_File_FD
);
589 * Store immediate data in current Psect
592 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
600 * We are writing a "Record_Type" record
602 Set_VMS_Object_File_Record (Record_Type
);
604 * We can only store 128 bytes at a time
609 * Store a maximum of 128 bytes
611 i
= (Size
> 128) ? 128 : Size
;
614 * If we cannot accommodate this record, flush the
617 if ((Object_Record_Offset
+ i
+ 1) >=
618 sizeof (Object_Record_Buffer
))
619 Flush_VMS_Object_Record_Buffer ();
621 * If the buffer is empty we must insert record type
623 if (Object_Record_Offset
== 0)
624 PUT_CHAR (Record_Type
);
628 PUT_CHAR (-i
& 0xff);
633 PUT_CHAR (*Pointer
++);
635 * Flush the buffer if it is more than 75% full
637 if (Object_Record_Offset
>
638 (sizeof (Object_Record_Buffer
) * 3 / 4))
639 Flush_VMS_Object_Record_Buffer ();
644 * Make a data reference
647 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
654 * We are writing a "Record_Type" record
656 Set_VMS_Object_File_Record (Record_Type
);
658 * If the buffer is empty we must insert the record type
660 if (Object_Record_Offset
== 0)
661 PUT_CHAR (Record_Type
);
663 * Stack the Psect base + Longword Offset
667 if (Psect_Index
> 127)
669 PUT_CHAR (TIR_S_C_STA_WPL
);
670 PUT_SHORT (Psect_Index
);
675 PUT_CHAR (TIR_S_C_STA_PL
);
676 PUT_CHAR (Psect_Index
);
684 PUT_CHAR (TIR_S_C_STA_WPL
);
685 PUT_SHORT (Psect_Index
);
688 else if (Offset
> 127)
690 PUT_CHAR (TIR_S_C_STA_WPW
);
691 PUT_SHORT (Psect_Index
);
696 PUT_CHAR (TIR_S_C_STA_WPB
);
697 PUT_SHORT (Psect_Index
);
702 * Set relocation base
704 PUT_CHAR (TIR_S_C_STO_PIDR
);
706 * Flush the buffer if it is more than 75% full
708 if (Object_Record_Offset
>
709 (sizeof (Object_Record_Buffer
) * 3 / 4))
710 Flush_VMS_Object_Record_Buffer ();
714 * Make a debugger reference to a struct, union or enum.
717 VMS_Store_Struct (Struct_Index
)
721 * We are writing a "OBJ_S_C_DBG" record
723 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
725 * If the buffer is empty we must insert the record type
727 if (Object_Record_Offset
== 0)
728 PUT_CHAR (OBJ_S_C_DBG
);
729 PUT_CHAR (TIR_S_C_STA_UW
);
730 PUT_SHORT (Struct_Index
);
731 PUT_CHAR (TIR_S_C_CTL_STKDL
);
732 PUT_CHAR (TIR_S_C_STO_L
);
734 * Flush the buffer if it is more than 75% full
736 if (Object_Record_Offset
>
737 (sizeof (Object_Record_Buffer
) * 3 / 4))
738 Flush_VMS_Object_Record_Buffer ();
742 * Make a debugger reference to partially define a struct, union or enum.
745 VMS_Def_Struct (Struct_Index
)
749 * We are writing a "OBJ_S_C_DBG" record
751 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
753 * If the buffer is empty we must insert the record type
755 if (Object_Record_Offset
== 0)
756 PUT_CHAR (OBJ_S_C_DBG
);
757 PUT_CHAR (TIR_S_C_STA_UW
);
758 PUT_SHORT (Struct_Index
);
759 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
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 ();
769 VMS_Set_Struct (Struct_Index
)
771 { /* see previous functions for comments */
772 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
773 if (Object_Record_Offset
== 0)
774 PUT_CHAR (OBJ_S_C_DBG
);
775 PUT_CHAR (TIR_S_C_STA_UW
);
776 PUT_SHORT (Struct_Index
);
777 PUT_CHAR (TIR_S_C_CTL_STLOC
);
778 if (Object_Record_Offset
>
779 (sizeof (Object_Record_Buffer
) * 3 / 4))
780 Flush_VMS_Object_Record_Buffer ();
784 * Write the Traceback Module Begin record
787 VMS_TBT_Module_Begin ()
789 register char *cp
, *cp1
;
791 char Module_Name
[256];
795 * Get module name (the FILENAME part of the object file)
801 if ((*cp
== ']') || (*cp
== '>') ||
802 (*cp
== ':') || (*cp
== '/'))
808 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
812 * Limit it to 31 characters
814 while (--cp1
>= Module_Name
)
817 if (strlen (Module_Name
) > 31)
819 if (flag_hash_long_names
)
820 as_tsktsk ("Module name truncated: %s", Module_Name
);
824 * Arrange to store the data locally (leave room for size byte)
830 *cp
++ = DST_S_C_MODBEG
;
836 * Language type == "C"
838 COPY_LONG (cp
, DST_S_C_C
);
841 * Store the module name
843 *cp
++ = strlen (Module_Name
);
848 * Now we can store the record size
853 * Put it into the object record
855 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
860 * Write the Traceback Module End record
863 VMS_TBT_Module_End ()
871 Local
[1] = DST_S_C_MODEND
;
873 * Put it into the object record
875 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
880 * Write the Traceback Routine Begin record
883 VMS_TBT_Routine_Begin (symbolP
, Psect
)
884 struct symbol
*symbolP
;
887 register char *cp
, *cp1
;
894 * Strip the leading "_" from the name
896 Name
= S_GET_NAME (symbolP
);
900 * Get the text psect offset
902 Offset
= S_GET_VALUE (symbolP
);
904 * Calculate the record size
906 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
914 Local
[1] = DST_S_C_RTNBEG
;
920 * Store the data so far
922 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
924 * Make sure we are still generating a OBJ_S_C_TBT record
926 if (Object_Record_Offset
== 0)
927 PUT_CHAR (OBJ_S_C_TBT
);
929 * Now get the symbol address
931 PUT_CHAR (TIR_S_C_STA_WPL
);
935 * Store the data reference
937 PUT_CHAR (TIR_S_C_STO_PIDR
);
939 * Store the counted string as data
943 Size
= strlen (cp1
) + 1;
947 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
952 * Write the Traceback Routine End record
953 * We *must* search the symbol table to find the next routine, since
954 * the assember has a way of reassembling the symbol table OUT OF ORDER
955 * Thus the next routine in the symbol list is not necessarily the
956 * next one in memory. For debugging to work correctly we must know the
957 * size of the routine.
960 VMS_TBT_Routine_End (Max_Size
, sp
)
965 int Size
= 0x7fffffff;
967 valueT sym_value
, sp_value
= S_GET_VALUE (sp
);
969 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
971 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
973 if (*S_GET_NAME (symbolP
) == 'L')
975 sym_value
= S_GET_VALUE (symbolP
);
976 if (sym_value
> sp_value
&& sym_value
< Size
)
980 * Dummy labels like "gcc_compiled." should no longer reach here.
984 /* check if gcc_compiled. has size of zero */
985 if (sym_value
== sp_value
&&
987 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
988 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
993 if (Size
== 0x7fffffff)
995 Size
-= sp_value
; /* and get the size of the routine */
1003 Local
[1] = DST_S_C_RTNEND
;
1011 COPY_LONG (&Local
[3], Size
);
1015 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1019 * Write the Traceback Block End record
1022 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1023 struct symbol
*symbolP
;
1027 register char *cp
, *cp1
;
1034 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1040 * Begin Block - We simulate with a phony routine
1042 Local
[1] = DST_S_C_BLKBEG
;
1048 * Store the data so far
1050 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1052 * Make sure we are still generating a OBJ_S_C_DBG record
1054 if (Object_Record_Offset
== 0)
1055 PUT_CHAR (OBJ_S_C_DBG
);
1057 * Now get the symbol address
1059 PUT_CHAR (TIR_S_C_STA_WPL
);
1062 * Get the text psect offset
1064 Offset
= S_GET_VALUE (symbolP
);
1067 * Store the data reference
1069 PUT_CHAR (TIR_S_C_STO_PIDR
);
1071 * Store the counted string as data
1075 Size
= strlen (cp1
) + 1;
1079 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1084 * Write the Traceback Block End record
1087 VMS_TBT_Block_End (Size
)
1093 * End block - simulate with a phony end routine
1096 Local
[1] = DST_S_C_BLKEND
;
1097 COPY_LONG (&Local
[3], Size
);
1102 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1108 * Write a Line number / PC correlation record
1111 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1121 * If not delta, set our PC/Line number correlation
1128 Local
[0] = 1 + 1 + 2 + 1 + 4;
1130 * Line Number/PC correlation
1132 Local
[1] = DST_S_C_LINE_NUM
;
1136 Local
[2] = DST_S_C_SET_LINE_NUM
;
1137 COPY_SHORT (&Local
[3], Line_Number
- 1);
1141 Local
[5] = DST_S_C_SET_ABS_PC
;
1142 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1144 * Make sure we are still generating a OBJ_S_C_TBT record
1146 if (Object_Record_Offset
== 0)
1147 PUT_CHAR (OBJ_S_C_TBT
);
1150 PUT_CHAR (TIR_S_C_STA_PL
);
1155 PUT_CHAR (TIR_S_C_STA_WPL
);
1159 PUT_CHAR (TIR_S_C_STO_PIDR
);
1161 * Do a PC offset of 0 to register the line number
1164 Local
[1] = DST_S_C_LINE_NUM
;
1165 Local
[2] = 0; /* Increment PC by 0 and register line # */
1166 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1171 * If Delta is negative, terminate the line numbers
1175 Local
[0] = 1 + 1 + 4;
1176 Local
[1] = DST_S_C_LINE_NUM
;
1177 Local
[2] = DST_S_C_TERM_L
;
1178 COPY_LONG (&Local
[3], Offset
);
1179 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1186 * Do a PC/Line delta
1189 *cp
++ = DST_S_C_LINE_NUM
;
1190 if (Line_Number
> 1)
1193 * We need to increment the line number
1195 if (Line_Number
- 1 <= 255)
1197 *cp
++ = DST_S_C_INCR_LINUM
;
1198 *cp
++ = Line_Number
- 1;
1202 *cp
++ = DST_S_C_INCR_LINUM_W
;
1203 COPY_SHORT (cp
, Line_Number
- 1);
1216 if (Offset
< 0x10000)
1218 *cp
++ = DST_S_C_DELTA_PC_W
;
1219 COPY_SHORT (cp
, Offset
);
1224 *cp
++ = DST_S_C_DELTA_PC_L
;
1225 COPY_LONG (cp
, Offset
);
1229 Local
[0] = cp
- (Local
+ 1);
1230 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1236 * Describe a source file to the debugger
1239 VMS_TBT_Source_File (Filename
, ID_Number
)
1243 register char *cp
, *cp1
;
1246 #ifndef VMS /* Used for cross-assembly */
1247 i
= strlen (Filename
);
1249 static struct FAB Fab
;
1250 static struct NAM Nam
;
1251 static struct XABDAT Date_Xab
;
1252 static struct XABFHC File_Header_Xab
;
1253 char Es_String
[255], Rs_String
[255];
1258 Fab
.fab$b_bid
= FAB$C_BID
;
1259 Fab
.fab$b_bln
= sizeof (Fab
);
1260 Fab
.fab$l_nam
= (&Nam
);
1261 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1263 * Setup the Nam block so we can find out the FULL name
1264 * of the source file.
1266 Nam
.nam$b_bid
= NAM$C_BID
;
1267 Nam
.nam$b_bln
= sizeof (Nam
);
1268 Nam
.nam$l_rsa
= Rs_String
;
1269 Nam
.nam$b_rss
= sizeof (Rs_String
);
1270 Nam
.nam$l_esa
= Es_String
;
1271 Nam
.nam$b_ess
= sizeof (Es_String
);
1273 * Setup the Date and File Header Xabs
1275 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1276 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1277 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1278 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1279 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1281 * Get the file information
1283 Fab
.fab$l_fna
= Filename
;
1284 Fab
.fab$b_fns
= strlen (Filename
);
1285 Status
= sys$
open (&Fab
);
1288 as_tsktsk ("Couldn't find source file \"%s\", status=%%X%x",
1294 * Calculate the size of the resultant string
1301 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1303 * Source declaration
1305 Local
[1] = DST_S_C_SOURCE
;
1307 * Make formfeeds count as source records
1309 Local
[2] = DST_S_C_SRC_FORMFEED
;
1311 * Declare source file
1313 Local
[3] = DST_S_C_SRC_DECLFILE
;
1314 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1323 COPY_SHORT (cp
, ID_Number
);
1327 * Creation Date. Unknown, so we fill with zeroes.
1352 #else /* Use this code when assembling for VMS on a VMS system */
1356 memcpy (cp
, (char *) &Date_Xab
.xab$q_cdt
, 8);
1361 COPY_LONG (cp
, File_Header_Xab
.xab$l_ebk
);
1366 COPY_SHORT (cp
, File_Header_Xab
.xab$w_ffb
);
1371 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1381 * Library module name (none)
1387 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1393 * Give the number of source lines to the debugger
1396 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1398 int Starting_Line_Number
;
1399 int Number_Of_Lines
;
1407 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1409 * Source declaration
1411 Local
[1] = DST_S_C_SOURCE
;
1416 *cp
++ = DST_S_C_SRC_SETFILE
;
1420 COPY_SHORT (cp
, ID_Number
);
1425 *cp
++ = DST_S_C_SRC_SETREC_L
;
1426 COPY_LONG (cp
, Starting_Line_Number
);
1431 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1432 COPY_SHORT (cp
, Number_Of_Lines
);
1437 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1443 /* This routine locates a file in the list of files. If an entry does not
1444 * exist, one is created. For include files, a new entry is always created
1445 * such that inline functions can be properly debugged. */
1446 static struct input_file
*
1450 struct input_file
*same_file
;
1451 struct input_file
*fpnt
;
1452 same_file
= (struct input_file
*) NULL
;
1453 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1455 if (fpnt
== (struct input_file
*) NULL
)
1457 if (fpnt
->spnt
== sp
)
1460 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1462 if (fpnt
== (struct input_file
*) NULL
)
1464 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1466 if (fpnt
->flag
== 1)
1472 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1473 if (file_root
== (struct input_file
*) NULL
)
1477 struct input_file
*fpnt1
;
1478 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1481 fpnt
->next
= (struct input_file
*) NULL
;
1482 fpnt
->name
= S_GET_NAME (sp
);
1483 fpnt
->min_line
= 0x7fffffff;
1487 fpnt
->file_number
= 0;
1489 fpnt
->same_file_fpnt
= same_file
;
1494 * The following functions and definitions are used to generate object records
1495 * that will describe program variables to the VMS debugger.
1497 * This file contains many of the routines needed to output debugging info into
1498 * the object file that the VMS debugger needs to understand symbols. These
1499 * routines are called very late in the assembly process, and thus we can be
1500 * fairly lax about changing things, since the GSD and the TIR sections have
1501 * already been output.
1505 /* This routine converts a number string into an integer, and stops when it
1506 * sees an invalid character. The return value is the address of the character
1507 * just past the last character read. No error is generated.
1510 cvt_integer (str
, rtn
)
1515 neg
= *str
== '-' ? ++str
, -1 : 1;
1517 while ((*str
<= '9') && (*str
>= '0'))
1518 ival
= 10 * ival
+ *str
++ - '0';
1523 /* this routine fixes the names that are generated by C++, ".this" is a good
1524 * example. The period does not work for the debugger, since it looks like
1525 * the syntax for a structure element, and thus it gets mightily confused
1527 * We also use this to strip the PsectAttribute hack from the name before we
1528 * write a debugger record */
1536 * Kill any leading "_"
1541 * Is there a Psect Attribute to skip??
1543 if (HAS_PSECT_ATTRIBUTES (pnt
))
1548 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1551 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1559 /* Here we fix the .this -> $this conversion */
1560 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1568 /* When defining a structure, this routine is called to find the name of
1569 * the actual structure. It is assumed that str points to the equal sign
1570 * in the definition, and it moves backward until it finds the start of the
1571 * name. If it finds a 0, then it knows that this structure def is in the
1572 * outermost level, and thus symbol_name points to the symbol name.
1575 get_struct_name (str
)
1580 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1585 while ((*pnt
!= ';') && (*pnt
!= '='))
1589 while ((*pnt
< '0') || (*pnt
> '9'))
1591 while ((*pnt
>= '0') && (*pnt
<= '9'))
1596 /* search symbol list for type number dbx_type. Return a pointer to struct */
1597 static struct VMS_DBG_Symbol
*
1598 find_symbol (dbx_type
)
1601 struct VMS_DBG_Symbol
*spnt
;
1602 spnt
= VMS_Symbol_type_list
;
1603 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1605 if (spnt
->dbx_type
== dbx_type
)
1609 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1610 return 0; /*Dunno what this is*/
1611 if(spnt
->advanced
== ALIAS
)
1612 return find_symbol(spnt
->type2
);
1617 /* this routine puts info into either Local or Asuffix, depending on the sign
1618 * of size. The reason is that it is easier to build the variable descriptor
1619 * backwards, while the array descriptor is best built forwards. In the end
1620 * they get put together, if there is not a struct/union/enum along the way
1639 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1643 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1646 Apoint
= MAX_DEBUG_RECORD
- 1;
1649 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1654 /* this routine generates the array descriptor for a given array */
1656 array_suffix (spnt2
)
1657 struct VMS_DBG_Symbol
*spnt2
;
1659 struct VMS_DBG_Symbol
*spnt
;
1660 struct VMS_DBG_Symbol
*spnt1
;
1666 while (spnt
->advanced
!= ARRAY
)
1668 spnt
= find_symbol (spnt
->type2
);
1669 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1675 while (spnt1
->advanced
== ARRAY
)
1678 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1679 spnt1
= find_symbol (spnt1
->type2
);
1681 total_size
= total_size
* spnt1
->data_size
;
1682 push (spnt1
->data_size
, 2); /* element size */
1683 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1686 push (spnt1
->VMS_type
, 1); /* element type */
1687 push (DSC_K_CLASS_A
, 1); /* descriptor class */
1688 push (0, 4); /* base address */
1689 push (0, 1); /* scale factor -- not applicable */
1690 push (0, 1); /* digit count -- not applicable */
1691 push (0xc0, 1); /* flags: multiplier block & bounds present */
1692 push (rank
, 1); /* number of dimensions */
1693 push (total_size
, 4);
1694 push (0, 4); /* pointer to element [0][0]...[0] */
1696 while (spnt1
->advanced
== ARRAY
)
1698 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1699 spnt1
= find_symbol (spnt1
->type2
);
1702 while (spnt1
->advanced
== ARRAY
)
1704 push (spnt1
->index_min
, 4);
1705 push (spnt1
->index_max
, 4);
1706 spnt1
= find_symbol (spnt1
->type2
);
1710 /* this routine generates the start of a variable descriptor based upon
1711 * a struct/union/enum that has yet to be defined. We define this spot as
1712 * a new location, and save four bytes for the address. When the struct is
1713 * finally defined, then we can go back and plug in the correct address.
1716 new_forward_ref (dbx_type
)
1719 struct forward_ref
*fpnt
;
1720 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1721 fpnt
->next
= f_ref_root
;
1723 fpnt
->dbx_type
= dbx_type
;
1724 fpnt
->struc_numb
= ++structure_count
;
1725 fpnt
->resolved
= 'N';
1726 push (DST_K_TS_IND
, -1); /* indirect type specification */
1728 push (total_len
, -2);
1729 struct_number
= -fpnt
->struc_numb
;
1732 /* this routine generates the variable descriptor used to describe non-basic
1733 * variables. It calls itself recursively until it gets to the bottom of it
1734 * all, and then builds the descriptor backwards. It is easiest to do it this
1735 *way since we must periodically write length bytes, and it is easiest if we know
1736 *the value when it is time to write it.
1739 gen1 (spnt
, array_suffix_len
)
1740 struct VMS_DBG_Symbol
*spnt
;
1741 int array_suffix_len
;
1743 struct VMS_DBG_Symbol
*spnt1
;
1745 switch (spnt
->advanced
)
1748 push (DBG_S_C_VOID
, -1);
1750 push (total_len
, -2);
1754 if (array_suffix_len
== 0)
1756 push (spnt
->VMS_type
, -1);
1757 push (DBG_S_C_BASIC
, -1);
1759 push (total_len
, -2);
1763 push (DST_K_VFLAGS_DSC
, -1);
1764 push (DST_K_TS_DSC
, -1); /* descriptor type specification */
1770 struct_number
= spnt
->struc_numb
;
1771 if (struct_number
< 0)
1773 new_forward_ref (spnt
->dbx_type
);
1776 push (DBG_S_C_STRUCT
, -1);
1778 push (total_len
, -2);
1781 spnt1
= find_symbol (spnt
->type2
);
1784 new_forward_ref (spnt
->type2
);
1786 i
= gen1 (spnt1
, 0);
1788 { /* (*void) is a special case, do not put pointer suffix*/
1789 push (DBG_S_C_POINTER
, -1);
1791 push (total_len
, -2);
1796 while (spnt1
->advanced
== ARRAY
)
1798 spnt1
= find_symbol (spnt1
->type2
);
1801 as_tsktsk ("debugger forward reference error, dbx type %d",
1806 /* It is too late to generate forward references, so the user gets a message.
1807 * This should only happen on a compiler error */
1808 i
= gen1 (spnt1
, 1);
1810 array_suffix (spnt
);
1811 array_suffix_len
= Apoint
- i
;
1812 switch (spnt1
->advanced
)
1820 push (total_len
, -2);
1821 push (DST_K_VFLAGS_DSC
, -1);
1822 push (1, -1); /* flags: element value spec included */
1823 push (1, -1); /* one dimension */
1824 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1826 total_len
+= array_suffix_len
+ 8;
1827 push (total_len
, -2);
1831 /* This generates a suffix for a variable. If it is not a defined type yet,
1832 * then dbx_type contains the type we are expecting so we can generate a
1833 * forward reference. This calls gen1 to build most of the descriptor, and
1834 * then it puts the icing on at the end. It then dumps whatever is needed
1835 * to get a complete descriptor (i.e. struct reference, array suffix ).
1838 generate_suffix (spnt
, dbx_type
)
1839 struct VMS_DBG_Symbol
*spnt
;
1842 static CONST
char pvoid
[6] = {
1843 5, /* record.length == 5 */
1844 DST_K_TYPSPEC
, /* record.type == 1 (type specification) */
1845 0, /* name.length == 0, no name follows */
1846 1, 0, /* type.length == 1 {2 bytes, little endian} */
1847 DBG_S_C_VOID
/* type.type == 5 (pointer to unspecified) */
1851 struct VMS_DBG_Symbol
*spnt1
;
1853 Lpnt
= MAX_DEBUG_RECORD
- 1;
1858 new_forward_ref (dbx_type
);
1861 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1862 return 0; /* no suffix needed */
1865 push (0, -1); /* no name (len==0) */
1866 push (DST_K_TYPSPEC
, -1);
1868 push (total_len
, -1);
1869 /* if the variable descriptor overflows the record, output a descriptor for
1870 * a pointer to void.
1872 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1874 as_warn ("Variable descriptor %d too complicated. Defined as void*", spnt
->dbx_type
);
1875 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1879 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1880 Local
[i
++] = Local
[++Lpnt
];
1882 /* we use this for a reference to a structure that has already been defined */
1883 if (struct_number
> 0)
1885 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1887 VMS_Store_Struct (struct_number
);
1889 /* we use this for a forward reference to a structure that has yet to be
1890 *defined. We store four bytes of zero to make room for the actual address once
1893 if (struct_number
< 0)
1895 struct_number
= -struct_number
;
1896 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1898 VMS_Def_Struct (struct_number
);
1899 COPY_LONG(&Local
[Lpnt
], 0L);
1901 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1906 Local
[Lpnt
++] = Asuffix
[i
++];
1908 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1912 /* "novel length" type doesn't work for simple atomic types */
1913 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
1914 #undef SETUP_BASIC_TYPES
1917 bitfield_suffix (spnt
, width
)
1918 struct VMS_DBG_Symbol
*spnt
;
1921 Local
[Lpnt
++] = 13; /* rec.len==13 */
1922 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* a type specification record */
1923 Local
[Lpnt
++] = 0; /* not named */
1924 COPY_SHORT(&Local
[Lpnt
], 9); /* typ.len==9 */
1926 Local
[Lpnt
++] = DST_K_TS_NOV_LENG
; /* This type is a "novel length"
1927 incarnation of some other type. */
1928 COPY_LONG(&Local
[Lpnt
], width
); /* size in bits == novel length */
1930 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1932 /* assert( spnt->struc_numb > 0 ); */
1933 VMS_Store_Struct (spnt
->struc_numb
); /* output 4 more bytes */
1936 /* Formally define a builtin type, so that it can serve as the target of
1937 an indirect reference. It makes bitfield_suffix() easier by avoiding
1938 the need to use a forward reference for the first occurrence of each
1939 type used in a bitfield. */
1941 setup_basic_type (spnt
)
1942 struct VMS_DBG_Symbol
*spnt
;
1944 #ifdef SETUP_BASIC_TYPES
1945 /* This would be very useful if "novel length" fields actually worked
1946 with basic types like they do with enumerated types. However,
1947 they do not, so this isn't worth doing just so that you can use
1948 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
1950 #ifndef SETUP_SYNONYM_TYPES
1951 /* This determines whether compatible things like `int' and `long int'
1952 ought to have distinct type records rather than sharing one. */
1953 struct VMS_DBG_Symbol
*spnt2
;
1955 /* first check whether this type has already been seen by another name */
1956 for (spnt2
= VMS_Symbol_type_list
; spnt2
; spnt2
= spnt2
->next
)
1957 if (spnt2
!= spnt
&& spnt2
->VMS_type
== spnt
->VMS_type
)
1959 spnt
->struc_numb
= spnt2
->struc_numb
;
1964 /* `structure number' doesn't really mean `structure'; it means an index
1965 into a linker maintained set of saved locations which can be referenced
1967 spnt
->struc_numb
= ++structure_count
;
1968 VMS_Def_Struct (spnt
->struc_numb
); /* remember where this type lives */
1969 /* define the simple scalar type */
1970 Local
[Lpnt
++] = 6 + strlen (symbol_name
) + 2; /* rec.len */
1971 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* rec.typ==type specification */
1972 Local
[Lpnt
++] = strlen (symbol_name
) + 2;
1973 Local
[Lpnt
++] = '_'; /* prefix name with "__" */
1974 Local
[Lpnt
++] = '_';
1975 for (p
= symbol_name
; *p
; p
++)
1976 Local
[Lpnt
++] = *p
== ' ' ? '_' : *p
;
1977 COPY_SHORT(&Local
[Lpnt
], 2); /* typ.len==2 */
1979 Local
[Lpnt
++] = DST_K_TS_ATOM
; /* typ.kind is simple type */
1980 Local
[Lpnt
++] = spnt
->VMS_type
; /* typ.type */
1981 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1983 #endif /* SETUP_BASIC_TYPES */
1986 /* This routine generates a symbol definition for a C symbol for the debugger.
1987 * It takes a psect and offset for global symbols; if psect < 0, then this is
1988 * a local variable and the offset is relative to FP. In this case it can
1989 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1992 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1993 struct VMS_DBG_Symbol
*spnt
;
2004 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
2005 len
= strlen(Name_pnt
);
2007 { /* this is a local variable, referenced to SP */
2008 Local
[i
++] = 7 + len
;
2009 Local
[i
++] = spnt
->VMS_type
;
2010 Local
[i
++] = (Offset
> 0) ? DBG_C_FUNCTION_PARAM
: DBG_C_LOCAL_SYM
;
2011 COPY_LONG (&Local
[i
], Offset
);
2016 Local
[i
++] = 7 + len
;
2017 Local
[i
++] = spnt
->VMS_type
;
2018 Local
[i
++] = DST_K_VALKIND_ADDR
;
2019 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2021 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2024 while (*Name_pnt
!= '\0')
2025 Local
[i
++] = *Name_pnt
++;
2026 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2027 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2028 generate_suffix (spnt
, 0);
2032 /* This routine parses the stabs entries in order to make the definition
2033 * for the debugger of local symbols and function parameters
2036 VMS_local_stab_Parse (sp
)
2042 struct VMS_DBG_Symbol
*spnt
;
2043 struct VMS_Symbol
*vsp
;
2046 str
= S_GET_NAME (sp
);
2047 pnt
= (char *) strchr (str
, ':');
2048 if (pnt
== (char *) NULL
)
2049 return; /* no colon present */
2050 pnt1
= pnt
++; /* save this for later, and skip colon */
2052 return 0; /* ignore static constants */
2053 /* there is one little catch that we must be aware of. Sometimes function
2054 * parameters are optimized into registers, and the compiler, in its infiite
2055 * wisdom outputs stabs records for *both*. In general we want to use the
2056 * register if it is present, so we must search the rest of the symbols for
2057 * this function to see if this parameter is assigned to a register.
2065 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2067 if (!S_IS_DEBUG (sp1
))
2069 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2071 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2072 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2074 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2076 str1
= S_GET_NAME (sp1
); /* and get the name */
2078 while (*pnt2
!= ':')
2085 if ((*str1
!= ':') || (*pnt2
!= ':'))
2087 return; /* they are the same! lets skip this one */
2089 /* first find the dbx symbol type from list, and then find VMS type */
2090 pnt
++; /* skip p in case no register */
2093 pnt
= cvt_integer (pnt
, &dbx_type
);
2094 spnt
= find_symbol (dbx_type
);
2096 return 0; /*Dunno what this is*/
2098 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2099 *pnt1
= ':'; /* and restore the string */
2103 /* This routine parses a stabs entry to find the information required to define
2104 * a variable. It is used for global and static variables.
2105 * Basically we need to know the address of the symbol. With older versions
2106 * of the compiler, const symbols are
2107 * treated differently, in that if they are global they are written into the
2108 * text psect. The global symbol entry for such a const is actually written
2109 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2110 * of psects, we must search the entry points as well. static consts are even
2111 * harder, since they are never assigned a memory address. The compiler passes
2112 * a stab to tell us the value, but I am not sure what to do with it.
2116 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2119 int type1
, type2
, Text_Psect
;
2125 struct VMS_DBG_Symbol
*spnt
;
2126 struct VMS_Symbol
*vsp
;
2129 str
= S_GET_NAME (sp
);
2130 pnt
= (char *) strchr (str
, ':');
2131 if (pnt
== (char *) NULL
)
2132 return; /* no colon present */
2133 pnt1
= pnt
; /* save this for later*/
2135 if (*pnt
== expected_type
)
2137 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2138 spnt
= find_symbol (dbx_type
);
2139 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2140 return 0; /*Dunno what this is*/
2141 /* now we need to search the symbol table to find the psect and offset for
2146 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2148 pnt
= S_GET_NAME (vsp
->Symbol
);
2149 if (pnt
!= (char *) NULL
)
2151 /* make sure name is the same, and make sure correct symbol type */
2152 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2153 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2154 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2158 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2160 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2161 *pnt1
= ':'; /* and restore the string */
2164 /* the symbol was not in the symbol list, but it may be an "entry point"
2165 if it was a constant */
2166 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2169 * Dispatch on STAB type
2171 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2173 pnt
= S_GET_NAME (sp1
);
2176 if (strcmp (pnt
, str
) == 0)
2178 if (!gave_compiler_message
&& expected_type
== 'G')
2180 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2181 printf ("global constant(s) in the text psect. These will not be available to\n");
2182 printf ("other modules, since this is not the correct way to handle this. You\n");
2183 printf ("have two options: 1) get a patched compiler that does not put global\n");
2184 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2185 printf ("definitions of global variables in your source module(s). Don't say\n");
2186 printf ("I didn't warn you!");
2187 gave_compiler_message
= 1;
2189 VMS_DBG_record (spnt
,
2194 *S_GET_NAME (sp1
) = 'L';
2195 /* fool assembler to not output this
2196 * as a routine in the TBT */
2201 *pnt1
= ':'; /* and restore the string */
2206 VMS_GSYM_Parse (sp
, Text_Psect
)
2209 { /* Global variables */
2210 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2215 VMS_LCSYM_Parse (sp
, Text_Psect
)
2218 { /* Static symbols - uninitialized */
2219 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2223 VMS_STSYM_Parse (sp
, Text_Psect
)
2226 { /* Static symbols - initialized */
2227 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2231 /* for register symbols, we must figure out what range of addresses within the
2232 * psect are valid. We will use the brackets in the stab directives to give us
2233 * guidance as to the PC range that this variable is in scope. I am still not
2234 * completely comfortable with this but as I learn more, I seem to get a better
2235 * handle on what is going on.
2239 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2240 symbolS
*sp
, *Current_Routine
;
2247 struct VMS_DBG_Symbol
*spnt
;
2252 int Min_Offset
= -1; /* min PC of validity */
2253 int Max_Offset
= 0; /* max PC of validity */
2256 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2259 * Dispatch on STAB type
2261 switch (S_GET_RAW_TYPE (symbolP
))
2265 Min_Offset
= S_GET_VALUE (symbolP
);
2270 S_GET_VALUE (symbolP
) - 1;
2273 if ((Min_Offset
!= -1) && (bcnt
== 0))
2275 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2277 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2278 if (*pnt
== 'F' || *pnt
== 'f') break;
2281 /* check to see that the addresses were defined. If not, then there were no
2282 * brackets in the function, and we must try to search for the next function
2283 * Since functions can be in any order, we should search all of the symbol list
2284 * to find the correct ending address. */
2285 if (Min_Offset
== -1)
2287 int Max_Source_Offset
;
2289 Min_Offset
= S_GET_VALUE (sp
);
2290 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2293 * Dispatch on STAB type
2295 This_Offset
= S_GET_VALUE (symbolP
);
2296 switch (S_GET_RAW_TYPE (symbolP
))
2298 case N_TEXT
| N_EXT
:
2299 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2300 Max_Offset
= This_Offset
;
2303 if (This_Offset
> Max_Source_Offset
)
2304 Max_Source_Offset
= This_Offset
;
2307 /* if this is the last routine, then we use the PC of the last source line
2308 * as a marker of the max PC for which this reg is valid */
2309 if (Max_Offset
== 0x7fffffff)
2310 Max_Offset
= Max_Source_Offset
;
2313 str
= S_GET_NAME (sp
);
2314 pnt
= (char *) strchr (str
, ':');
2315 if (pnt
== (char *) NULL
)
2316 return; /* no colon present */
2317 pnt1
= pnt
; /* save this for later*/
2321 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2322 spnt
= find_symbol (dbx_type
);
2324 return 0; /*Dunno what this is yet*/
2326 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2328 Local
[i
++] = 25 + len
;
2329 Local
[i
++] = spnt
->VMS_type
;
2330 Local
[i
++] = DST_K_VFLAGS_TVS
; /* trailing value specified */
2331 COPY_LONG(&Local
[i
], 1 + len
); /* relative offset, beyond name */
2333 Local
[i
++] = len
; /* name length (ascic prefix) */
2334 while (*pnt
!= '\0')
2335 Local
[i
++] = *pnt
++;
2336 Local
[i
++] = DST_K_VS_FOLLOWS
; /* value specification follows */
2337 COPY_SHORT(&Local
[i
], 15); /* length of rest of record */
2339 Local
[i
++] = DST_K_VS_ALLOC_SPLIT
; /* split lifetime */
2340 Local
[i
++] = 1; /* one binding follows */
2341 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2343 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2344 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2345 Local
[i
++] = DST_K_VALKIND_REG
; /* nested value spec */
2346 COPY_LONG(&Local
[i
], S_GET_VALUE (sp
));
2348 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2350 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2351 generate_suffix (spnt
, 0);
2354 /* this function examines a structure definition, checking all of the elements
2355 * to make sure that all of them are fully defined. The only thing that we
2356 * kick out are arrays of undefined structs, since we do not know how big
2357 * they are. All others we can handle with a normal forward reference.
2360 forward_reference (pnt
)
2364 struct VMS_DBG_Symbol
*spnt
;
2365 struct VMS_DBG_Symbol
*spnt1
;
2366 pnt
= cvt_integer (pnt
+ 1, &i
);
2368 return 0; /* no forward references */
2371 pnt
= (char *) strchr (pnt
, ':');
2372 pnt
= cvt_integer (pnt
+ 1, &i
);
2373 spnt
= find_symbol (i
);
2374 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2375 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2378 spnt1
= find_symbol (spnt
->type2
);
2379 if ((spnt
->advanced
== ARRAY
) &&
2380 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2382 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2387 pnt
= cvt_integer (pnt
+ 1, &i
);
2388 pnt
= cvt_integer (pnt
+ 1, &i
);
2389 } while (*++pnt
!= ';');
2390 return 0; /* no forward refences found */
2393 /* Used to check a single element of a structure on the final pass*/
2396 final_forward_reference (spnt
)
2397 struct VMS_DBG_Symbol
*spnt
;
2399 struct VMS_DBG_Symbol
*spnt1
;
2401 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2403 spnt1
= find_symbol(spnt
->type2
);
2404 if (spnt
->advanced
== ARRAY
&& !spnt1
) return 1;
2407 return 0; /* no forward refences found */
2410 /* This routine parses the stabs directives to find any definitions of dbx type
2411 * numbers. It makes a note of all of them, creating a structure element
2412 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2413 * debugger that describes the struct/union/enum, so that further references
2414 * to these data types will be by number
2415 * We have to process pointers right away, since there can be references
2416 * to them later in the same stabs directive. We cannot have forward
2417 * references to pointers, (but we can have a forward reference to a pointer to
2418 * a structure/enum/union) and this is why we process them immediately.
2419 * After we process the pointer, then we search for defs that are nested even
2421 * 8/15/92: We have to process arrays right away too, because there can
2422 * be multiple references to identical array types in one structure
2423 * definition, and only the first one has the definition. (We tend to
2424 * parse from the back going forward.
2427 VMS_typedef_parse (str
)
2435 struct forward_ref
*fpnt
;
2436 int i1
, i2
, i3
, len
;
2437 int convert_integer
;
2438 struct VMS_DBG_Symbol
*spnt
;
2439 struct VMS_DBG_Symbol
*spnt1
;
2441 /* check for any nested def's */
2442 pnt
= (char *) strchr (str
+ 1, '=');
2443 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2444 && (str
[1] != 'a' || str
[2] != 'r'))
2445 if (VMS_typedef_parse (pnt
) == 1)
2447 /* now find dbx_type of entry */
2450 { /* check for static constants */
2451 *str
= '\0'; /* for now we ignore them */
2454 while ((*pnt
<= '9') && (*pnt
>= '0'))
2456 pnt
++; /* and get back to the number */
2457 cvt_integer (pnt
, &i1
);
2458 spnt
= find_symbol (i1
);
2459 /* first we see if this has been defined already, due to a forward reference*/
2462 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2463 spnt
->next
= VMS_Symbol_type_list
;
2464 VMS_Symbol_type_list
= spnt
;
2465 spnt
->dbx_type
= i1
; /* and save the type */
2466 spnt
->type2
= spnt
->VMS_type
= spnt
->data_size
= 0;
2467 spnt
->index_min
= spnt
->index_max
= spnt
->struc_numb
= 0;
2469 /* for structs and unions, do a partial parse, otherwise we sometimes get
2470 * circular definitions that are impossible to resolve. We read enough info
2471 * so that any reference to this type has enough info to be resolved
2473 pnt
= str
+ 1; /* point to character past equal sign */
2474 if ((*pnt
== 'u') || (*pnt
== 's'))
2477 if ((*pnt
<= '9') && (*pnt
>= '0'))
2479 if (type_check ("void"))
2480 { /* this is the void symbol */
2482 spnt
->advanced
= VOID
;
2485 if (type_check ("unknown type"))
2488 spnt
->advanced
= UNKNOWN
;
2491 pnt1
= cvt_integer(pnt
,&i1
);
2492 if(i1
!= spnt
->dbx_type
)
2494 spnt
->advanced
= ALIAS
;
2499 as_tsktsk ("debugginer output: %d is an unknown untyped variable.",
2501 return 1; /* do not know what this is */
2503 /* now define this module*/
2504 pnt
= str
+ 1; /* point to character past equal sign */
2508 spnt
->advanced
= BASIC
;
2509 if (type_check ("int"))
2511 spnt
->VMS_type
= DBG_S_C_SLINT
;
2512 spnt
->data_size
= 4;
2514 else if (type_check ("long int"))
2516 spnt
->VMS_type
= DBG_S_C_SLINT
;
2517 spnt
->data_size
= 4;
2519 else if (type_check ("unsigned int"))
2521 spnt
->VMS_type
= DBG_S_C_ULINT
;
2522 spnt
->data_size
= 4;
2524 else if (type_check ("long unsigned int"))
2526 spnt
->VMS_type
= DBG_S_C_ULINT
;
2527 spnt
->data_size
= 4;
2529 else if (type_check ("short int"))
2531 spnt
->VMS_type
= DBG_S_C_SSINT
;
2532 spnt
->data_size
= 2;
2534 else if (type_check ("short unsigned int"))
2536 spnt
->VMS_type
= DBG_S_C_USINT
;
2537 spnt
->data_size
= 2;
2539 else if (type_check ("char"))
2541 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2542 spnt
->data_size
= 1;
2544 else if (type_check ("signed char"))
2546 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2547 spnt
->data_size
= 1;
2549 else if (type_check ("unsigned char"))
2551 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2552 spnt
->data_size
= 1;
2554 else if (type_check ("float"))
2556 spnt
->VMS_type
= DBG_S_C_REAL4
;
2557 spnt
->data_size
= 4;
2559 else if (type_check ("double"))
2561 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2562 spnt
->data_size
= 8;
2564 else if (type_check ("long double"))
2566 /* same as double, at least for now */
2567 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2568 spnt
->data_size
= 8;
2570 else if (type_check ("long long int"))
2572 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2573 spnt
->data_size
= 8;
2575 else if (type_check ("long long unsigned int"))
2577 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2578 spnt
->data_size
= 8;
2580 else if (type_check ("complex float"))
2582 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2583 spnt
->data_size
= 2 * 4;
2585 else if (type_check ("complex double"))
2587 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2588 spnt
->data_size
= 2 * 8;
2590 else if (type_check ("complex long double"))
2592 /* same as complex double, at least for now */
2593 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2594 spnt
->data_size
= 2 * 8;
2599 * Shouldn't get here, but if we do, something
2600 * more substantial ought to be done...
2603 spnt
->data_size
= 0;
2605 if (spnt
->VMS_type
!= 0)
2606 setup_basic_type(spnt
);
2607 pnt1
= (char *) strchr (str
, ';') + 1;
2611 spnt
->advanced
= (*pnt
== 's') ? STRUCT
: UNION
;
2612 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2613 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2614 if (!final_pass
&& forward_reference(pnt
))
2616 spnt
->struc_numb
= -1;
2619 spnt
->struc_numb
= ++structure_count
;
2621 pnt
= get_struct_name (str
);
2622 VMS_Def_Struct (spnt
->struc_numb
);
2624 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2625 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2627 fpnt
->resolved
= 'Y';
2628 VMS_Set_Struct (fpnt
->struc_numb
);
2629 VMS_Store_Struct (spnt
->struc_numb
);
2633 VMS_Set_Struct (spnt
->struc_numb
);
2635 Local
[i
++] = 11 + strlen (pnt
);
2636 Local
[i
++] = DBG_S_C_STRUCT_START
;
2637 Local
[i
++] = DST_K_VFLAGS_NOVAL
; /* structure definition only */
2638 COPY_LONG(&Local
[i
], 0L); /* hence value is unused */
2640 Local
[i
++] = strlen (pnt
);
2642 while (*pnt2
!= '\0')
2643 Local
[i
++] = *pnt2
++;
2644 i2
= spnt
->data_size
* 8; /* number of bits */
2645 COPY_LONG(&Local
[i
], i2
);
2647 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2649 if (pnt
!= symbol_name
)
2651 pnt
+= strlen (pnt
);
2653 } /* replace colon for later */
2654 while (*++pnt1
!= ';')
2656 pnt
= (char *) strchr (pnt1
, ':');
2659 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2660 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2661 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2662 spnt1
= find_symbol (dtype
);
2663 len
= strlen (pnt2
);
2664 if (spnt1
&& (spnt1
->advanced
== BASIC
|| spnt1
->advanced
== ENUM
)
2665 && ((i3
!= spnt1
->data_size
* 8) || (i2
% 8 != 0)))
2667 if (USE_BITSTRING_DESCRIPTOR (spnt1
))
2669 /* This uses a type descriptor, which doesn't work if
2670 the enclosing structure has been placed in a register.
2671 Also, enum bitfields degenerate to simple integers. */
2672 int unsigned_type
= (spnt1
->VMS_type
== DBG_S_C_ULINT
2673 || spnt1
->VMS_type
== DBG_S_C_USINT
2674 || spnt1
->VMS_type
== DBG_S_C_UCHAR
2675 || spnt1
->VMS_type
== DBG_S_C_UQUAD
2676 || spnt1
->advanced
== ENUM
); /* (approximate) */
2679 push (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2680 push (DST_K_VFLAGS_DSC
, 1); /* specified by descriptor */
2681 push (1 + len
, 4); /* relative offset to descriptor */
2682 push (len
, 1); /* length byte (ascic prefix) */
2683 while (*pnt2
!= '\0') /* name bytes */
2685 push (i3
, 2); /* dsc length == size of bitfield */
2686 /* dsc type == un?signed bitfield */
2687 push (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2688 push (DSC_K_CLASS_UBS
, 1); /* dsc class == unaligned bitstring */
2689 push (0x00, 4); /* dsc pointer == zeroes */
2690 push (i2
, 4); /* start position */
2691 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2696 /* Use a "novel length" type specification, which works
2697 right for register structures and for enum bitfields
2698 but results in larger object modules. */
2699 Local
[i
++] = 7 + len
;
2700 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
; /* type spec follows */
2701 Local
[i
++] = DBG_S_C_STRUCT_ITEM
; /* value is a bit offset */
2702 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2704 Local
[i
++] = strlen (pnt2
);
2705 while (*pnt2
!= '\0')
2706 Local
[i
++] = *pnt2
++;
2707 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2709 bitfield_suffix (spnt1
, i3
);
2713 { /* not a bitfield */
2714 /* check if this is a forward reference */
2715 if(final_pass
&& final_forward_reference(spnt1
))
2717 as_tsktsk ("debugger output: structure element `%s' has undefined type",
2721 Local
[i
++] = 7 + len
;
2722 Local
[i
++] = spnt1
? spnt1
->VMS_type
: DBG_S_C_ADVANCED_TYPE
;
2723 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2724 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2726 Local
[i
++] = strlen (pnt2
);
2727 while (*pnt2
!= '\0')
2728 Local
[i
++] = *pnt2
++;
2729 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2732 generate_suffix (spnt1
, dtype
);
2733 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2734 generate_suffix (spnt1
, 0);
2738 Local
[i
++] = 0x01; /* length byte */
2739 Local
[i
++] = DBG_S_C_STRUCT_END
;
2740 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2744 spnt
->advanced
= ENUM
;
2745 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2746 spnt
->struc_numb
= ++structure_count
;
2747 spnt
->data_size
= 4;
2748 VMS_Def_Struct (spnt
->struc_numb
);
2750 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2751 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2753 fpnt
->resolved
= 'Y';
2754 VMS_Set_Struct (fpnt
->struc_numb
);
2755 VMS_Store_Struct (spnt
->struc_numb
);
2759 VMS_Set_Struct (spnt
->struc_numb
);
2761 len
= strlen (symbol_name
);
2762 Local
[i
++] = 3 + len
;
2763 Local
[i
++] = DBG_S_C_ENUM_START
;
2764 Local
[i
++] = 4 * 8; /* enum values are 32 bits */
2767 while (*pnt2
!= '\0')
2768 Local
[i
++] = *pnt2
++;
2769 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2771 while (*++pnt
!= ';')
2773 pnt1
= (char *) strchr (pnt
, ':');
2775 pnt1
= cvt_integer (pnt1
, &i1
);
2777 Local
[i
++] = 7 + len
;
2778 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2779 Local
[i
++] = DST_K_VALKIND_LITERAL
;
2780 COPY_LONG (&Local
[i
], i1
);
2784 while (*pnt
!= '\0')
2785 Local
[i
++] = *pnt
++;
2786 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2788 pnt
= pnt1
; /* Skip final semicolon */
2790 Local
[i
++] = 0x01; /* len byte */
2791 Local
[i
++] = DBG_S_C_ENUM_END
;
2792 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2797 spnt
->advanced
= ARRAY
;
2798 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2799 pnt
= (char *) strchr (pnt
, ';');
2800 if (pnt
== (char *) NULL
)
2802 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2803 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2804 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2805 pnt
=(char*)strchr(str
+1,'=');
2806 if((pnt
!= (char*) NULL
))
2807 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2810 spnt
->advanced
= FUNCTION
;
2811 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2812 /* this masquerades as a basic type*/
2813 spnt
->data_size
= 4;
2814 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2817 spnt
->advanced
= POINTER
;
2818 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2819 spnt
->data_size
= 4;
2820 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2821 pnt
= (char *) strchr (str
+ 1, '=');
2822 if ((pnt
!= (char *) NULL
))
2823 if (VMS_typedef_parse (pnt
) == 1)
2827 spnt
->advanced
= UNKNOWN
;
2829 as_tsktsk ("debugger output: %d is an unknown type of variable.",
2831 return 1; /* unable to decipher */
2833 /* this removes the evidence of the definition so that the outer levels of
2834 parsing do not have to worry about it */
2836 while (*pnt1
!= '\0')
2844 * This is the root routine that parses the stabs entries for definitions.
2845 * it calls VMS_typedef_parse, which can in turn call itself.
2846 * We need to be careful, since sometimes there are forward references to
2847 * other symbol types, and these cannot be resolved until we have completed
2850 * Also check and see if we are using continuation stabs, if we are, then
2851 * paste together the entire contents of the stab before we pass it to
2852 * VMS_typedef_parse.
2861 char *parse_buffer
= 0;
2863 int incomplete
, i
, pass
, incom1
;
2864 struct VMS_DBG_Symbol
*spnt
;
2865 struct VMS_Symbol
*vsp
;
2866 struct forward_ref
*fpnt
;
2873 incom1
= incomplete
;
2875 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2878 * Deal with STAB symbols
2880 if (S_IS_DEBUG (sp
))
2883 * Dispatch on STAB type
2885 switch (S_GET_RAW_TYPE (sp
))
2893 case N_FUN
: /*sometimes these contain typedefs*/
2894 str
= S_GET_NAME (sp
);
2896 pnt
= str
+ strlen(str
) -1;
2897 if (*pnt
== '?') /* Continuation stab. */
2903 tlen
+= strlen(str
) - 1;
2904 spnext
= symbol_next (spnext
);
2905 str
= S_GET_NAME (spnext
);
2906 pnt
= str
+ strlen(str
) - 1;
2907 } while (*pnt
== '?');
2908 tlen
+= strlen(str
);
2909 parse_buffer
= (char *) xmalloc (tlen
+ 1);
2910 strcpy(parse_buffer
, S_GET_NAME (sp
));
2911 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2915 spnext
= symbol_next (spnext
);
2916 str
= S_GET_NAME (spnext
);
2917 strcat (pnt2
, S_GET_NAME (spnext
));
2918 pnt2
+= strlen(str
) - 1;
2919 *str
= '\0'; /* Erase this string */
2920 if (*pnt2
!= '?') break;
2926 pnt
= (char *) strchr (str
, ':');
2927 if (pnt
!= (char *) NULL
)
2931 pnt2
= (char *) strchr (pnt1
, '=');
2932 if (pnt2
!= (char *) NULL
)
2933 incomplete
+= VMS_typedef_parse (pnt2
);
2935 /* At this point the parse buffer should just contain name:nn.
2936 If it does not, then we are in real trouble. Anyway,
2937 this is always shorter than the original line. */
2938 strcpy(S_GET_NAME (sp
), parse_buffer
);
2939 free (parse_buffer
);
2942 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2949 /* Make one last pass, if needed, and define whatever we can that is left */
2950 if(final_pass
== 0 && incomplete
== incom1
)
2953 incom1
++; /* Force one last pass through */
2955 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2956 /* repeat until all refs resolved if possible */
2957 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2958 if (incomplete
!= 0)
2960 as_tsktsk ("debugger output: Unable to resolve %d circular references.",
2965 while (fpnt
!= (struct forward_ref
*) NULL
)
2967 if (fpnt
->resolved
!= 'Y')
2969 if (find_symbol (fpnt
->dbx_type
) !=
2970 (struct VMS_DBG_Symbol
*) NULL
)
2972 as_tsktsk ("debugger forward reference error, dbx type %d",
2977 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2978 pnt2
= (char *) strchr (&fixit
[1], '=');
2979 VMS_typedef_parse (pnt2
);
2986 Define_Local_Symbols (s1
, s2
)
2990 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2992 if (symbolP1
== (symbolS
*) NULL
)
2994 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2996 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2997 if (*pnt
== 'F' || *pnt
== 'f') break;
3000 * Deal with STAB symbols
3002 if (S_IS_DEBUG (symbolP1
))
3005 * Dispatch on STAB type
3007 switch (S_GET_RAW_TYPE (symbolP1
))
3011 VMS_local_stab_Parse (symbolP1
);
3014 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
3022 /* This function crawls the symbol chain searching for local symbols that need
3023 * to be described to the debugger. When we enter a new scope with a "{", it
3024 * creates a new "block", which helps the debugger keep track of which scope
3025 * we are currently in.
3029 Define_Routine (symbolP
, Level
)
3039 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
3041 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3043 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3044 if (*pnt
== 'F' || *pnt
== 'f') break;
3047 * Deal with STAB symbols
3049 if (S_IS_DEBUG (symbolP1
))
3052 * Dispatch on STAB type
3054 switch (S_GET_RAW_TYPE (symbolP1
))
3059 sprintf (str
, "$%d", rcount
++);
3060 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3062 Offset
= S_GET_VALUE (symbolP1
);
3063 Define_Local_Symbols (sstart
, symbolP1
);
3065 Define_Routine (symbolP1
, Level
+ 1);
3067 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3076 /* we end up here if there were no brackets in this function. Define
3078 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3084 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3086 symbolS
*Curr_Routine
;
3089 Current_Routine
= Curr_Routine
;
3090 Text_Psect
= Txt_Psect
;
3091 Define_Routine (symbolP
, 0);
3098 #include <sys/types.h>
3101 /* Manufacure a VMS like time on a unix based system. */
3102 get_VMS_time_on_unix (Now
)
3108 pnt
= ctime (&timeb
);
3114 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3117 #endif /* not VMS */
3119 * Write the MHD (Module Header) records
3122 Write_VMS_MHD_Records ()
3124 register char *cp
, *cp1
;
3131 char Module_Name
[256];
3135 * We are writing a module header record
3137 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3139 * ***************************
3140 * *MAIN MODULE HEADER RECORD*
3141 * ***************************
3143 * Store record type and header type
3145 PUT_CHAR (OBJ_S_C_HDR
);
3146 PUT_CHAR (MHD_S_C_MHD
);
3148 * Structure level is 0
3150 PUT_CHAR (OBJ_S_C_STRLVL
);
3152 * Maximum record size is size of the object record buffer
3154 PUT_SHORT (sizeof (Object_Record_Buffer
));
3156 * Get module name (the FILENAME part of the object file)
3162 if ((*cp
== ']') || (*cp
== '>') ||
3163 (*cp
== ':') || (*cp
== '/'))
3169 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3173 * Limit it to 31 characters and store in the object record
3175 while (--cp1
>= Module_Name
)
3178 if (strlen (Module_Name
) > 31)
3180 if (flag_hash_long_names
)
3181 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3182 Module_Name
[31] = 0;
3184 PUT_COUNTED_STRING (Module_Name
);
3186 * Module Version is "V1.0"
3188 PUT_COUNTED_STRING ("V1.0");
3190 * Creation time is "now" (17 chars of time string)
3193 get_VMS_time_on_unix (&Now
[0]);
3195 Descriptor
.Size
= 17;
3196 Descriptor
.Ptr
= Now
;
3197 sys$
asctim (0, &Descriptor
, 0, 0);
3199 for (i
= 0; i
< 17; i
++)
3202 * Patch time is "never" (17 zeros)
3204 for (i
= 0; i
< 17; i
++)
3209 Flush_VMS_Object_Record_Buffer ();
3211 * *************************
3212 * *LANGUAGE PROCESSOR NAME*
3213 * *************************
3215 * Store record type and header type
3217 PUT_CHAR (OBJ_S_C_HDR
);
3218 PUT_CHAR (MHD_S_C_LNM
);
3220 * Store language processor name and version
3221 * (not a counted string!)
3223 * This is normally supplied by the gcc driver for the command line
3224 * which invokes gas. If absent, we fall back to gas's version.
3226 cp
= compiler_version_string
;
3239 Flush_VMS_Object_Record_Buffer ();
3244 * Write the EOM (End Of Module) record
3247 Write_VMS_EOM_Record (Psect
, Offset
)
3252 * We are writing an end-of-module record
3254 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3258 PUT_CHAR (OBJ_S_C_EOM
);
3260 * Store the error severity (0)
3264 * Store the entry point, if it exists
3269 * Store the entry point Psect
3273 * Store the entry point Psect offset
3280 Flush_VMS_Object_Record_Buffer ();
3284 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3290 register unsigned char *p
= ptr
;
3291 register unsigned char *end
= p
+ strlen (ptr
);
3292 register unsigned char c
;
3293 register int hash
= 0;
3298 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3304 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3307 VMS_Case_Hack_Symbol (In
, Out
)
3317 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3319 int Case_Hack_Bits
= 0;
3321 static char Hex_Table
[16] =
3322 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3325 * Kill any leading "_"
3327 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3330 new_name
= Out
; /* save this for later*/
3332 #if barfoo /* Dead code */
3333 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3337 /* We may need to truncate the symbol, save the hash for later*/
3338 if (strlen (In
) > 23)
3339 result
= hash_string (In
);
3341 * Is there a Psect Attribute to skip??
3343 if (HAS_PSECT_ATTRIBUTES (In
))
3348 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3351 if ((In
[0] == '$') && (In
[1] == '$'))
3361 /* if (strlen(In) > 31 && flag_hash_long_names)
3362 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3364 * Do the case conversion
3366 i
= 23; /* Maximum of 23 chars */
3367 while (*In
&& (--i
>= 0))
3369 Case_Hack_Bits
<<= 1;
3372 if ((destructor
== 1) && (i
== 21))
3374 switch (vms_name_mapping
)
3379 Case_Hack_Bits
|= 1;
3381 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3384 case 3: *Out
++ = *In
++;
3390 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3396 * If we saw a dollar sign, we don't do case hacking
3398 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3402 * If we have more than 23 characters and everything is lowercase
3403 * we can insert the full 31 characters
3408 * We have more than 23 characters
3409 * If we must add the case hack, then we have truncated the str
3413 if (Case_Hack_Bits
== 0)
3416 * And so far they are all lower case:
3417 * Check up to 8 more characters
3418 * and ensure that they are lowercase
3420 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3421 if (isupper(In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3427 if ((i
== 8) || (In
[i
] == 0))
3430 * They are: Copy up to 31 characters
3431 * to the output string
3434 while ((--i
>= 0) && (*In
))
3435 switch (vms_name_mapping
){
3436 case 0: *Out
++ = islower(*In
) ?
3440 case 3: *Out
++ = *In
++;
3442 case 2: *Out
++ = isupper(*In
) ?
3451 * If there were any uppercase characters in the name we
3452 * take on the case hacking string
3455 /* Old behavior for regular GNU-C compiler */
3456 if (!flag_hash_long_names
)
3458 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3463 for (i
= 0; i
< 6; i
++)
3465 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3466 Case_Hack_Bits
>>= 4;
3472 Out
= pnt
; /*Cut back to 23 characters maximum */
3474 for (i
= 0; i
< 7; i
++)
3476 init
= result
& 0x01f;
3478 *Out
++ = '0' + init
;
3480 *Out
++ = 'A' + init
- 10;
3481 result
= result
>> 5;
3489 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3490 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3495 * Scan a symbol name for a psect attribute specification
3497 #define GLOBALSYMBOL_BIT 0x10000
3498 #define GLOBALVALUE_BIT 0x20000
3502 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3504 int *Attribute_Pointer
;
3515 {"PIC", GPS_S_M_PIC
},
3516 {"LIB", GPS_S_M_LIB
},
3517 {"OVR", GPS_S_M_OVR
},
3518 {"REL", GPS_S_M_REL
},
3519 {"GBL", GPS_S_M_GBL
},
3520 {"SHR", GPS_S_M_SHR
},
3521 {"EXE", GPS_S_M_EXE
},
3523 {"WRT", GPS_S_M_WRT
},
3524 {"VEC", GPS_S_M_VEC
},
3525 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3526 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3536 * Check for a PSECT attribute list
3538 if (!HAS_PSECT_ATTRIBUTES (Name
))
3539 return; /* If not, return */
3541 * Skip the attribute list indicator
3543 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3545 * Process the attributes ("_" separated, "$" terminated)
3547 while (*Name
!= '$')
3550 * Assume not negating
3556 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3559 * We are negating (and skip the NO)
3565 * Find the token delimiter
3568 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3571 * Look for the token in the attribute list
3573 for (i
= 0; Attributes
[i
].Name
; i
++)
3576 * If the strings match, set/clear the attr.
3578 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3584 *Attribute_Pointer
&=
3585 ~Attributes
[i
].Value
;
3587 *Attribute_Pointer
|=
3588 Attributes
[i
].Value
;
3596 * Now skip the attribute
3606 * Define a global symbol
3609 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3617 * We are writing a GSD record
3619 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3621 * If the buffer is empty we must insert the GSD record type
3623 if (Object_Record_Offset
== 0)
3624 PUT_CHAR (OBJ_S_C_GSD
);
3626 * We are writing a Global symbol definition subrecord
3628 if (Psect_Number
<= 255)
3630 PUT_CHAR (GSD_S_C_SYM
);
3634 PUT_CHAR (GSD_S_C_SYMW
);
3637 * Data type is undefined
3641 * Switch on Definition/Reference
3643 if ((Defined
& 1) != 0)
3647 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3648 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3650 if ((Defined
& 2) == 0)
3652 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3656 PUT_SHORT (GSY_S_M_DEF
);
3661 if (Psect_Number
<= 255)
3663 PUT_CHAR (Psect_Number
);
3667 PUT_SHORT (Psect_Number
);
3672 PUT_LONG (Psect_Offset
);
3678 * Flags = "RELOCATABLE" for regular symbol,
3679 * = "" for globalvalue (Defined & 2 == 1)
3681 if ((Defined
& 2) == 0)
3683 PUT_SHORT (GSY_S_M_REL
);
3691 * Finally, the global symbol name
3693 VMS_Case_Hack_Symbol (Name
, Local
);
3694 PUT_COUNTED_STRING (Local
);
3696 * Flush the buffer if it is more than 75% full
3698 if (Object_Record_Offset
>
3699 (sizeof (Object_Record_Buffer
) * 3 / 4))
3700 Flush_VMS_Object_Record_Buffer ();
3708 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3712 struct VMS_Symbol
*vsp
;
3715 int Psect_Attributes
;
3718 * Generate the appropriate PSECT flags given the PSECT type
3720 if (strcmp (Type
, "COMMON") == 0)
3723 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3725 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3726 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3728 else if (strcmp (Type
, "CONST") == 0)
3731 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3733 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3734 GPS_S_M_SHR
| GPS_S_M_RD
);
3736 else if (strcmp (Type
, "DATA") == 0)
3739 * The Data psects are PIC,REL,RD,WRT
3742 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3744 else if (strcmp (Type
, "TEXT") == 0)
3747 * The Text psects are PIC,REL,SHR,EXE,RD
3750 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3751 GPS_S_M_EXE
| GPS_S_M_RD
);
3756 * Error: Unknown psect type
3758 error ("Unknown VMS psect type");
3761 * Modify the psect attributes according to any attribute string
3763 if (HAS_PSECT_ATTRIBUTES (Name
))
3764 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3766 * Check for globalref/def/val.
3768 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3771 * globalvalue symbols were generated before. This code
3772 * prevents unsightly psect buildup, and makes sure that
3773 * fixup references are emitted correctly.
3775 vsp
->Psect_Index
= -1; /* to catch errors */
3776 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3777 return 1; /* decrement psect counter */
3780 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3782 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3784 case N_UNDF
| N_EXT
:
3785 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3786 vsp
->Psect_Offset
, 0);
3787 vsp
->Psect_Index
= -1;
3788 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3789 return 1; /* return and indicate no psect */
3790 case N_DATA
| N_EXT
:
3791 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3792 vsp
->Psect_Offset
, 1);
3793 /* In this case we still generate the psect */
3796 as_fatal ("Globalsymbol attribute for symbol %s was unexpected.",
3802 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3804 * We are writing a GSD record
3806 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3808 * If the buffer is empty we must insert the GSD record type
3810 if (Object_Record_Offset
== 0)
3811 PUT_CHAR (OBJ_S_C_GSD
);
3813 * We are writing a PSECT definition subrecord
3815 PUT_CHAR (GSD_S_C_PSC
);
3817 * Psects are always LONGWORD aligned
3821 * Specify the psect attributes
3823 PUT_SHORT (Psect_Attributes
);
3825 * Specify the allocation
3829 * Finally, the psect name
3831 VMS_Case_Hack_Symbol (Name
, Local
);
3832 PUT_COUNTED_STRING (Local
);
3834 * Flush the buffer if it is more than 75% full
3836 if (Object_Record_Offset
>
3837 (sizeof (Object_Record_Buffer
) * 3 / 4))
3838 Flush_VMS_Object_Record_Buffer ();
3844 * Given the pointer to a symbol we calculate how big the data at the
3845 * symbol is. We do this by looking for the next symbol (local or
3846 * global) which will indicate the start of another datum.
3849 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3850 register struct symbol
*sp
;
3853 struct symbol
*sp1
, *Next_Symbol
;
3854 /* Cache values to avoid extra lookups. */
3855 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
;
3858 * Find the next symbol
3859 * it delimits this datum
3862 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3865 * The data type must match
3867 if (S_GET_TYPE (sp1
) != N_DATA
)
3870 sp1_val
= S_GET_VALUE (sp1
);
3873 * The symbol must be AFTER this symbol
3875 if (sp1_val
<= sp_val
)
3878 * We ignore THIS symbol
3883 * If there is already a candidate selected for the
3884 * next symbol, see if we are a better candidate
3889 * We are a better candidate if we are "closer"
3892 if (sp1_val
> next_val
)
3896 * Make this the candidate
3902 * Calculate its size
3904 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
3908 * Check symbol names for the Psect hack with a globalvalue, and then
3909 * generate globalvalues for those that have it.
3912 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3917 register symbolS
*sp
;
3918 char *stripped_name
, *Name
;
3920 int Psect_Attributes
;
3924 * Scan the symbol table for globalvalues, and emit def/ref when
3925 * required. These will be caught again later and converted to
3928 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3931 * See if this is something we want to look at.
3933 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3934 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3937 * See if this has globalvalue specification.
3939 Name
= S_GET_NAME (sp
);
3941 if (!HAS_PSECT_ATTRIBUTES (Name
))
3944 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
3945 strcpy (stripped_name
, Name
);
3946 Psect_Attributes
= 0;
3947 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3949 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3951 switch (S_GET_RAW_TYPE (sp
))
3953 case N_UNDF
| N_EXT
:
3954 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3956 case N_DATA
| N_EXT
:
3957 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3959 error ("Invalid data type for globalvalue");
3960 globalvalue
= md_chars_to_number (Data_Segment
+
3961 S_GET_VALUE (sp
) - text_siz
, Size
);
3962 /* Three times for good luck. The linker seems to get confused
3963 if there are fewer than three */
3964 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3965 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3966 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3969 as_tsktsk ("Invalid globalvalue of %s", stripped_name
);
3973 free (stripped_name
); /* clean up */
3980 * Define a procedure entry pt/mask
3983 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3992 * We are writing a GSD record
3994 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3996 * If the buffer is empty we must insert the GSD record type
3998 if (Object_Record_Offset
== 0)
3999 PUT_CHAR (OBJ_S_C_GSD
);
4001 * We are writing a Procedure Entry Pt/Mask subrecord
4003 if (Psect_Number
<= 255)
4005 PUT_CHAR (GSD_S_C_EPM
);
4009 PUT_CHAR (GSD_S_C_EPMW
);
4012 * Data type is undefined
4016 * Flags = "RELOCATABLE" and "DEFINED"
4018 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4022 if (Psect_Number
<= 255)
4024 PUT_CHAR (Psect_Number
);
4028 PUT_SHORT (Psect_Number
);
4033 PUT_LONG (Psect_Offset
);
4037 PUT_SHORT (Entry_Mask
);
4039 * Finally, the global symbol name
4041 VMS_Case_Hack_Symbol (Name
, Local
);
4042 PUT_COUNTED_STRING (Local
);
4044 * Flush the buffer if it is more than 75% full
4046 if (Object_Record_Offset
>
4047 (sizeof (Object_Record_Buffer
) * 3 / 4))
4048 Flush_VMS_Object_Record_Buffer ();
4053 * Set the current location counter to a particular Psect and Offset
4056 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4062 * We are writing a "Record_Type" record
4064 Set_VMS_Object_File_Record (Record_Type
);
4066 * If the buffer is empty we must insert the record type
4068 if (Object_Record_Offset
== 0)
4069 PUT_CHAR (Record_Type
);
4071 * Stack the Psect base + Longword Offset
4073 if (Psect_Index
< 255)
4075 PUT_CHAR (TIR_S_C_STA_PL
);
4076 PUT_CHAR (Psect_Index
);
4080 PUT_CHAR (TIR_S_C_STA_WPL
);
4081 PUT_SHORT (Psect_Index
);
4085 * Set relocation base
4087 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4089 * Flush the buffer if it is more than 75% full
4091 if (Object_Record_Offset
>
4092 (sizeof (Object_Record_Buffer
) * 3 / 4))
4093 Flush_VMS_Object_Record_Buffer ();
4098 * Store repeated immediate data in current Psect
4101 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4103 register char *Pointer
;
4109 * Ignore zero bytes/words/longwords
4118 if (Pointer
[1] != 0)
4121 if (Pointer
[0] != 0)
4130 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4131 * then we do it manually
4135 while (--Repeat_Count
>= 0)
4136 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4140 * We are writing a "Record_Type" record
4142 Set_VMS_Object_File_Record (Record_Type
);
4144 * If the buffer is empty we must insert record type
4146 if (Object_Record_Offset
== 0)
4147 PUT_CHAR (Record_Type
);
4149 * Stack the repeat count
4151 PUT_CHAR (TIR_S_C_STA_LW
);
4152 PUT_LONG (Repeat_Count
);
4154 * And now the command and its data
4156 PUT_CHAR (TIR_S_C_STO_RIVB
);
4159 PUT_CHAR (*Pointer
++);
4161 * Flush the buffer if it is more than 75% full
4163 if (Object_Record_Offset
>
4164 (sizeof (Object_Record_Buffer
) * 3 / 4))
4165 Flush_VMS_Object_Record_Buffer ();
4170 * Store a Position Independent Reference
4173 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4174 Psect
, Psect_Offset
, Record_Type
)
4175 struct symbol
*Symbol
;
4182 register struct VMS_Symbol
*vsp
= Symbol
->sy_obj
;
4186 * We are writing a "Record_Type" record
4188 Set_VMS_Object_File_Record (Record_Type
);
4190 * If the buffer is empty we must insert record type
4192 if (Object_Record_Offset
== 0)
4193 PUT_CHAR (Record_Type
);
4195 * Set to the appropriate offset in the Psect
4200 * For a Code reference we need to fix the operand
4201 * specifier as well (so back up 1 byte)
4203 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4208 * For a Data reference we just store HERE
4210 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4213 * Make sure we are still generating a "Record Type" record
4215 if (Object_Record_Offset
== 0)
4216 PUT_CHAR (Record_Type
);
4218 * Dispatch on symbol type (so we can stack its value)
4220 switch (S_GET_RAW_TYPE (Symbol
))
4225 #ifdef NOT_VAX_11_C_COMPATIBLE
4226 case N_UNDF
| N_EXT
:
4227 case N_DATA
| N_EXT
:
4228 #endif /* NOT_VAX_11_C_COMPATIBLE */
4230 case N_TEXT
| N_EXT
:
4232 * Get the symbol name (case hacked)
4234 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4236 * Stack the global symbol value
4238 PUT_CHAR (TIR_S_C_STA_GBL
);
4239 PUT_COUNTED_STRING (Local
);
4243 * Stack the longword offset
4245 PUT_CHAR (TIR_S_C_STA_LW
);
4248 * Add the two, leaving the result on the stack
4250 PUT_CHAR (TIR_S_C_OPR_ADD
);
4254 * Uninitialized local data
4258 * Stack the Psect (+offset)
4260 if (vsp
->Psect_Index
< 255)
4262 PUT_CHAR (TIR_S_C_STA_PL
);
4263 PUT_CHAR (vsp
->Psect_Index
);
4267 PUT_CHAR (TIR_S_C_STA_WPL
);
4268 PUT_SHORT (vsp
->Psect_Index
);
4270 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4277 * Stack the Psect (+offset)
4279 if (vsp
->Psect_Index
< 255)
4281 PUT_CHAR (TIR_S_C_STA_PL
);
4282 PUT_CHAR (vsp
->Psect_Index
);
4286 PUT_CHAR (TIR_S_C_STA_WPL
);
4287 PUT_SHORT (vsp
->Psect_Index
);
4289 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4292 * Initialized local or global data
4295 #ifndef NOT_VAX_11_C_COMPATIBLE
4296 case N_UNDF
| N_EXT
:
4297 case N_DATA
| N_EXT
:
4298 #endif /* NOT_VAX_11_C_COMPATIBLE */
4300 * Stack the Psect (+offset)
4302 if (vsp
->Psect_Index
< 255)
4304 PUT_CHAR (TIR_S_C_STA_PL
);
4305 PUT_CHAR (vsp
->Psect_Index
);
4309 PUT_CHAR (TIR_S_C_STA_WPL
);
4310 PUT_SHORT (vsp
->Psect_Index
);
4312 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4316 * Store either a code or data reference
4318 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4320 * Flush the buffer if it is more than 75% full
4322 if (Object_Record_Offset
>
4323 (sizeof (Object_Record_Buffer
) * 3 / 4))
4324 Flush_VMS_Object_Record_Buffer ();
4329 * Check in the text area for an indirect pc-relative reference
4330 * and fix it up with addressing mode 0xff [PC indirect]
4332 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4333 * PIC CODE GENERATING FIXUP ROUTINE.
4336 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4339 register fragS
*fragP
;
4340 struct frag
*text_frag_root
;
4343 * The addressing mode byte is 1 byte before the address
4347 * Is it in THIS frag??
4349 if ((Offset
< fragP
->fr_address
) ||
4350 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4353 * We need to search for the fragment containing this
4356 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4358 if ((Offset
>= fragP
->fr_address
) &&
4359 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4363 * If we couldn't find the frag, things are BAD!!
4366 error ("Couldn't find fixup fragment when checking for indirect reference");
4369 * Check for indirect PC relative addressing mode
4371 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4373 static char Address_Mode
= 0xff;
4376 * Yes: Store the indirect mode back into the image
4377 * to fix up the damage done by STO_PICR
4379 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4380 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4385 * If the procedure "main()" exists we have to add the instruction
4386 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4388 VMS_Check_For_Main ()
4390 register symbolS
*symbolP
;
4391 #ifdef HACK_DEC_C_STARTUP /* JF */
4392 register struct frchain
*frchainP
;
4393 register fragS
*fragP
;
4394 register fragS
**prev_fragPP
;
4395 register struct fix
*fixP
;
4396 register fragS
*New_Frag
;
4398 #endif /* HACK_DEC_C_STARTUP */
4400 symbolP
= (struct symbol
*) symbol_find ("_main");
4401 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4402 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4404 #ifdef HACK_DEC_C_STARTUP
4405 if (!flag_hash_long_names
)
4409 * Remember the entry point symbol
4411 Entry_Point_Symbol
= symbolP
;
4412 #ifdef HACK_DEC_C_STARTUP
4417 * Scan all the fragment chains for the one with "_main"
4418 * (Actually we know the fragment from the symbol, but we need
4419 * the previous fragment so we can change its pointer)
4421 frchainP
= frchain_root
;
4425 * Scan all the fragments in this chain, remembering
4426 * the "previous fragment"
4428 prev_fragPP
= &frchainP
->frch_root
;
4429 fragP
= frchainP
->frch_root
;
4430 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4433 * Is this the fragment?
4435 if (fragP
== symbolP
->sy_frag
)
4438 * Yes: Modify the fragment by replacing
4439 * it with a new fragment.
4441 New_Frag
= (fragS
*)
4442 xmalloc (sizeof (*New_Frag
) +
4447 * The fragments are the same except
4448 * that the "fixed" area is larger
4451 New_Frag
->fr_fix
+= 6;
4453 * Copy the literal data opening a hole
4454 * 2 bytes after "_main" (i.e. just after
4455 * the entry mask). Into which we place
4456 * the JSB instruction.
4458 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4459 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4460 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4461 New_Frag
->fr_literal
[3] = 0xef;
4462 New_Frag
->fr_literal
[4] = 0;
4463 New_Frag
->fr_literal
[5] = 0;
4464 New_Frag
->fr_literal
[6] = 0;
4465 New_Frag
->fr_literal
[7] = 0;
4466 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4467 New_Frag
->fr_literal
[i
+ 6] =
4468 fragP
->fr_literal
[i
];
4470 * Now replace the old fragment with the
4471 * newly generated one.
4473 *prev_fragPP
= New_Frag
;
4475 * Remember the entry point symbol
4477 Entry_Point_Symbol
= symbolP
;
4479 * Scan the text area fixup structures
4480 * as offsets in the fragment may have
4483 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4486 * Look for references to this
4489 if (fixP
->fx_frag
== fragP
)
4492 * Change the fragment
4495 fixP
->fx_frag
= New_Frag
;
4497 * If the offset is after
4498 * the entry mask we need
4499 * to account for the JSB
4500 * instruction we just
4503 if (fixP
->fx_where
>= 2)
4504 fixP
->fx_where
+= 6;
4508 * Scan the symbols as offsets in the
4509 * fragment may have changed
4511 for (symbolP
= symbol_rootP
;
4513 symbolP
= symbol_next (symbolP
))
4516 * Look for references to this
4519 if (symbolP
->sy_frag
== fragP
)
4522 * Change the fragment
4525 symbolP
->sy_frag
= New_Frag
;
4527 * If the offset is after
4528 * the entry mask we need
4529 * to account for the JSB
4530 * instruction we just
4533 if (S_GET_VALUE (symbolP
) >= 2)
4534 S_SET_VALUE (symbolP
,
4535 S_GET_VALUE (symbolP
) + 6);
4539 * Make a symbol reference to
4540 * "_c$main_args" so we can get
4541 * its address inserted into the
4544 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4545 S_SET_NAME (symbolP
, "_C$MAIN_ARGS");
4546 S_SET_TYPE (symbolP
, N_UNDF
);
4547 S_SET_OTHER (symbolP
, 0);
4548 S_SET_DESC (symbolP
, 0);
4549 S_SET_VALUE (symbolP
, 0);
4550 symbolP
->sy_name_offset
= 0;
4551 symbolP
->sy_number
= 0;
4552 symbolP
->sy_obj
= 0;
4553 symbolP
->sy_frag
= New_Frag
;
4554 symbolP
->sy_resolved
= 0;
4555 symbolP
->sy_resolving
= 0;
4556 /* this actually inserts at the beginning of the list */
4557 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4559 symbol_rootP
= symbolP
;
4561 * Generate a text fixup structure
4562 * to get "_c$main_args" stored into the
4565 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4566 fixP
->fx_frag
= New_Frag
;
4568 fixP
->fx_addsy
= symbolP
;
4570 fixP
->fx_offset
= 0;
4573 fixP
->fx_next
= text_fix_root
;
4574 text_fix_root
= fixP
;
4576 * Now make sure we exit from the loop
4582 * Try the next fragment
4584 prev_fragPP
= &fragP
->fr_next
;
4585 fragP
= fragP
->fr_next
;
4588 * Try the next fragment chain
4591 frchainP
= frchainP
->frch_next
;
4594 #endif /* HACK_DEC_C_STARTUP */
4599 * Write a VAX/VMS object file (everything else has been done!)
4601 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4606 struct frag
*text_frag_root
;
4607 struct frag
*data_frag_root
;
4609 register fragS
*fragP
;
4610 register symbolS
*symbolP
;
4611 register symbolS
*sp
;
4612 register struct fix
*fixP
;
4613 register struct VMS_Symbol
*vsp
;
4615 int Local_Initialized_Data_Size
= 0;
4617 int Psect_Number
= 0; /* Psect Index Number */
4618 int Text_Psect
= -1; /* Text Psect Index */
4619 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4620 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4623 * Create the VMS object file
4625 Create_VMS_Object_File ();
4627 * Write the module header records
4629 Write_VMS_MHD_Records ();
4632 * Store the Data segment:
4634 * Since this is REALLY hard to do any other way,
4635 * we actually manufacture the data segment and
4636 * the store the appropriate values out of it.
4637 * We need to generate this early, so that globalvalues
4638 * can be properly emitted.
4643 * Allocate the data segment
4645 Data_Segment
= (char *) xmalloc (data_siz
);
4647 * Run through the data fragments, filling in the segment
4649 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4651 register long int count
;
4652 register char *fill_literal
;
4653 register long int fill_size
;
4656 i
= fragP
->fr_address
- text_siz
;
4658 memcpy (Data_Segment
+ i
,
4663 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4664 fill_size
= fragP
->fr_var
;
4665 for (count
= fragP
->fr_offset
; count
; count
--)
4668 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4676 * Generate the VMS object file records
4677 * 1st GSD then TIR records
4680 /******* Global Symbol Dictionary *******/
4682 * Emit globalvalues now. We must do this before the text psect
4683 * is defined, or we will get linker warnings about multiply defined
4684 * symbols. All of the globalvalues "reference" psect 0, although
4685 * it really does not have anything to do with it.
4687 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4689 * Define the Text Psect
4691 Text_Psect
= Psect_Number
++;
4692 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4694 * Define the BSS Psect
4698 Bss_Psect
= Psect_Number
++;
4699 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4701 #ifndef gxx_bug_fixed
4703 * The g++ compiler does not write out external references to vtables
4704 * correctly. Check for this and holler if we see it happening.
4705 * If that compiler bug is ever fixed we can remove this.
4707 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4710 * Dispatch on symbol type
4712 switch (S_GET_RAW_TYPE (sp
)) {
4718 * Make a GSD global symbol reference
4721 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4723 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4724 S_SET_OTHER (sp
, 1);
4725 /* Is this warning still needed? It sounds like it describes
4726 a compiler bug. Does it? If not, let's dump it. */
4727 as_warn("g++ wrote an extern reference to %s as a routine.",
4729 as_warn("I will fix it, but I hope that it was not really a routine");
4736 #endif /* gxx_bug_fixed */
4738 * Now scan the symbols and emit the appropriate GSD records
4740 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4743 * Dispatch on symbol type
4745 switch (S_GET_RAW_TYPE (sp
))
4748 * Global uninitialized data
4750 case N_UNDF
| N_EXT
:
4752 * Make a VMS data symbol entry
4754 vsp
= (struct VMS_Symbol
*)
4755 xmalloc (sizeof (*vsp
));
4757 vsp
->Size
= S_GET_VALUE (sp
);
4758 vsp
->Psect_Index
= Psect_Number
++;
4759 vsp
->Psect_Offset
= 0;
4760 vsp
->Next
= VMS_Symbols
;
4764 * Make the psect for this data
4766 Globalref
= VMS_Psect_Spec (
4769 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
4774 /* See if this is an external vtable. We want to help the linker find
4775 these things in libraries, so we make a symbol reference. This
4776 is not compatible with VAX-C usage for variables, but since vtables are
4777 only used internally by g++, we can get away with this hack. */
4779 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4780 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4785 #ifdef NOT_VAX_11_C_COMPATIBLE
4787 * Place a global symbol at the
4788 * beginning of the Psect
4790 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4794 #endif /* NOT_VAX_11_C_COMPATIBLE */
4797 * Local uninitialized data
4801 * Make a VMS data symbol entry
4803 vsp
= (struct VMS_Symbol
*)
4804 xmalloc (sizeof (*vsp
));
4807 vsp
->Psect_Index
= Bss_Psect
;
4810 bss_address_frag
.fr_address
;
4811 vsp
->Next
= VMS_Symbols
;
4816 * Global initialized data
4818 case N_DATA
| N_EXT
:
4820 * Make a VMS data symbol entry
4822 vsp
= (struct VMS_Symbol
*)
4823 xmalloc (sizeof (*vsp
));
4825 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4826 text_siz
+ data_siz
);
4827 vsp
->Psect_Index
= Psect_Number
++;
4828 vsp
->Psect_Offset
= 0;
4829 vsp
->Next
= VMS_Symbols
;
4835 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
4837 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
4842 /* See if this is an external vtable. We want to help the linker find
4843 these things in libraries, so we make a symbol definition. This
4844 is not compatible with VAX-C usage for variables, but since vtables are
4845 only used internally by g++, we can get away with this hack. */
4847 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4848 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4853 #ifdef NOT_VAX_11_C_COMPATIBLE
4855 * Place a global symbol at the
4856 * beginning of the Psect
4858 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4862 #endif /* NOT_VAX_11_C_COMPATIBLE */
4865 * Local initialized data
4869 * Make a VMS data symbol entry
4871 vsp
= (struct VMS_Symbol
*)
4872 xmalloc (sizeof (*vsp
));
4875 VMS_Initialized_Data_Size (sp
,
4876 text_siz
+ data_siz
);
4877 vsp
->Psect_Index
= Data_Psect
;
4879 Local_Initialized_Data_Size
;
4880 Local_Initialized_Data_Size
+= vsp
->Size
;
4881 vsp
->Next
= VMS_Symbols
;
4886 * Global Text definition
4888 case N_TEXT
| N_EXT
:
4890 unsigned short Entry_Mask
;
4893 * Get the entry mask
4895 fragP
= sp
->sy_frag
;
4897 /* If first frag doesn't contain the data, what do we do?
4898 If it's possibly smaller than two bytes, that would
4899 imply that the entry mask is not stored where we're
4902 If you can find a test case that triggers this, report
4903 it (and tell me what the entry mask field ought to be),
4904 and I'll try to fix it. KR */
4905 /* First frag might be empty if we're generating listings.
4906 So skip empty rs_fill frags. */
4907 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
4908 fragP
= fragP
->fr_next
;
4910 if (fragP
->fr_fix
< 2)
4913 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4914 ((fragP
->fr_literal
[1] & 0xff)
4917 * Define the Procedure entry pt.
4919 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4926 * Local Text definition
4930 * Make a VMS data symbol entry
4932 if (Text_Psect
!= -1)
4934 vsp
= (struct VMS_Symbol
*)
4935 xmalloc (sizeof (*vsp
));
4938 vsp
->Psect_Index
= Text_Psect
;
4939 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4940 vsp
->Next
= VMS_Symbols
;
4950 * Make a GSD global symbol reference
4953 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4963 * Ignore STAB symbols
4964 * Including .stabs emitted by g++
4966 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4971 if (S_GET_TYPE (sp
) != 22)
4972 as_tsktsk ("unhandled stab type %d", S_GET_TYPE (sp
));
4977 * Define the Data Psect
4979 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4984 Data_Psect
= Psect_Number
++;
4985 VMS_Psect_Spec ("$data",
4986 Local_Initialized_Data_Size
,
4989 * Scan the VMS symbols and fill in the data psect
4991 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4994 * Only look for undefined psects
4996 if (vsp
->Psect_Index
< 0)
4999 * And only initialized data
5001 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
5002 vsp
->Psect_Index
= Data_Psect
;
5007 /******* Text Information and Relocation Records *******/
5009 * Write the text segment data
5014 * Scan the text fragments
5016 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
5019 * Stop if we get to the data fragments
5021 if (fragP
== data_frag_root
)
5024 * Ignore fragments with no data
5026 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5029 * Go the the appropriate offset in the
5032 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5034 * Store the "fixed" part
5037 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5041 * Store the "variable" part
5043 if (fragP
->fr_var
&& fragP
->fr_offset
)
5044 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5051 * Now we go through the text segment fixups and
5052 * generate TIR records to fix up addresses within
5055 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5058 * We DO handle the case of "Symbol - Symbol" as
5059 * long as it is in the same segment.
5061 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5066 * They need to be in the same segment
5068 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5069 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5070 error ("Fixup data addsy and subsy didn't have the same type");
5072 * And they need to be in one that we
5073 * can check the psect on
5075 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5076 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5077 error ("Fixup data addsy and subsy didn't have an appropriate type");
5079 * This had better not be PC relative!
5082 error ("Fixup data was erroneously \"pcrel\"");
5084 * Subtract their values to get the
5087 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5088 S_GET_VALUE (fixP
->fx_subsy
);
5090 * Now generate the fixup object records
5091 * Set the psect and store the data
5093 VMS_Set_Psect (Text_Psect
,
5095 fixP
->fx_frag
->fr_address
,
5097 VMS_Store_Immediate_Data (&i
,
5106 * Size will HAVE to be "long"
5108 if (fixP
->fx_size
!= 4)
5109 error ("Fixup datum was not a longword");
5111 * Symbol must be "added" (if it is ever
5113 * fix this assumption)
5115 if (fixP
->fx_addsy
== 0)
5116 error ("Fixup datum was not \"fixP->fx_addsy\"");
5118 * Store the symbol value in a PIC fashion
5120 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5125 fixP
->fx_frag
->fr_address
,
5128 * Check for indirect address reference,
5129 * which has to be fixed up (as the linker
5130 * will screw it up with TIR_S_C_STO_PICR).
5133 VMS_Fix_Indirect_Reference (Text_Psect
,
5135 fixP
->fx_frag
->fr_address
,
5141 * Store the Data segment:
5143 * Since this is REALLY hard to do any other way,
5144 * we actually manufacture the data segment and
5145 * the store the appropriate values out of it.
5146 * The segment was manufactured before, now we just
5147 * dump it into the appropriate psects.
5153 * Now we can run through all the data symbols
5154 * and store the data
5156 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5159 * Ignore anything other than data symbols
5161 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5164 * Set the Psect + Offset
5166 VMS_Set_Psect (vsp
->Psect_Index
,
5172 VMS_Store_Immediate_Data (Data_Segment
+
5173 S_GET_VALUE (vsp
->Symbol
) -
5179 * Now we go through the data segment fixups and
5180 * generate TIR records to fix up addresses within
5183 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5186 * Find the symbol for the containing datum
5188 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5191 * Only bother with Data symbols
5194 if (S_GET_TYPE (sp
) != N_DATA
)
5197 * Ignore symbol if After fixup
5199 if (S_GET_VALUE (sp
) >
5201 fixP
->fx_frag
->fr_address
))
5204 * See if the datum is here
5206 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5208 fixP
->fx_frag
->fr_address
))
5211 * We DO handle the case of "Symbol - Symbol" as
5212 * long as it is in the same segment.
5214 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5219 * They need to be in the same segment
5221 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5222 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5223 error ("Fixup data addsy and subsy didn't have the same type");
5225 * And they need to be in one that we
5226 * can check the psect on
5228 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5229 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5230 error ("Fixup data addsy and subsy didn't have an appropriate type");
5232 * This had better not be PC relative!
5235 error ("Fixup data was erroneously \"pcrel\"");
5237 * Subtract their values to get the
5240 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5241 S_GET_VALUE (fixP
->fx_subsy
);
5243 * Now generate the fixup object records
5244 * Set the psect and store the data
5246 VMS_Set_Psect (vsp
->Psect_Index
,
5247 fixP
->fx_frag
->fr_address
+
5249 S_GET_VALUE (vsp
->Symbol
) +
5252 VMS_Store_Immediate_Data (&i
,
5261 * Size will HAVE to be "long"
5263 if (fixP
->fx_size
!= 4)
5264 error ("Fixup datum was not a longword");
5266 * Symbol must be "added" (if it is ever
5268 * fix this assumption)
5270 if (fixP
->fx_addsy
== 0)
5271 error ("Fixup datum was not \"fixP->fx_addsy\"");
5273 * Store the symbol value in a PIC fashion
5275 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5279 fixP
->fx_frag
->fr_address
+
5281 S_GET_VALUE (vsp
->Symbol
) +
5294 * Write the Traceback Begin Module record
5296 VMS_TBT_Module_Begin ();
5298 * Scan the symbols and write out the routines
5299 * (this makes the assumption that symbols are in
5300 * order of ascending text segment offset)
5303 struct symbol
*Current_Routine
= 0;
5304 int Current_Line_Number
= 0;
5305 int Current_Offset
= -1;
5306 struct input_file
*Current_File
;
5308 /* Output debugging info for global variables and static variables that are not
5309 * specific to one routine. We also need to examine all stabs directives, to
5310 * find the definitions to all of the advanced data types, and this is done by
5311 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5312 * the object file, since there can be forward references in the stabs
5313 * directives. When through with parsing, the text of the stabs directive
5314 * is altered, with the definitions removed, so that later passes will see
5315 * directives as they would be written if the type were already defined.
5317 * We also look for files and include files, and make a list of them. We
5318 * examine the source file numbers to establish the actual lines that code was
5319 * generated from, and then generate offsets.
5322 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5325 * Deal with STAB symbols
5327 if (S_IS_DEBUG (symbolP
))
5330 * Dispatch on STAB type
5332 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5335 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5336 Current_File
->max_line
= S_GET_DESC (symbolP
);
5337 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5338 Current_File
->min_line
= S_GET_DESC (symbolP
);
5341 Current_File
= find_file (symbolP
);
5342 Current_File
->flag
= 1;
5343 Current_File
->min_line
= 1;
5346 Current_File
= find_file (symbolP
);
5349 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5352 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5354 case N_FUN
: /* For static constant symbols */
5356 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5362 /* now we take a quick sweep through the files and assign offsets
5363 to each one. This will essentially be the starting line number to the
5364 debugger for each file. Output the info for the debugger to specify the
5365 files, and then tell it how many lines to use */
5367 int File_Number
= 0;
5368 int Debugger_Offset
= 0;
5370 Current_File
= file_root
;
5371 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5373 if (Current_File
== (struct input_file
*) NULL
)
5375 if (Current_File
->max_line
== 0)
5377 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5380 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5383 /* show a few extra lines at the start of the region selected */
5384 if (Current_File
->min_line
> 2)
5385 Current_File
->min_line
-= 2;
5386 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5387 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5388 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5389 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5392 Current_File
->file_number
= ++File_Number
;
5393 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5394 Current_File
->file_number
);
5395 if (!file_available
)
5397 Current_File
->file_number
= 0;
5402 VMS_TBT_Source_Lines (Current_File
->file_number
,
5403 Current_File
->min_line
,
5404 Current_File
->max_line
- Current_File
->min_line
+ 1);
5407 Current_File
= (struct input_file
*) NULL
;
5409 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5412 * Deal with text symbols
5414 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5417 * Ignore symbols starting with "L",
5418 * as they are local symbols
5420 if (*S_GET_NAME (symbolP
) == 'L')
5423 * If there is a routine start defined,
5426 if (Current_Routine
)
5431 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5434 * Check for & skip dummy labels like "gcc_compiled.".
5435 * They're identified by the IN_DEFAULT_SECTION flag.
5437 if ((S_GET_OTHER (symbolP
) & IN_DEFAULT_SECTION
) != 0 &&
5438 (S_GET_VALUE (symbolP
) == 0))
5441 * Store the routine begin traceback info
5443 if (Text_Psect
!= -1)
5445 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5446 Current_Routine
= symbolP
;
5448 /* Output local symbols, i.e. all symbols that are associated with a specific
5449 * routine. We output them now so the debugger recognizes them as local to
5456 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5458 if (!S_IS_DEBUG (symbolP1
))
5460 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5462 pnt
= S_GET_NAME (symbolP
);
5463 pnt1
= S_GET_NAME (symbolP1
);
5466 while (*pnt
++ == *pnt1
++)
5469 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5470 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5473 if (symbolP1
!= (symbolS
*) NULL
)
5474 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5475 } /* local symbol block */
5482 * Deal with STAB symbols
5484 if (S_IS_DEBUG (symbolP
))
5487 * Dispatch on STAB type
5489 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5495 /* Offset the line into the correct portion
5497 if (Current_File
->file_number
== 0)
5499 /* Sometimes the same offset gets several source
5500 * lines assigned to it.
5501 * We should be selective about which lines
5502 * we allow, we should prefer lines that are
5503 * in the main source file when debugging
5504 * inline functions. */
5505 if ((Current_File
->file_number
!= 1) &&
5506 S_GET_VALUE (symbolP
) ==
5509 /* calculate actual debugger source line */
5510 S_GET_DESC (symbolP
)
5511 += Current_File
->offset
;
5513 * If this is the 1st N_SLINE, setup
5514 * PC/Line correlation. Otherwise
5515 * do the delta PC/Line. If the offset
5516 * for the line number is not +ve we need
5517 * to do another PC/Line correlation
5520 if (Current_Offset
== -1)
5522 VMS_TBT_Line_PC_Correlation (
5523 S_GET_DESC (symbolP
),
5524 S_GET_VALUE (symbolP
),
5530 if ((S_GET_DESC (symbolP
) -
5531 Current_Line_Number
) <= 0)
5534 * Line delta is not +ve, we
5535 * need to close the line and
5536 * start a new PC/Line
5539 VMS_TBT_Line_PC_Correlation (0,
5540 S_GET_VALUE (symbolP
) -
5544 VMS_TBT_Line_PC_Correlation (
5545 S_GET_DESC (symbolP
),
5546 S_GET_VALUE (symbolP
),
5553 * Line delta is +ve, all is well
5555 VMS_TBT_Line_PC_Correlation (
5556 S_GET_DESC (symbolP
) -
5557 Current_Line_Number
,
5558 S_GET_VALUE (symbolP
) -
5565 * Update the current line/PC
5567 Current_Line_Number
= S_GET_DESC (symbolP
);
5568 Current_Offset
= S_GET_VALUE (symbolP
);
5578 * Remember that we had a source file
5579 * and emit the source file debugger
5583 find_file (symbolP
);
5585 /* We need to make sure that we are really in the actual source file when
5586 * we compute the maximum line number. Otherwise the debugger gets really
5590 find_file (symbolP
);
5596 * If there is a routine start defined,
5597 * terminate it (and the line numbers)
5599 if (Current_Routine
)
5602 * Terminate the line numbers
5604 VMS_TBT_Line_PC_Correlation (0,
5605 text_siz
- S_GET_VALUE (Current_Routine
),
5609 * Terminate the routine
5611 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5615 * Write the Traceback End Module TBT record
5617 VMS_TBT_Module_End ();
5620 * Write the End Of Module record
5622 if (Entry_Point_Symbol
== 0)
5623 Write_VMS_EOM_Record (-1, 0);
5625 Write_VMS_EOM_Record (Text_Psect
,
5626 S_GET_VALUE (Entry_Point_Symbol
));
5629 * All done, close the object file
5631 Close_VMS_Object_File ();
5634 /* end of obj-vms.c */