1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992, 1994, 1995 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*/
35 extern int sys$
open(), sys$
close(), sys$
asctim();
38 * Version string of the compiler that produced the code we are
39 * assembling. (And this assembler, if we do not have compiler info.)
41 char *compiler_version_string
;
43 extern int flag_hash_long_names
; /* -+ */
44 extern int flag_one
; /* -1 */
45 extern int flag_show_after_trunc
; /* -H */
46 extern int flag_no_hash_mixed_case
; /* -h NUM */
48 /* Flag that determines how we map names. This takes several values, and
49 * is set with the -h switch. A value of zero implies names should be
50 * upper case, and the presence of the -h switch inhibits the case hack.
51 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
52 * A value of 2 (set with -h2) implies names should be
53 * all lower case, with no case hack. A value of 3 (set with -h3) implies
54 * that case should be preserved. */
56 /* If the -+ switch is given, then the hash is appended to any name that is
57 * longer than 31 characters, irregardless of the setting of the -h switch.
60 char vms_name_mapping
= 0;
63 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
66 * We augment the "gas" symbol structure with this
70 struct VMS_Symbol
*Next
;
71 struct symbol
*Symbol
;
76 struct VMS_Symbol
*VMS_Symbols
= 0;
78 /* We need this to keep track of the various input files, so that we can
79 * give the debugger the correct source line.
84 struct input_file
*next
;
85 struct input_file
*same_file_fpnt
;
95 static struct input_file
*file_root
= (struct input_file
*) NULL
;
98 static struct input_file
*find_file
PARAMS ((symbolS
*));
101 * This enum is used to keep track of the various types of variables that
107 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
111 * This structure contains the information from the stabs directives, and the
112 * information is filled in by VMS_typedef_parse. Everything that is needed
113 * to generate the debugging record for a given symbol is present here.
114 * This could be done more efficiently, using nested struct/unions, but for now
115 * I am happy that it works.
117 struct VMS_DBG_Symbol
119 struct VMS_DBG_Symbol
*next
;
120 /* description of what this is */
121 enum advanced_type advanced
;
122 /* this record is for this type */
124 /* For advanced types this is the type referred to. I.e., the type
125 a pointer points to, or the type of object that makes up an
128 /* Use this type when generating a variable def */
130 /* used for arrays - this will be present for all */
132 /* entries, but will be meaningless for non-arrays */
134 /* Size in bytes of the data type. For an array, this is the size
135 of one element in the array */
137 /* Number of the structure/union/enum - used for ref */
141 #define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */
142 #define SYMTYP_HASH(x) ((unsigned)(x) & (SYMTYPLST_SIZE-1))
143 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
[SYMTYPLST_SIZE
];
146 * We need this structure to keep track of forward references to
147 * struct/union/enum that have not been defined yet. When they are ultimately
148 * defined, then we can go back and generate the TIR commands to make a back
154 struct forward_ref
*next
;
160 struct forward_ref
*f_ref_root
=
161 {(struct forward_ref
*) NULL
};
164 * This routine is used to compare the names of certain types to various
165 * fixed types that are known by the debugger.
167 #define type_check(x) !strcmp( symbol_name , x )
170 * This variable is used to keep track of the name of the symbol we are
171 * working on while we are parsing the stabs directives.
173 static const char *symbol_name
;
175 /* We use this counter to assign numbers to all of the structures, unions
176 * and enums that we define. When we actually declare a variable to the
177 * debugger, we can simply do it by number, rather than describing the
178 * whole thing each time.
181 static structure_count
= 0;
183 /* This variable is used to indicate that we are making the last attempt to
184 parse the stabs, and that we should define as much as we can, and ignore
187 static int final_pass
;
189 /* This variable is used to keep track of the current structure number
190 * for a given variable. If this is < 0, that means that the structure
191 * has not yet been defined to the debugger. This is still cool, since
192 * the VMS object language has ways of fixing things up after the fact,
193 * so we just make a note of this, and generate fixups at the end.
195 static int struct_number
;
197 /* This is used to distinguish between D_float and G_float for telling
198 the debugger about doubles. gcc outputs the same .stabs regardless
199 of whether -mg is used to select alternate doubles. */
201 static int vax_g_doubles
= 0;
203 /* Local symbol references (used to handle N_ABS symbols; gcc does not
204 generate those, but they're possible with hand-coded assembler input)
205 are always made relative to some particular environment. If the current
206 input has any such symbols, then we expect this to get incremented
207 exactly once and end up having all of them be in environment #0. */
209 static int Current_Environment
= -1;
213 * Variable descriptors are used tell the debugger the data types of certain
214 * more complicated variables (basically anything involving a structure,
215 * union, enum, array or pointer). Some non-pointer variables of the
216 * basic types that the debugger knows about do not require a variable
219 * Since it is impossible to have a variable descriptor longer than 128
220 * bytes by virtue of the way that the VMS object language is set up,
221 * it makes not sense to make the arrays any longer than this, or worrying
222 * about dynamic sizing of the array.
224 * These are the arrays and counters that we use to build a variable
228 #define MAX_DEBUG_RECORD 128
229 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
230 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
231 static int Lpnt
; /* index into Local */
232 static int Apoint
; /* index into Asuffix */
233 static char overflow
; /* flag to indicate we have written too much*/
234 static int total_len
; /* used to calculate the total length of variable
235 descriptor plus array descriptor - used for len byte*/
237 /* Flag if we have told user about finding global constants in the text
239 static gave_compiler_message
= 0;
241 /* A pointer to the current routine that we are working on. */
243 static symbolS
*Current_Routine
;
245 /* The psect number for $code a.k.a. the text section. */
247 static int Text_Psect
;
251 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
253 static int VMS_Object_File_FD
; /* File Descriptor for object file */
254 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
255 static int Object_Record_Offset
;/* Offset to end of data */
256 static int Current_Object_Record_Type
; /* Type of record in above */
259 * Macros for moving data around. Must work on big-endian systems.
261 #ifdef VMS /* These are more efficient for VMS->VMS systems */
262 #define COPY_LONG(dest,val) {*(long *) dest = val; }
263 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
265 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
266 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
269 * Macros for placing data into the object record buffer
272 #define PUT_LONG(val) \
273 { md_number_to_chars(Object_Record_Buffer + \
274 Object_Record_Offset, val, 4); \
275 Object_Record_Offset += 4; }
277 #define PUT_SHORT(val) \
278 { md_number_to_chars(Object_Record_Buffer + \
279 Object_Record_Offset, val, 2); \
280 Object_Record_Offset += 2; }
282 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
284 #define PUT_COUNTED_STRING(cp) {\
285 register const char *p = cp; \
286 PUT_CHAR(strlen(p)); \
287 while (*p) PUT_CHAR(*p++);}
290 * Macro for determining if a Name has psect attributes attached
293 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
294 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
296 #define HAS_PSECT_ATTRIBUTES(Name) \
297 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
298 PSECT_ATTRIBUTES_STRING, \
299 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
302 /* in: segT out: N_TYPE bits */
303 const short seg_N_TYPE
[] =
309 N_UNDF
, /* unknown */
311 N_UNDF
, /* expression */
315 N_REGISTER
, /* register */
318 const segT N_TYPE_seg
[N_TYPE
+ 2] =
319 { /* N_TYPE == 0x1E = 32-2 */
320 SEG_UNKNOWN
, /* N_UNDF == 0 */
322 SEG_ABSOLUTE
, /* N_ABS == 2 */
324 SEG_TEXT
, /* N_TEXT == 4 */
326 SEG_DATA
, /* N_DATA == 6 */
328 SEG_BSS
, /* N_BSS == 8 */
330 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
331 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
332 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
333 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
338 /* The following code defines the special types of pseudo-ops that we
342 char const_flag
= IN_DEFAULT_SECTION
;
349 temp
= get_absolute_expression ();
350 subseg_set (SEG_DATA
, (subsegT
) temp
);
352 demand_empty_rest_of_line ();
355 const pseudo_typeS obj_pseudo_table
[] =
357 {"const", s_const
, 0},
359 }; /* obj_pseudo_table */
362 vms_resolve_symbol_redef (sym
)
366 * If the new symbol is .comm AND it has a size of zero,
367 * we ignore it (i.e. the old symbol overrides it)
369 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)
370 && frag_now_fix () == 0)
372 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
377 * If the old symbol is .comm and it has a size of zero,
378 * we override it with the new symbol value.
380 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
381 && (S_GET_VALUE(sym
) == 0))
383 as_warn ("compiler redefined zero-size common symbol `%s'",
385 sym
->sy_frag
= frag_now
;
386 S_SET_OTHER(sym
, const_flag
);
387 S_SET_VALUE(sym
, frag_now_fix ());
388 /* Keep N_EXT bit. */
389 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
396 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
397 dummy label(s) gcc inserts at the beginning of each file it generates.
398 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
399 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
402 vms_check_for_special_label (symbolP
)
405 /* Special labels only occur prior to explicit section directives. */
406 if ((const_flag
& IN_DEFAULT_SECTION
) != 0)
408 char *sym_name
= S_GET_NAME(symbolP
);
410 if (*sym_name
== '_')
413 if (!strcmp (sym_name
, "__vax_g_doubles"))
415 #if 0 /* not necessary */
416 else if (!strcmp (sym_name
, "__vax_d_doubles"))
419 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
420 else if (!strcmp (sym_name
, "gcc_compiled."))
422 else if (!strcmp (sym_name
, "__gnu_language_cplusplus"))
423 flag_hash_long_names
= 1;
430 obj_read_begin_hook ()
436 obj_crawl_symbol_chain (headers
)
437 object_headers
*headers
;
441 int symbol_number
= 0;
443 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
444 while ((symbolP
= *symbolPP
) != NULL
)
446 resolve_symbol_value (symbolP
);
448 /* OK, here is how we decide which symbols go out into the
449 brave new symtab. Symbols that do are:
451 * symbols with no name (stabd's?)
452 * symbols with debug info in their N_TYPE
453 * symbols with \1 as their 3rd character (numeric labels)
454 * "local labels" needed for PIC fixups
456 Symbols that don't are:
457 * symbols that are registers
459 All other symbols are output. We complain if a deleted
460 symbol was marked external. */
462 if (!S_IS_REGISTER (symbolP
))
464 symbolP
->sy_number
= symbol_number
++;
465 symbolP
->sy_name_offset
= 0;
466 symbolPP
= &(symbol_next (symbolP
));
470 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
472 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
475 /* Unhook it from the chain. */
476 *symbolPP
= symbol_next (symbolP
);
477 } /* if this symbol should be in the output */
479 } /* for each symbol */
481 H_SET_STRING_SIZE (headers
, string_byte_count
);
482 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
483 } /* obj_crawl_symbol_chain() */
486 /****** VMS OBJECT FILE HACKING ROUTINES *******/
490 * Create the VMS object file
493 Create_VMS_Object_File ()
495 #if defined(eunice) || !defined(VMS)
496 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
498 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
499 "mbc=16", "deq=64", "fop=tef", "shr=nil");
504 if (VMS_Object_File_FD
< 0)
505 as_fatal ("Couldn't create VMS object file \"%s\"", out_file_name
);
507 * Initialize object file hacking variables
509 Object_Record_Offset
= 0;
510 Current_Object_Record_Type
= -1;
515 * Flush the object record buffer to the object file
518 Flush_VMS_Object_Record_Buffer ()
527 * If the buffer is empty, we are done
529 if (Object_Record_Offset
== 0)
532 * Write the data to the file
534 #ifndef VMS /* For cross-assembly purposes. */
535 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
536 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
538 i
= write (VMS_Object_File_FD
,
539 Object_Record_Buffer
,
540 Object_Record_Offset
);
541 if (i
!= Object_Record_Offset
)
542 error ("I/O error writing VMS object file");
543 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
545 /* pad it if needed */
547 if ((Object_Record_Offset
& 1) != 0)
548 write (VMS_Object_File_FD
, &zero
, 1);
551 * The buffer is now empty
553 Object_Record_Offset
= 0;
558 * Declare a particular type of object file record
561 Set_VMS_Object_File_Record (Type
)
565 * If the type matches, we are done
567 if (Type
== Current_Object_Record_Type
)
570 * Otherwise: flush the buffer
572 Flush_VMS_Object_Record_Buffer ();
576 Current_Object_Record_Type
= Type
;
582 * Close the VMS Object file
585 Close_VMS_Object_File ()
587 #ifndef VMS /* For cross-assembly purposes. */
588 short int m_one
= -1;
590 /* Write a record-length field of 0xffff into the file, which means
591 end-of-file when read later. It is only needed for variable-length
592 record files transferred to VMS as fixed-length record files
593 (typical for binary ftp). */
594 write (VMS_Object_File_FD
, &m_one
, 2);
596 /* When written on a VMS system, the file header (cf inode) will record
597 the actual end-of-file position and no inline marker is needed. */
600 close (VMS_Object_File_FD
);
605 * Stack Psect base followed by signed, varying-sized offset.
606 * Common to several object records.
609 vms_tir_stack_psect (Psect_Index
, Offset
, Force
)
614 int psect_width
, offset_width
;
616 psect_width
= ((unsigned) Psect_Index
> 255) ? 2 : 1;
617 offset_width
= (Force
|| Offset
> 32767 || Offset
< -32768) ? 4
618 : (Offset
> 127 || Offset
< -128) ? 2 : 1;
619 #define Sta_P(p,o) (((o)<<1) | ((p)-1))
620 switch (Sta_P(psect_width
,offset_width
))
622 case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB
);
623 PUT_CHAR ((char)(unsigned char) Psect_Index
);
624 PUT_CHAR ((char) Offset
);
626 case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW
);
627 PUT_CHAR ((char)(unsigned char) Psect_Index
);
630 case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL
);
631 PUT_CHAR ((char)(unsigned char) Psect_Index
);
634 case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB
);
635 PUT_SHORT (Psect_Index
);
636 PUT_CHAR ((char) Offset
);
638 case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW
);
639 PUT_SHORT (Psect_Index
);
642 case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL
);
643 PUT_SHORT (Psect_Index
);
651 * Store immediate data in current Psect
654 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
662 * We are writing a "Record_Type" record
664 Set_VMS_Object_File_Record (Record_Type
);
666 * We can only store 128 bytes at a time
671 * Store a maximum of 128 bytes
673 i
= (Size
> 128) ? 128 : Size
;
676 * If we cannot accommodate this record, flush the
679 if ((Object_Record_Offset
+ i
+ 1) >=
680 sizeof (Object_Record_Buffer
))
681 Flush_VMS_Object_Record_Buffer ();
683 * If the buffer is empty we must insert record type
685 if (Object_Record_Offset
== 0)
686 PUT_CHAR (Record_Type
);
690 PUT_CHAR (-i
& 0xff);
695 PUT_CHAR (*Pointer
++);
697 * Flush the buffer if it is more than 75% full
699 if (Object_Record_Offset
>
700 (sizeof (Object_Record_Buffer
) * 3 / 4))
701 Flush_VMS_Object_Record_Buffer ();
706 * Make a data reference
709 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
716 * We are writing a "Record_Type" record
718 Set_VMS_Object_File_Record (Record_Type
);
720 * If the buffer is empty we must insert the record type
722 if (Object_Record_Offset
== 0)
723 PUT_CHAR (Record_Type
);
725 * Stack the Psect base with its offset
727 vms_tir_stack_psect (Psect_Index
, Offset
, Force
);
729 * Set relocation base
731 PUT_CHAR (TIR_S_C_STO_PIDR
);
733 * Flush the buffer if it is more than 75% full
735 if (Object_Record_Offset
>
736 (sizeof (Object_Record_Buffer
) * 3 / 4))
737 Flush_VMS_Object_Record_Buffer ();
741 * Make a debugger reference to a struct, union or enum.
744 VMS_Store_Struct (Struct_Index
)
748 * We are writing a "OBJ_S_C_DBG" record
750 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
752 * If the buffer is empty we must insert the record type
754 if (Object_Record_Offset
== 0)
755 PUT_CHAR (OBJ_S_C_DBG
);
756 PUT_CHAR (TIR_S_C_STA_UW
);
757 PUT_SHORT (Struct_Index
);
758 PUT_CHAR (TIR_S_C_CTL_STKDL
);
759 PUT_CHAR (TIR_S_C_STO_L
);
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 * Make a debugger reference to partially define a struct, union or enum.
772 VMS_Def_Struct (Struct_Index
)
776 * We are writing a "OBJ_S_C_DBG" record
778 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
780 * If the buffer is empty we must insert the record type
782 if (Object_Record_Offset
== 0)
783 PUT_CHAR (OBJ_S_C_DBG
);
784 PUT_CHAR (TIR_S_C_STA_UW
);
785 PUT_SHORT (Struct_Index
);
786 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
788 * Flush the buffer if it is more than 75% full
790 if (Object_Record_Offset
>
791 (sizeof (Object_Record_Buffer
) * 3 / 4))
792 Flush_VMS_Object_Record_Buffer ();
796 VMS_Set_Struct (Struct_Index
)
798 { /* see previous functions for comments */
799 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
800 if (Object_Record_Offset
== 0)
801 PUT_CHAR (OBJ_S_C_DBG
);
802 PUT_CHAR (TIR_S_C_STA_UW
);
803 PUT_SHORT (Struct_Index
);
804 PUT_CHAR (TIR_S_C_CTL_STLOC
);
805 if (Object_Record_Offset
>
806 (sizeof (Object_Record_Buffer
) * 3 / 4))
807 Flush_VMS_Object_Record_Buffer ();
811 * Write the Traceback Module Begin record
814 VMS_TBT_Module_Begin ()
816 register char *cp
, *cp1
;
818 char Module_Name
[256];
822 * Get module name (the FILENAME part of the object file)
828 if ((*cp
== ']') || (*cp
== '>') ||
829 (*cp
== ':') || (*cp
== '/'))
835 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
839 * Limit it to 31 characters
841 while (--cp1
>= Module_Name
)
844 if (strlen (Module_Name
) > 31)
846 if (flag_hash_long_names
)
847 as_tsktsk ("Module name truncated: %s", Module_Name
);
851 * Arrange to store the data locally (leave room for size byte)
857 *cp
++ = DST_S_C_MODBEG
;
863 * Language type == "C"
865 COPY_LONG (cp
, DST_S_C_C
);
868 * Store the module name
870 *cp
++ = strlen (Module_Name
);
875 * Now we can store the record size
880 * Put it into the object record
882 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
887 * Write the Traceback Module End record
890 VMS_TBT_Module_End ()
898 Local
[1] = DST_S_C_MODEND
;
900 * Put it into the object record
902 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
907 * Write the Traceback Routine Begin record
910 VMS_TBT_Routine_Begin (symbolP
, Psect
)
911 struct symbol
*symbolP
;
914 register char *cp
, *cp1
;
921 * Strip the leading "_" from the name
923 Name
= S_GET_NAME (symbolP
);
927 * Get the text psect offset
929 Offset
= S_GET_VALUE (symbolP
);
931 * Calculate the record size
933 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
941 Local
[1] = DST_S_C_RTNBEG
;
947 * Store the data so far
949 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
951 * Make sure we are still generating a OBJ_S_C_TBT record
953 if (Object_Record_Offset
== 0)
954 PUT_CHAR (OBJ_S_C_TBT
);
958 vms_tir_stack_psect (Psect
, Offset
, 0);
960 * Store the data reference
962 PUT_CHAR (TIR_S_C_STO_PIDR
);
964 * Store the counted string as data
968 Size
= strlen (cp1
) + 1;
972 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
977 * Write the Traceback Routine End record
978 * We *must* search the symbol table to find the next routine, since
979 * the assember has a way of reassembling the symbol table OUT OF ORDER
980 * Thus the next routine in the symbol list is not necessarily the
981 * next one in memory. For debugging to work correctly we must know the
982 * size of the routine.
985 VMS_TBT_Routine_End (Max_Size
, sp
)
990 int Size
= 0x7fffffff;
992 valueT sym_value
, sp_value
= S_GET_VALUE (sp
);
994 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
996 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
998 if (*S_GET_NAME (symbolP
) == 'L')
1000 sym_value
= S_GET_VALUE (symbolP
);
1001 if (sym_value
> sp_value
&& sym_value
< Size
)
1005 * Dummy labels like "gcc_compiled." should no longer reach here.
1009 /* check if gcc_compiled. has size of zero */
1010 if (sym_value
== sp_value
&&
1012 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1013 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1018 if (Size
== 0x7fffffff)
1020 Size
-= sp_value
; /* and get the size of the routine */
1028 Local
[1] = DST_S_C_RTNEND
;
1036 COPY_LONG (&Local
[3], Size
);
1040 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1044 * Write the Traceback Block End record
1047 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1048 struct symbol
*symbolP
;
1052 register char *cp
, *cp1
;
1059 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1065 * Begin Block - We simulate with a phony routine
1067 Local
[1] = DST_S_C_BLKBEG
;
1073 * Store the data so far
1075 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1077 * Make sure we are still generating a OBJ_S_C_DBG record
1079 if (Object_Record_Offset
== 0)
1080 PUT_CHAR (OBJ_S_C_DBG
);
1082 * Now get the symbol address
1084 PUT_CHAR (TIR_S_C_STA_WPL
);
1087 * Get the text psect offset
1089 Offset
= S_GET_VALUE (symbolP
);
1092 * Store the data reference
1094 PUT_CHAR (TIR_S_C_STO_PIDR
);
1096 * Store the counted string as data
1100 Size
= strlen (cp1
) + 1;
1104 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1109 * Write the Traceback Block End record
1112 VMS_TBT_Block_End (Size
)
1118 * End block - simulate with a phony end routine
1121 Local
[1] = DST_S_C_BLKEND
;
1122 COPY_LONG (&Local
[3], Size
);
1127 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1133 * Write a Line number / PC correlation record
1136 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1146 * If not delta, set our PC/Line number correlation
1153 Local
[0] = 1 + 1 + 2 + 1 + 4;
1155 * Line Number/PC correlation
1157 Local
[1] = DST_S_C_LINE_NUM
;
1161 Local
[2] = DST_S_C_SET_LINE_NUM
;
1162 COPY_SHORT (&Local
[3], Line_Number
- 1);
1166 Local
[5] = DST_S_C_SET_ABS_PC
;
1167 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1169 * Make sure we are still generating a OBJ_S_C_TBT record
1171 if (Object_Record_Offset
== 0)
1172 PUT_CHAR (OBJ_S_C_TBT
);
1173 vms_tir_stack_psect (Psect
, Offset
, 0);
1174 PUT_CHAR (TIR_S_C_STO_PIDR
);
1176 * Do a PC offset of 0 to register the line number
1179 Local
[1] = DST_S_C_LINE_NUM
;
1180 Local
[2] = 0; /* Increment PC by 0 and register line # */
1181 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1186 * If Delta is negative, terminate the line numbers
1190 Local
[0] = 1 + 1 + 4;
1191 Local
[1] = DST_S_C_LINE_NUM
;
1192 Local
[2] = DST_S_C_TERM_L
;
1193 COPY_LONG (&Local
[3], Offset
);
1194 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1201 * Do a PC/Line delta
1204 *cp
++ = DST_S_C_LINE_NUM
;
1205 if (Line_Number
> 1)
1208 * We need to increment the line number
1210 if (Line_Number
- 1 <= 255)
1212 *cp
++ = DST_S_C_INCR_LINUM
;
1213 *cp
++ = Line_Number
- 1;
1217 *cp
++ = DST_S_C_INCR_LINUM_W
;
1218 COPY_SHORT (cp
, Line_Number
- 1);
1231 if (Offset
< 0x10000)
1233 *cp
++ = DST_S_C_DELTA_PC_W
;
1234 COPY_SHORT (cp
, Offset
);
1239 *cp
++ = DST_S_C_DELTA_PC_L
;
1240 COPY_LONG (cp
, Offset
);
1244 Local
[0] = cp
- (Local
+ 1);
1245 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1251 * Describe a source file to the debugger
1254 VMS_TBT_Source_File (Filename
, ID_Number
)
1258 register char *cp
, *cp1
;
1261 #ifndef VMS /* Used for cross-assembly */
1262 i
= strlen (Filename
);
1264 static struct FAB Fab
;
1265 static struct NAM Nam
;
1266 static struct XABDAT Date_Xab
;
1267 static struct XABFHC File_Header_Xab
;
1268 char Es_String
[255], Rs_String
[255];
1273 Fab
.fab$b_bid
= FAB$C_BID
;
1274 Fab
.fab$b_bln
= sizeof (Fab
);
1275 Fab
.fab$l_nam
= (&Nam
);
1276 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1278 * Setup the Nam block so we can find out the FULL name
1279 * of the source file.
1281 Nam
.nam$b_bid
= NAM$C_BID
;
1282 Nam
.nam$b_bln
= sizeof (Nam
);
1283 Nam
.nam$l_rsa
= Rs_String
;
1284 Nam
.nam$b_rss
= sizeof (Rs_String
);
1285 Nam
.nam$l_esa
= Es_String
;
1286 Nam
.nam$b_ess
= sizeof (Es_String
);
1288 * Setup the Date and File Header Xabs
1290 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1291 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1292 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1293 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1294 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1296 * Get the file information
1298 Fab
.fab$l_fna
= Filename
;
1299 Fab
.fab$b_fns
= strlen (Filename
);
1300 Status
= sys$
open (&Fab
);
1303 as_tsktsk ("Couldn't find source file \"%s\", status=%%X%x",
1309 * Calculate the size of the resultant string
1316 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1318 * Source declaration
1320 Local
[1] = DST_S_C_SOURCE
;
1322 * Make formfeeds count as source records
1324 Local
[2] = DST_S_C_SRC_FORMFEED
;
1326 * Declare source file
1328 Local
[3] = DST_S_C_SRC_DECLFILE
;
1329 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1338 COPY_SHORT (cp
, ID_Number
);
1342 * Creation Date. Unknown, so we fill with zeroes.
1367 #else /* Use this code when assembling for VMS on a VMS system */
1371 memcpy (cp
, (char *) &Date_Xab
.xab$q_cdt
, 8);
1376 COPY_LONG (cp
, File_Header_Xab
.xab$l_ebk
);
1381 COPY_SHORT (cp
, File_Header_Xab
.xab$w_ffb
);
1386 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1396 * Library module name (none)
1402 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1408 * Give the number of source lines to the debugger
1411 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1413 int Starting_Line_Number
;
1414 int Number_Of_Lines
;
1422 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1424 * Source declaration
1426 Local
[1] = DST_S_C_SOURCE
;
1431 *cp
++ = DST_S_C_SRC_SETFILE
;
1435 COPY_SHORT (cp
, ID_Number
);
1440 *cp
++ = DST_S_C_SRC_SETREC_L
;
1441 COPY_LONG (cp
, Starting_Line_Number
);
1446 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1447 COPY_SHORT (cp
, Number_Of_Lines
);
1452 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1458 /* This routine locates a file in the list of files. If an entry does not
1459 * exist, one is created. For include files, a new entry is always created
1460 * such that inline functions can be properly debugged. */
1461 static struct input_file
*
1465 struct input_file
*same_file
;
1466 struct input_file
*fpnt
;
1467 same_file
= (struct input_file
*) NULL
;
1468 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1470 if (fpnt
== (struct input_file
*) NULL
)
1472 if (fpnt
->spnt
== sp
)
1475 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1477 if (fpnt
== (struct input_file
*) NULL
)
1479 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1481 if (fpnt
->flag
== 1)
1487 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1488 if (file_root
== (struct input_file
*) NULL
)
1492 struct input_file
*fpnt1
;
1493 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1496 fpnt
->next
= (struct input_file
*) NULL
;
1497 fpnt
->name
= S_GET_NAME (sp
);
1498 fpnt
->min_line
= 0x7fffffff;
1502 fpnt
->file_number
= 0;
1504 fpnt
->same_file_fpnt
= same_file
;
1509 * The following functions and definitions are used to generate object records
1510 * that will describe program variables to the VMS debugger.
1512 * This file contains many of the routines needed to output debugging info into
1513 * the object file that the VMS debugger needs to understand symbols. These
1514 * routines are called very late in the assembly process, and thus we can be
1515 * fairly lax about changing things, since the GSD and the TIR sections have
1516 * already been output.
1520 /* This routine converts a number string into an integer, and stops when it
1521 * sees an invalid character. The return value is the address of the character
1522 * just past the last character read. No error is generated.
1525 cvt_integer (str
, rtn
)
1530 neg
= *str
== '-' ? ++str
, -1 : 1;
1532 while ((*str
<= '9') && (*str
>= '0'))
1533 ival
= 10 * ival
+ *str
++ - '0';
1538 /* this routine fixes the names that are generated by C++, ".this" is a good
1539 * example. The period does not work for the debugger, since it looks like
1540 * the syntax for a structure element, and thus it gets mightily confused
1542 * We also use this to strip the PsectAttribute hack from the name before we
1543 * write a debugger record */
1551 * Kill any leading "_"
1556 * Is there a Psect Attribute to skip??
1558 if (HAS_PSECT_ATTRIBUTES (pnt
))
1563 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1566 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1574 /* Here we fix the .this -> $this conversion */
1575 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1583 /* When defining a structure, this routine is called to find the name of
1584 * the actual structure. It is assumed that str points to the equal sign
1585 * in the definition, and it moves backward until it finds the start of the
1586 * name. If it finds a 0, then it knows that this structure def is in the
1587 * outermost level, and thus symbol_name points to the symbol name.
1590 get_struct_name (str
)
1595 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1598 return (char *) symbol_name
;
1600 while ((*pnt
!= ';') && (*pnt
!= '='))
1604 while ((*pnt
< '0') || (*pnt
> '9'))
1606 while ((*pnt
>= '0') && (*pnt
<= '9'))
1611 /* search symbol list for type number dbx_type. Return a pointer to struct */
1612 static struct VMS_DBG_Symbol
*
1613 find_symbol (dbx_type
)
1616 struct VMS_DBG_Symbol
*spnt
;
1618 spnt
= VMS_Symbol_type_list
[SYMTYP_HASH(dbx_type
)];
1619 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1621 if (spnt
->dbx_type
== dbx_type
)
1625 if (!spnt
|| spnt
->advanced
!= ALIAS
)
1627 return find_symbol(spnt
->type2
);
1631 #if 0 /* obsolete */
1632 /* this routine puts info into either Local or Asuffix, depending on the sign
1633 * of size. The reason is that it is easier to build the variable descriptor
1634 * backwards, while the array descriptor is best built forwards. In the end
1635 * they get put together, if there is not a struct/union/enum along the way
1651 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1655 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1658 Apoint
= MAX_DEBUG_RECORD
- 1;
1661 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1672 if (Apoint
+ size
>= MAX_DEBUG_RECORD
)
1675 Apoint
= MAX_DEBUG_RECORD
- 1;
1679 Asuffix
[Apoint
++] = (char) value
;
1682 md_number_to_chars (&Asuffix
[Apoint
], value
, size
);
1698 Local
[Lpnt
--] = (char) value
;
1702 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size
);
1706 /* this routine generates the array descriptor for a given array */
1708 array_suffix (spnt2
)
1709 struct VMS_DBG_Symbol
*spnt2
;
1711 struct VMS_DBG_Symbol
*spnt
;
1712 struct VMS_DBG_Symbol
*spnt1
;
1718 while (spnt
->advanced
!= ARRAY
)
1720 spnt
= find_symbol (spnt
->type2
);
1721 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1726 while (spnt1
->advanced
== ARRAY
)
1729 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1730 spnt1
= find_symbol (spnt1
->type2
);
1732 total_size
= total_size
* spnt1
->data_size
;
1733 fpush (spnt1
->data_size
, 2); /* element size */
1734 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1737 fpush (spnt1
->VMS_type
, 1); /* element type */
1738 fpush (DSC_K_CLASS_A
, 1); /* descriptor class */
1739 fpush (0, 4); /* base address */
1740 fpush (0, 1); /* scale factor -- not applicable */
1741 fpush (0, 1); /* digit count -- not applicable */
1742 fpush (0xc0, 1); /* flags: multiplier block & bounds present */
1743 fpush (rank
, 1); /* number of dimensions */
1744 fpush (total_size
, 4);
1745 fpush (0, 4); /* pointer to element [0][0]...[0] */
1747 while (spnt1
->advanced
== ARRAY
)
1749 fpush (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1750 spnt1
= find_symbol (spnt1
->type2
);
1753 while (spnt1
->advanced
== ARRAY
)
1755 fpush (spnt1
->index_min
, 4);
1756 fpush (spnt1
->index_max
, 4);
1757 spnt1
= find_symbol (spnt1
->type2
);
1761 /* this routine generates the start of a variable descriptor based upon
1762 * a struct/union/enum that has yet to be defined. We define this spot as
1763 * a new location, and save four bytes for the address. When the struct is
1764 * finally defined, then we can go back and plug in the correct address.
1767 new_forward_ref (dbx_type
)
1770 struct forward_ref
*fpnt
;
1771 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1772 fpnt
->next
= f_ref_root
;
1774 fpnt
->dbx_type
= dbx_type
;
1775 fpnt
->struc_numb
= ++structure_count
;
1776 fpnt
->resolved
= 'N';
1777 rpush (DST_K_TS_IND
, 1); /* indirect type specification */
1779 rpush (total_len
, 2);
1780 struct_number
= -fpnt
->struc_numb
;
1783 /* this routine generates the variable descriptor used to describe non-basic
1784 * variables. It calls itself recursively until it gets to the bottom of it
1785 * all, and then builds the descriptor backwards. It is easiest to do it this
1786 *way since we must periodically write length bytes, and it is easiest if we know
1787 *the value when it is time to write it.
1790 gen1 (spnt
, array_suffix_len
)
1791 struct VMS_DBG_Symbol
*spnt
;
1792 int array_suffix_len
;
1794 struct VMS_DBG_Symbol
*spnt1
;
1797 switch (spnt
->advanced
)
1800 rpush (DBG_S_C_VOID
, 1);
1802 rpush (total_len
, 2);
1806 if (array_suffix_len
== 0)
1808 rpush (spnt
->VMS_type
, 1);
1809 rpush (DBG_S_C_BASIC
, 1);
1811 rpush (total_len
, 2);
1815 rpush (DST_K_VFLAGS_DSC
, 1);
1816 rpush (DST_K_TS_DSC
, 1); /* descriptor type specification */
1822 struct_number
= spnt
->struc_numb
;
1823 if (struct_number
< 0)
1825 new_forward_ref (spnt
->dbx_type
);
1828 rpush (DBG_S_C_STRUCT
, 1);
1830 rpush (total_len
, 2);
1833 spnt1
= find_symbol (spnt
->type2
);
1836 new_forward_ref (spnt
->type2
);
1838 i
= gen1 (spnt1
, 0);
1840 { /* (*void) is a special case, do not put pointer suffix*/
1841 rpush (DBG_S_C_POINTER
, 1);
1843 rpush (total_len
, 2);
1848 while (spnt1
->advanced
== ARRAY
)
1850 spnt1
= find_symbol (spnt1
->type2
);
1853 as_tsktsk ("debugger forward reference error, dbx type %d",
1858 /* It is too late to generate forward references, so the user gets a message.
1859 * This should only happen on a compiler error */
1860 (void) gen1 (spnt1
, 1);
1862 array_suffix (spnt
);
1863 array_suffix_len
= Apoint
- i
;
1864 switch (spnt1
->advanced
)
1872 rpush (total_len
, 2);
1873 rpush (DST_K_VFLAGS_DSC
, 1);
1874 rpush (1, 1); /* flags: element value spec included */
1875 rpush (1, 1); /* one dimension */
1876 rpush (DBG_S_C_COMPLEX_ARRAY
, 1);
1878 total_len
+= array_suffix_len
+ 8;
1879 rpush (total_len
, 2);
1881 default: /* lint suppression */
1887 /* This generates a suffix for a variable. If it is not a defined type yet,
1888 * then dbx_type contains the type we are expecting so we can generate a
1889 * forward reference. This calls gen1 to build most of the descriptor, and
1890 * then it puts the icing on at the end. It then dumps whatever is needed
1891 * to get a complete descriptor (i.e. struct reference, array suffix ).
1894 generate_suffix (spnt
, dbx_type
)
1895 struct VMS_DBG_Symbol
*spnt
;
1898 static CONST
char pvoid
[6] = {
1899 5, /* record.length == 5 */
1900 DST_K_TYPSPEC
, /* record.type == 1 (type specification) */
1901 0, /* name.length == 0, no name follows */
1902 1, 0, /* type.length == 1 {2 bytes, little endian} */
1903 DBG_S_C_VOID
/* type.type == 5 (pointer to unspecified) */
1908 Lpnt
= MAX_DEBUG_RECORD
- 1;
1913 new_forward_ref (dbx_type
);
1916 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1917 return; /* no suffix needed */
1920 rpush (0, 1); /* no name (len==0) */
1921 rpush (DST_K_TYPSPEC
, 1);
1923 rpush (total_len
, 1);
1924 /* if the variable descriptor overflows the record, output a descriptor for
1925 * a pointer to void.
1927 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1929 as_warn ("Variable descriptor %d too complicated. Defined as void*", spnt
->dbx_type
);
1930 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1934 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1935 Local
[i
++] = Local
[++Lpnt
];
1937 /* we use this for a reference to a structure that has already been defined */
1938 if (struct_number
> 0)
1940 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1942 VMS_Store_Struct (struct_number
);
1944 /* we use this for a forward reference to a structure that has yet to be
1945 *defined. We store four bytes of zero to make room for the actual address once
1948 if (struct_number
< 0)
1950 struct_number
= -struct_number
;
1951 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1953 VMS_Def_Struct (struct_number
);
1954 COPY_LONG(&Local
[Lpnt
], 0L);
1956 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1961 Local
[Lpnt
++] = Asuffix
[i
++];
1963 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1967 /* "novel length" type doesn't work for simple atomic types */
1968 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
1969 #undef SETUP_BASIC_TYPES
1972 bitfield_suffix (spnt
, width
)
1973 struct VMS_DBG_Symbol
*spnt
;
1976 Local
[Lpnt
++] = 13; /* rec.len==13 */
1977 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* a type specification record */
1978 Local
[Lpnt
++] = 0; /* not named */
1979 COPY_SHORT(&Local
[Lpnt
], 9); /* typ.len==9 */
1981 Local
[Lpnt
++] = DST_K_TS_NOV_LENG
; /* This type is a "novel length"
1982 incarnation of some other type. */
1983 COPY_LONG(&Local
[Lpnt
], width
); /* size in bits == novel length */
1985 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1987 /* assert( spnt->struc_numb > 0 ); */
1988 VMS_Store_Struct (spnt
->struc_numb
); /* output 4 more bytes */
1991 /* Formally define a builtin type, so that it can serve as the target of
1992 an indirect reference. It makes bitfield_suffix() easier by avoiding
1993 the need to use a forward reference for the first occurrence of each
1994 type used in a bitfield. */
1996 setup_basic_type (spnt
)
1997 struct VMS_DBG_Symbol
*spnt
;
1999 #ifdef SETUP_BASIC_TYPES
2000 /* This would be very useful if "novel length" fields actually worked
2001 with basic types like they do with enumerated types. However,
2002 they do not, so this isn't worth doing just so that you can use
2003 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
2005 #ifndef SETUP_SYNONYM_TYPES
2006 /* This determines whether compatible things like `int' and `long int'
2007 ought to have distinct type records rather than sharing one. */
2008 struct VMS_DBG_Symbol
*spnt2
;
2010 /* first check whether this type has already been seen by another name */
2011 for (spnt2
= VMS_Symbol_type_list
[SYMTYP_HASH(spnt
->VMS_type
)];
2013 spnt2
= spnt2
->next
)
2014 if (spnt2
!= spnt
&& spnt2
->VMS_type
== spnt
->VMS_type
)
2016 spnt
->struc_numb
= spnt2
->struc_numb
;
2021 /* `structure number' doesn't really mean `structure'; it means an index
2022 into a linker maintained set of saved locations which can be referenced
2024 spnt
->struc_numb
= ++structure_count
;
2025 VMS_Def_Struct (spnt
->struc_numb
); /* remember where this type lives */
2026 /* define the simple scalar type */
2027 Local
[Lpnt
++] = 6 + strlen (symbol_name
) + 2; /* rec.len */
2028 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* rec.typ==type specification */
2029 Local
[Lpnt
++] = strlen (symbol_name
) + 2;
2030 Local
[Lpnt
++] = '_'; /* prefix name with "__" */
2031 Local
[Lpnt
++] = '_';
2032 for (p
= symbol_name
; *p
; p
++)
2033 Local
[Lpnt
++] = *p
== ' ' ? '_' : *p
;
2034 COPY_SHORT(&Local
[Lpnt
], 2); /* typ.len==2 */
2036 Local
[Lpnt
++] = DST_K_TS_ATOM
; /* typ.kind is simple type */
2037 Local
[Lpnt
++] = spnt
->VMS_type
; /* typ.type */
2038 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2040 #endif /* SETUP_BASIC_TYPES */
2043 /* This routine generates a symbol definition for a C symbol for the debugger.
2044 * It takes a psect and offset for global symbols; if psect < 0, then this is
2045 * a local variable and the offset is relative to FP. In this case it can
2046 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2049 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2050 struct VMS_DBG_Symbol
*spnt
;
2059 /* if there are bad characters in name, convert them */
2060 Name_pnt
= fix_name (Name
);
2062 len
= strlen(Name_pnt
);
2064 { /* this is a local variable, referenced to SP */
2065 Local
[i
++] = 7 + len
;
2066 Local
[i
++] = spnt
->VMS_type
;
2067 Local
[i
++] = (Offset
> 0) ? DBG_C_FUNCTION_PARAM
: DBG_C_LOCAL_SYM
;
2068 COPY_LONG (&Local
[i
], Offset
);
2073 Local
[i
++] = 7 + len
;
2074 Local
[i
++] = spnt
->VMS_type
;
2075 Local
[i
++] = DST_K_VALKIND_ADDR
;
2076 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2078 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2081 while (*Name_pnt
!= '\0')
2082 Local
[i
++] = *Name_pnt
++;
2083 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2084 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2085 generate_suffix (spnt
, 0);
2089 /* This routine parses the stabs entries in order to make the definition
2090 * for the debugger of local symbols and function parameters
2093 VMS_local_stab_Parse (sp
)
2099 struct VMS_DBG_Symbol
*spnt
;
2103 str
= S_GET_NAME (sp
);
2104 pnt
= (char *) strchr (str
, ':');
2105 if (pnt
== (char *) NULL
)
2106 return; /* no colon present */
2107 pnt1
= pnt
++; /* save this for later, and skip colon */
2109 return; /* ignore static constants */
2111 /* there is one little catch that we must be aware of. Sometimes function
2112 * parameters are optimized into registers, and the compiler, in its infiite
2113 * wisdom outputs stabs records for *both*. In general we want to use the
2114 * register if it is present, so we must search the rest of the symbols for
2115 * this function to see if this parameter is assigned to a register.
2123 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2125 if (!S_IS_DEBUG (sp1
))
2127 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2129 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2130 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2132 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2134 str1
= S_GET_NAME (sp1
); /* and get the name */
2136 while (*pnt2
!= ':')
2143 if ((*str1
!= ':') || (*pnt2
!= ':'))
2145 return; /* they are the same! lets skip this one */
2147 /* first find the dbx symbol type from list, and then find VMS type */
2148 pnt
++; /* skip p in case no register */
2151 pnt
= cvt_integer (pnt
, &dbx_type
);
2152 spnt
= find_symbol (dbx_type
);
2154 return; /*Dunno what this is*/
2156 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2157 *pnt1
= ':'; /* and restore the string */
2161 /* This routine parses a stabs entry to find the information required to define
2162 * a variable. It is used for global and static variables.
2163 * Basically we need to know the address of the symbol. With older versions
2164 * of the compiler, const symbols are
2165 * treated differently, in that if they are global they are written into the
2166 * text psect. The global symbol entry for such a const is actually written
2167 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2168 * of psects, we must search the entry points as well. static consts are even
2169 * harder, since they are never assigned a memory address. The compiler passes
2170 * a stab to tell us the value, but I am not sure what to do with it.
2174 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2177 int type1
, type2
, Text_Psect
;
2183 struct VMS_DBG_Symbol
*spnt
;
2184 struct VMS_Symbol
*vsp
;
2188 str
= S_GET_NAME (sp
);
2189 pnt
= (char *) strchr (str
, ':');
2190 if (pnt
== (char *) NULL
)
2191 return; /* no colon present */
2192 pnt1
= pnt
; /* save this for later*/
2194 if (*pnt
== expected_type
)
2196 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2197 spnt
= find_symbol (dbx_type
);
2198 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2199 return; /*Dunno what this is*/
2200 /* now we need to search the symbol table to find the psect and offset for
2205 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2207 pnt
= S_GET_NAME (vsp
->Symbol
);
2208 if (pnt
!= (char *) NULL
)
2210 /* make sure name is the same, and make sure correct symbol type */
2211 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2212 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2213 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2217 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2219 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2220 *pnt1
= ':'; /* and restore the string */
2223 /* the symbol was not in the symbol list, but it may be an "entry point"
2224 if it was a constant */
2225 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2228 * Dispatch on STAB type
2230 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2232 pnt
= S_GET_NAME (sp1
);
2235 if (strcmp (pnt
, str
) == 0)
2237 if (!gave_compiler_message
&& expected_type
== 'G')
2239 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2240 printf ("global constant(s) in the text psect. These will not be available to\n");
2241 printf ("other modules, since this is not the correct way to handle this. You\n");
2242 printf ("have two options: 1) get a patched compiler that does not put global\n");
2243 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2244 printf ("definitions of global variables in your source module(s). Don't say\n");
2245 printf ("I didn't warn you!");
2246 gave_compiler_message
= 1;
2248 VMS_DBG_record (spnt
,
2253 *S_GET_NAME (sp1
) = 'L';
2254 /* fool assembler to not output this
2255 * as a routine in the TBT */
2260 *pnt1
= ':'; /* and restore the string */
2265 VMS_GSYM_Parse (sp
, Text_Psect
)
2268 { /* Global variables */
2269 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2274 VMS_LCSYM_Parse (sp
, Text_Psect
)
2277 { /* Static symbols - uninitialized */
2278 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2282 VMS_STSYM_Parse (sp
, Text_Psect
)
2285 { /* Static symbols - initialized */
2286 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2290 /* for register symbols, we must figure out what range of addresses within the
2291 * psect are valid. We will use the brackets in the stab directives to give us
2292 * guidance as to the PC range that this variable is in scope. I am still not
2293 * completely comfortable with this but as I learn more, I seem to get a better
2294 * handle on what is going on.
2298 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2299 symbolS
*sp
, *Current_Routine
;
2306 struct VMS_DBG_Symbol
*spnt
;
2310 int Min_Offset
= -1; /* min PC of validity */
2311 int Max_Offset
= 0; /* max PC of validity */
2314 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2317 * Dispatch on STAB type
2319 switch (S_GET_RAW_TYPE (symbolP
))
2323 Min_Offset
= S_GET_VALUE (symbolP
);
2327 Max_Offset
= S_GET_VALUE (symbolP
) - 1;
2330 if ((Min_Offset
!= -1) && (bcnt
== 0))
2332 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2334 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2335 if (*pnt
== 'F' || *pnt
== 'f') break;
2339 /* Check to see that the addresses were defined. If not, then there were no
2340 * brackets in the function, and we must try to search for the next function.
2341 * Since functions can be in any order, we should search all of the symbol
2342 * list to find the correct ending address. */
2343 if (Min_Offset
== -1)
2345 int Max_Source_Offset
;
2347 Min_Offset
= S_GET_VALUE (sp
);
2348 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2351 * Dispatch on STAB type
2353 switch (S_GET_RAW_TYPE (symbolP
))
2355 case N_TEXT
| N_EXT
:
2356 This_Offset
= S_GET_VALUE (symbolP
);
2357 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2358 Max_Offset
= This_Offset
;
2361 This_Offset
= S_GET_VALUE (symbolP
);
2362 if (This_Offset
> Max_Source_Offset
)
2363 Max_Source_Offset
= This_Offset
;
2367 /* if this is the last routine, then we use the PC of the last source line
2368 * as a marker of the max PC for which this reg is valid */
2369 if (Max_Offset
== 0x7fffffff)
2370 Max_Offset
= Max_Source_Offset
;
2373 str
= S_GET_NAME (sp
);
2374 pnt
= (char *) strchr (str
, ':');
2375 if (pnt
== (char *) NULL
)
2376 return; /* no colon present */
2377 pnt1
= pnt
; /* save this for later*/
2381 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2382 spnt
= find_symbol (dbx_type
);
2384 return; /*Dunno what this is yet*/
2386 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2388 Local
[i
++] = 25 + len
;
2389 Local
[i
++] = spnt
->VMS_type
;
2390 Local
[i
++] = DST_K_VFLAGS_TVS
; /* trailing value specified */
2391 COPY_LONG(&Local
[i
], 1 + len
); /* relative offset, beyond name */
2393 Local
[i
++] = len
; /* name length (ascic prefix) */
2394 while (*pnt
!= '\0')
2395 Local
[i
++] = *pnt
++;
2396 Local
[i
++] = DST_K_VS_FOLLOWS
; /* value specification follows */
2397 COPY_SHORT(&Local
[i
], 15); /* length of rest of record */
2399 Local
[i
++] = DST_K_VS_ALLOC_SPLIT
; /* split lifetime */
2400 Local
[i
++] = 1; /* one binding follows */
2401 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2403 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2404 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2405 Local
[i
++] = DST_K_VALKIND_REG
; /* nested value spec */
2406 COPY_LONG(&Local
[i
], S_GET_VALUE (sp
));
2408 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2410 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2411 generate_suffix (spnt
, 0);
2414 /* this function examines a structure definition, checking all of the elements
2415 * to make sure that all of them are fully defined. The only thing that we
2416 * kick out are arrays of undefined structs, since we do not know how big
2417 * they are. All others we can handle with a normal forward reference.
2420 forward_reference (pnt
)
2424 struct VMS_DBG_Symbol
*spnt
;
2425 struct VMS_DBG_Symbol
*spnt1
;
2426 pnt
= cvt_integer (pnt
+ 1, &i
);
2428 return 0; /* no forward references */
2431 pnt
= (char *) strchr (pnt
, ':');
2432 pnt
= cvt_integer (pnt
+ 1, &i
);
2433 spnt
= find_symbol (i
);
2434 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2435 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2438 spnt1
= find_symbol (spnt
->type2
);
2439 if ((spnt
->advanced
== ARRAY
) &&
2440 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2442 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2447 pnt
= cvt_integer (pnt
+ 1, &i
);
2448 pnt
= cvt_integer (pnt
+ 1, &i
);
2449 } while (*++pnt
!= ';');
2450 return 0; /* no forward refences found */
2453 /* Used to check a single element of a structure on the final pass*/
2456 final_forward_reference (spnt
)
2457 struct VMS_DBG_Symbol
*spnt
;
2459 struct VMS_DBG_Symbol
*spnt1
;
2461 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2463 spnt1
= find_symbol(spnt
->type2
);
2464 if (spnt
->advanced
== ARRAY
&& !spnt1
) return 1;
2467 return 0; /* no forward refences found */
2470 /* This routine parses the stabs directives to find any definitions of dbx type
2471 * numbers. It makes a note of all of them, creating a structure element
2472 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2473 * debugger that describes the struct/union/enum, so that further references
2474 * to these data types will be by number
2475 * We have to process pointers right away, since there can be references
2476 * to them later in the same stabs directive. We cannot have forward
2477 * references to pointers, (but we can have a forward reference to a pointer to
2478 * a structure/enum/union) and this is why we process them immediately.
2479 * After we process the pointer, then we search for defs that are nested even
2481 * 8/15/92: We have to process arrays right away too, because there can
2482 * be multiple references to identical array types in one structure
2483 * definition, and only the first one has the definition. (We tend to
2484 * parse from the back going forward.
2487 VMS_typedef_parse (str
)
2495 struct forward_ref
*fpnt
;
2496 int i1
, i2
, i3
, len
;
2497 struct VMS_DBG_Symbol
*spnt
;
2498 struct VMS_DBG_Symbol
*spnt1
;
2500 /* check for any nested def's */
2501 pnt
= (char *) strchr (str
+ 1, '=');
2502 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2503 && (str
[1] != 'a' || str
[2] != 'r'))
2504 if (VMS_typedef_parse (pnt
) == 1)
2506 /* now find dbx_type of entry */
2509 { /* check for static constants */
2510 *str
= '\0'; /* for now we ignore them */
2513 while ((*pnt
<= '9') && (*pnt
>= '0'))
2515 pnt
++; /* and get back to the number */
2516 cvt_integer (pnt
, &i1
);
2517 spnt
= find_symbol (i1
);
2518 /* first we see if this has been defined already, due to a forward reference*/
2521 i2
= SYMTYP_HASH(i1
);
2522 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2523 spnt
->next
= VMS_Symbol_type_list
[i2
];
2524 VMS_Symbol_type_list
[i2
] = spnt
;
2525 spnt
->dbx_type
= i1
; /* and save the type */
2526 spnt
->type2
= spnt
->VMS_type
= spnt
->data_size
= 0;
2527 spnt
->index_min
= spnt
->index_max
= spnt
->struc_numb
= 0;
2529 /* for structs and unions, do a partial parse, otherwise we sometimes get
2530 * circular definitions that are impossible to resolve. We read enough info
2531 * so that any reference to this type has enough info to be resolved
2533 pnt
= str
+ 1; /* point to character past equal sign */
2534 if ((*pnt
== 'u') || (*pnt
== 's'))
2537 if ((*pnt
<= '9') && (*pnt
>= '0'))
2539 if (type_check ("void"))
2540 { /* this is the void symbol */
2542 spnt
->advanced
= VOID
;
2545 if (type_check ("unknown type"))
2548 spnt
->advanced
= UNKNOWN
;
2551 pnt1
= cvt_integer(pnt
,&i1
);
2552 if(i1
!= spnt
->dbx_type
)
2554 spnt
->advanced
= ALIAS
;
2559 as_tsktsk ("debugginer output: %d is an unknown untyped variable.",
2561 return 1; /* do not know what this is */
2563 /* now define this module*/
2564 pnt
= str
+ 1; /* point to character past equal sign */
2568 spnt
->advanced
= BASIC
;
2569 if (type_check ("int"))
2571 spnt
->VMS_type
= DBG_S_C_SLINT
;
2572 spnt
->data_size
= 4;
2574 else if (type_check ("long int"))
2576 spnt
->VMS_type
= DBG_S_C_SLINT
;
2577 spnt
->data_size
= 4;
2579 else if (type_check ("unsigned int"))
2581 spnt
->VMS_type
= DBG_S_C_ULINT
;
2582 spnt
->data_size
= 4;
2584 else if (type_check ("long unsigned int"))
2586 spnt
->VMS_type
= DBG_S_C_ULINT
;
2587 spnt
->data_size
= 4;
2589 else if (type_check ("short int"))
2591 spnt
->VMS_type
= DBG_S_C_SSINT
;
2592 spnt
->data_size
= 2;
2594 else if (type_check ("short unsigned int"))
2596 spnt
->VMS_type
= DBG_S_C_USINT
;
2597 spnt
->data_size
= 2;
2599 else if (type_check ("char"))
2601 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2602 spnt
->data_size
= 1;
2604 else if (type_check ("signed char"))
2606 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2607 spnt
->data_size
= 1;
2609 else if (type_check ("unsigned char"))
2611 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2612 spnt
->data_size
= 1;
2614 else if (type_check ("float"))
2616 spnt
->VMS_type
= DBG_S_C_REAL4
;
2617 spnt
->data_size
= 4;
2619 else if (type_check ("double"))
2621 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2622 spnt
->data_size
= 8;
2624 else if (type_check ("long double"))
2626 /* same as double, at least for now */
2627 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2628 spnt
->data_size
= 8;
2630 else if (type_check ("long long int"))
2632 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2633 spnt
->data_size
= 8;
2635 else if (type_check ("long long unsigned int"))
2637 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2638 spnt
->data_size
= 8;
2640 else if (type_check ("complex float"))
2642 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2643 spnt
->data_size
= 2 * 4;
2645 else if (type_check ("complex double"))
2647 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2648 spnt
->data_size
= 2 * 8;
2650 else if (type_check ("complex long double"))
2652 /* same as complex double, at least for now */
2653 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2654 spnt
->data_size
= 2 * 8;
2659 * Shouldn't get here, but if we do, something
2660 * more substantial ought to be done...
2663 spnt
->data_size
= 0;
2665 if (spnt
->VMS_type
!= 0)
2666 setup_basic_type(spnt
);
2667 pnt1
= (char *) strchr (str
, ';') + 1;
2671 spnt
->advanced
= (*pnt
== 's') ? STRUCT
: UNION
;
2672 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2673 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2674 if (!final_pass
&& forward_reference(pnt
))
2676 spnt
->struc_numb
= -1;
2679 spnt
->struc_numb
= ++structure_count
;
2681 pnt
= get_struct_name (str
);
2682 VMS_Def_Struct (spnt
->struc_numb
);
2684 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2685 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2687 fpnt
->resolved
= 'Y';
2688 VMS_Set_Struct (fpnt
->struc_numb
);
2689 VMS_Store_Struct (spnt
->struc_numb
);
2693 VMS_Set_Struct (spnt
->struc_numb
);
2695 Local
[i
++] = 11 + strlen (pnt
);
2696 Local
[i
++] = DBG_S_C_STRUCT_START
;
2697 Local
[i
++] = DST_K_VFLAGS_NOVAL
; /* structure definition only */
2698 COPY_LONG(&Local
[i
], 0L); /* hence value is unused */
2700 Local
[i
++] = strlen (pnt
);
2702 while (*pnt2
!= '\0')
2703 Local
[i
++] = *pnt2
++;
2704 i2
= spnt
->data_size
* 8; /* number of bits */
2705 COPY_LONG(&Local
[i
], i2
);
2707 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2709 if (pnt
!= symbol_name
)
2711 pnt
+= strlen (pnt
);
2713 } /* replace colon for later */
2714 while (*++pnt1
!= ';')
2716 pnt
= (char *) strchr (pnt1
, ':');
2719 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2720 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2721 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2722 spnt1
= find_symbol (dtype
);
2723 len
= strlen (pnt2
);
2724 if (spnt1
&& (spnt1
->advanced
== BASIC
|| spnt1
->advanced
== ENUM
)
2725 && ((i3
!= spnt1
->data_size
* 8) || (i2
% 8 != 0)))
2727 if (USE_BITSTRING_DESCRIPTOR (spnt1
))
2729 /* This uses a type descriptor, which doesn't work if
2730 the enclosing structure has been placed in a register.
2731 Also, enum bitfields degenerate to simple integers. */
2732 int unsigned_type
= (spnt1
->VMS_type
== DBG_S_C_ULINT
2733 || spnt1
->VMS_type
== DBG_S_C_USINT
2734 || spnt1
->VMS_type
== DBG_S_C_UCHAR
2735 || spnt1
->VMS_type
== DBG_S_C_UQUAD
2736 || spnt1
->advanced
== ENUM
); /* (approximate) */
2738 fpush (19 + len
, 1);
2739 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2740 fpush (DST_K_VFLAGS_DSC
, 1); /* specified by descriptor */
2741 fpush (1 + len
, 4); /* relative offset to descriptor */
2742 fpush (len
, 1); /* length byte (ascic prefix) */
2743 while (*pnt2
!= '\0') /* name bytes */
2745 fpush (i3
, 2); /* dsc length == size of bitfield */
2746 /* dsc type == un?signed bitfield */
2747 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2748 fpush (DSC_K_CLASS_UBS
, 1); /* dsc class == unaligned bitstring */
2749 fpush (0x00, 4); /* dsc pointer == zeroes */
2750 fpush (i2
, 4); /* start position */
2751 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2756 /* Use a "novel length" type specification, which works
2757 right for register structures and for enum bitfields
2758 but results in larger object modules. */
2759 Local
[i
++] = 7 + len
;
2760 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
; /* type spec follows */
2761 Local
[i
++] = DBG_S_C_STRUCT_ITEM
; /* value is a bit offset */
2762 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2764 Local
[i
++] = strlen (pnt2
);
2765 while (*pnt2
!= '\0')
2766 Local
[i
++] = *pnt2
++;
2767 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2769 bitfield_suffix (spnt1
, i3
);
2773 { /* not a bitfield */
2774 /* check if this is a forward reference */
2775 if(final_pass
&& final_forward_reference(spnt1
))
2777 as_tsktsk ("debugger output: structure element `%s' has undefined type",
2781 Local
[i
++] = 7 + len
;
2782 Local
[i
++] = spnt1
? spnt1
->VMS_type
: DBG_S_C_ADVANCED_TYPE
;
2783 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2784 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2786 Local
[i
++] = strlen (pnt2
);
2787 while (*pnt2
!= '\0')
2788 Local
[i
++] = *pnt2
++;
2789 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2792 generate_suffix (spnt1
, dtype
);
2793 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2794 generate_suffix (spnt1
, 0);
2798 Local
[i
++] = 0x01; /* length byte */
2799 Local
[i
++] = DBG_S_C_STRUCT_END
;
2800 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2804 spnt
->advanced
= ENUM
;
2805 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2806 spnt
->struc_numb
= ++structure_count
;
2807 spnt
->data_size
= 4;
2808 VMS_Def_Struct (spnt
->struc_numb
);
2810 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2811 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2813 fpnt
->resolved
= 'Y';
2814 VMS_Set_Struct (fpnt
->struc_numb
);
2815 VMS_Store_Struct (spnt
->struc_numb
);
2819 VMS_Set_Struct (spnt
->struc_numb
);
2821 len
= strlen (symbol_name
);
2822 Local
[i
++] = 3 + len
;
2823 Local
[i
++] = DBG_S_C_ENUM_START
;
2824 Local
[i
++] = 4 * 8; /* enum values are 32 bits */
2827 while (*pnt2
!= '\0')
2828 Local
[i
++] = *pnt2
++;
2829 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2831 while (*++pnt
!= ';')
2833 pnt1
= (char *) strchr (pnt
, ':');
2835 pnt1
= cvt_integer (pnt1
, &i1
);
2837 Local
[i
++] = 7 + len
;
2838 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2839 Local
[i
++] = DST_K_VALKIND_LITERAL
;
2840 COPY_LONG (&Local
[i
], i1
);
2844 while (*pnt
!= '\0')
2845 Local
[i
++] = *pnt
++;
2846 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2848 pnt
= pnt1
; /* Skip final semicolon */
2850 Local
[i
++] = 0x01; /* len byte */
2851 Local
[i
++] = DBG_S_C_ENUM_END
;
2852 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2857 spnt
->advanced
= ARRAY
;
2858 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2859 pnt
= (char *) strchr (pnt
, ';');
2862 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2863 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2864 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2865 pnt
= (char *) strchr (str
+ 1, '=');
2866 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2870 spnt
->advanced
= FUNCTION
;
2871 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2872 /* this masquerades as a basic type*/
2873 spnt
->data_size
= 4;
2874 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2877 spnt
->advanced
= POINTER
;
2878 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2879 spnt
->data_size
= 4;
2880 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2881 pnt
= (char *) strchr (str
+ 1, '=');
2882 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2886 spnt
->advanced
= UNKNOWN
;
2888 as_tsktsk ("debugger output: %d is an unknown type of variable.",
2890 return 1; /* unable to decipher */
2892 /* this removes the evidence of the definition so that the outer levels of
2893 parsing do not have to worry about it */
2895 while (*pnt1
!= '\0')
2903 * This is the root routine that parses the stabs entries for definitions.
2904 * it calls VMS_typedef_parse, which can in turn call itself.
2905 * We need to be careful, since sometimes there are forward references to
2906 * other symbol types, and these cannot be resolved until we have completed
2909 * Also check and see if we are using continuation stabs, if we are, then
2910 * paste together the entire contents of the stab before we pass it to
2911 * VMS_typedef_parse.
2920 char *parse_buffer
= 0;
2922 int incomplete
, pass
, incom1
;
2923 struct forward_ref
*fpnt
;
2931 incom1
= incomplete
;
2933 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2936 * Deal with STAB symbols
2938 if (S_IS_DEBUG (sp
))
2941 * Dispatch on STAB type
2943 switch (S_GET_RAW_TYPE (sp
))
2951 case N_FUN
: /*sometimes these contain typedefs*/
2952 str
= S_GET_NAME (sp
);
2954 pnt
= str
+ strlen(str
) -1;
2955 if (*pnt
== '?') /* Continuation stab. */
2962 tlen
+= strlen(str
) - 1;
2963 spnext
= symbol_next (spnext
);
2964 str
= S_GET_NAME (spnext
);
2965 pnt
= str
+ strlen(str
) - 1;
2966 } while (*pnt
== '?');
2967 tlen
+= strlen(str
);
2968 parse_buffer
= (char *) xmalloc (tlen
+ 1);
2969 strcpy(parse_buffer
, S_GET_NAME (sp
));
2970 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2974 spnext
= symbol_next (spnext
);
2975 str
= S_GET_NAME (spnext
);
2976 strcat (pnt2
, S_GET_NAME (spnext
));
2977 pnt2
+= strlen(str
) - 1;
2978 *str
= '\0'; /* Erase this string */
2979 if (*pnt2
!= '?') break;
2985 pnt
= (char *) strchr (str
, ':');
2986 if (pnt
!= (char *) NULL
)
2990 pnt2
= (char *) strchr (pnt1
, '=');
2991 if (pnt2
!= (char *) NULL
)
2992 incomplete
+= VMS_typedef_parse (pnt2
);
2994 /* At this point the parse buffer should just contain name:nn.
2995 If it does not, then we are in real trouble. Anyway,
2996 this is always shorter than the original line. */
2997 strcpy(S_GET_NAME (sp
), parse_buffer
);
2998 free (parse_buffer
);
3001 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
3008 /* Make one last pass, if needed, and define whatever we can that is left */
3009 if(final_pass
== 0 && incomplete
== incom1
)
3012 incom1
++; /* Force one last pass through */
3014 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
3015 /* repeat until all refs resolved if possible */
3016 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
3017 if (incomplete
!= 0)
3019 as_tsktsk ("debugger output: Unable to resolve %d circular references.",
3024 while (fpnt
!= (struct forward_ref
*) NULL
)
3026 if (fpnt
->resolved
!= 'Y')
3028 if (find_symbol (fpnt
->dbx_type
) !=
3029 (struct VMS_DBG_Symbol
*) NULL
)
3031 as_tsktsk ("debugger forward reference error, dbx type %d",
3036 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
3037 pnt2
= (char *) strchr (&fixit
[1], '=');
3038 VMS_typedef_parse (pnt2
);
3045 Define_Local_Symbols (s1
, s2
)
3049 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
3051 if (symbolP1
== (symbolS
*) NULL
)
3053 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3055 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3056 if (*pnt
== 'F' || *pnt
== 'f') break;
3059 * Deal with STAB symbols
3061 if (S_IS_DEBUG (symbolP1
))
3064 * Dispatch on STAB type
3066 switch (S_GET_RAW_TYPE (symbolP1
))
3070 VMS_local_stab_Parse (symbolP1
);
3073 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
3081 /* This function crawls the symbol chain searching for local symbols that need
3082 * to be described to the debugger. When we enter a new scope with a "{", it
3083 * creates a new "block", which helps the debugger keep track of which scope
3084 * we are currently in.
3088 Define_Routine (symbolP
, Level
)
3098 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
3100 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
3102 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
3103 if (*pnt
== 'F' || *pnt
== 'f') break;
3106 * Deal with STAB symbols
3108 if (S_IS_DEBUG (symbolP1
))
3111 * Dispatch on STAB type
3113 switch (S_GET_RAW_TYPE (symbolP1
))
3118 sprintf (str
, "$%d", rcount
++);
3119 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
3121 Offset
= S_GET_VALUE (symbolP1
);
3122 Define_Local_Symbols (sstart
, symbolP1
);
3124 Define_Routine (symbolP1
, Level
+ 1);
3126 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
3135 /* we end up here if there were no brackets in this function. Define
3137 Define_Local_Symbols (sstart
, (symbolS
*) 0);
3143 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
3145 symbolS
*Curr_Routine
;
3148 Current_Routine
= Curr_Routine
;
3149 Text_Psect
= Txt_Psect
;
3150 Define_Routine (symbolP
, 0);
3157 #include <sys/types.h>
3160 /* Manufacure a VMS like time on a unix based system. */
3161 get_VMS_time_on_unix (Now
)
3167 pnt
= ctime (&timeb
);
3173 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3176 #endif /* not VMS */
3178 * Write the MHD (Module Header) records
3181 Write_VMS_MHD_Records ()
3183 register const char *cp
;
3191 char Module_Name
[256];
3195 * We are writing a module header record
3197 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3199 * ***************************
3200 * *MAIN MODULE HEADER RECORD*
3201 * ***************************
3203 * Store record type and header type
3205 PUT_CHAR (OBJ_S_C_HDR
);
3206 PUT_CHAR (MHD_S_C_MHD
);
3208 * Structure level is 0
3210 PUT_CHAR (OBJ_S_C_STRLVL
);
3212 * Maximum record size is size of the object record buffer
3214 PUT_SHORT (sizeof (Object_Record_Buffer
));
3216 * Get module name (the FILENAME part of the object file)
3222 if ((*cp
== ']') || (*cp
== '>') ||
3223 (*cp
== ':') || (*cp
== '/'))
3229 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3233 * Limit it to 31 characters and store in the object record
3235 while (--cp1
>= Module_Name
)
3238 if (strlen (Module_Name
) > 31)
3240 if (flag_hash_long_names
)
3241 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3242 Module_Name
[31] = 0;
3244 PUT_COUNTED_STRING (Module_Name
);
3246 * Module Version is "V1.0"
3248 PUT_COUNTED_STRING ("V1.0");
3250 * Creation time is "now" (17 chars of time string)
3253 get_VMS_time_on_unix (&Now
[0]);
3255 Descriptor
.Size
= 17;
3256 Descriptor
.Ptr
= Now
;
3257 sys$
asctim (0, &Descriptor
, 0, 0);
3259 for (i
= 0; i
< 17; i
++)
3262 * Patch time is "never" (17 zeros)
3264 for (i
= 0; i
< 17; i
++)
3269 Flush_VMS_Object_Record_Buffer ();
3271 * *************************
3272 * *LANGUAGE PROCESSOR NAME*
3273 * *************************
3275 * Store record type and header type
3277 PUT_CHAR (OBJ_S_C_HDR
);
3278 PUT_CHAR (MHD_S_C_LNM
);
3280 * Store language processor name and version
3281 * (not a counted string!)
3283 * This is normally supplied by the gcc driver for the command line
3284 * which invokes gas. If absent, we fall back to gas's version.
3286 cp
= compiler_version_string
;
3299 Flush_VMS_Object_Record_Buffer ();
3304 * Write the EOM (End Of Module) record
3307 Write_VMS_EOM_Record (Psect
, Offset
)
3312 * We are writing an end-of-module record
3313 * (this assumes that the entry point will always be in a psect
3314 * represented by a single byte, which is the case for code in
3317 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3321 PUT_CHAR (OBJ_S_C_EOM
);
3323 * Store the error severity (0)
3327 * Store the entry point, if it exists
3332 * Store the entry point Psect
3336 * Store the entry point Psect offset
3343 Flush_VMS_Object_Record_Buffer ();
3347 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3353 register unsigned char *p
= ptr
;
3354 register unsigned char *end
= p
+ strlen (ptr
);
3355 register unsigned char c
;
3356 register int hash
= 0;
3361 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3367 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3370 VMS_Case_Hack_Symbol (In
, Out
)
3380 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3382 int Case_Hack_Bits
= 0;
3384 static char Hex_Table
[16] =
3385 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3388 * Kill any leading "_"
3390 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3393 new_name
= Out
; /* save this for later*/
3395 #if barfoo /* Dead code */
3396 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3400 /* We may need to truncate the symbol, save the hash for later*/
3401 result
= (strlen (In
) > 23) ? hash_string (In
) : 0;
3403 * Is there a Psect Attribute to skip??
3405 if (HAS_PSECT_ATTRIBUTES (In
))
3410 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3413 if ((In
[0] == '$') && (In
[1] == '$'))
3423 /* if (strlen(In) > 31 && flag_hash_long_names)
3424 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3426 * Do the case conversion
3428 i
= 23; /* Maximum of 23 chars */
3429 while (*In
&& (--i
>= 0))
3431 Case_Hack_Bits
<<= 1;
3434 if ((destructor
== 1) && (i
== 21))
3436 switch (vms_name_mapping
)
3441 Case_Hack_Bits
|= 1;
3443 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3446 case 3: *Out
++ = *In
++;
3452 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3458 * If we saw a dollar sign, we don't do case hacking
3460 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3464 * If we have more than 23 characters and everything is lowercase
3465 * we can insert the full 31 characters
3470 * We have more than 23 characters
3471 * If we must add the case hack, then we have truncated the str
3475 if (Case_Hack_Bits
== 0)
3478 * And so far they are all lower case:
3479 * Check up to 8 more characters
3480 * and ensure that they are lowercase
3482 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3483 if (isupper(In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3489 if ((i
== 8) || (In
[i
] == 0))
3492 * They are: Copy up to 31 characters
3493 * to the output string
3496 while ((--i
>= 0) && (*In
))
3497 switch (vms_name_mapping
){
3498 case 0: *Out
++ = islower(*In
) ?
3502 case 3: *Out
++ = *In
++;
3504 case 2: *Out
++ = isupper(*In
) ?
3513 * If there were any uppercase characters in the name we
3514 * take on the case hacking string
3517 /* Old behavior for regular GNU-C compiler */
3518 if (!flag_hash_long_names
)
3520 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3525 for (i
= 0; i
< 6; i
++)
3527 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3528 Case_Hack_Bits
>>= 4;
3534 Out
= pnt
; /*Cut back to 23 characters maximum */
3536 for (i
= 0; i
< 7; i
++)
3538 init
= result
& 0x01f;
3539 *Out
++ = (init
< 10) ? ('0' + init
) : ('A' + init
- 10);
3540 result
= result
>> 5;
3548 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3549 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3554 * Scan a symbol name for a psect attribute specification
3556 #define GLOBALSYMBOL_BIT 0x10000
3557 #define GLOBALVALUE_BIT 0x20000
3561 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3563 int *Attribute_Pointer
;
3574 {"PIC", GPS_S_M_PIC
},
3575 {"LIB", GPS_S_M_LIB
},
3576 {"OVR", GPS_S_M_OVR
},
3577 {"REL", GPS_S_M_REL
},
3578 {"GBL", GPS_S_M_GBL
},
3579 {"SHR", GPS_S_M_SHR
},
3580 {"EXE", GPS_S_M_EXE
},
3582 {"WRT", GPS_S_M_WRT
},
3583 {"VEC", GPS_S_M_VEC
},
3584 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3585 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3595 * Check for a PSECT attribute list
3597 if (!HAS_PSECT_ATTRIBUTES (Name
))
3598 return; /* If not, return */
3600 * Skip the attribute list indicator
3602 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3604 * Process the attributes ("_" separated, "$" terminated)
3606 while (*Name
!= '$')
3609 * Assume not negating
3615 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3618 * We are negating (and skip the NO)
3624 * Find the token delimiter
3627 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3630 * Look for the token in the attribute list
3632 for (i
= 0; Attributes
[i
].Name
; i
++)
3635 * If the strings match, set/clear the attr.
3637 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3643 *Attribute_Pointer
&=
3644 ~Attributes
[i
].Value
;
3646 *Attribute_Pointer
|=
3647 Attributes
[i
].Value
;
3655 * Now skip the attribute
3664 #define GBLSYM_REF 0
3665 #define GBLSYM_DEF 1
3666 #define GBLSYM_VAL 2
3667 #define GBLSYM_LCL 4 /* not GBL after all... */
3670 * Define a global symbol (or possibly a local one).
3673 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Flags
)
3682 * We are writing a GSD record
3684 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3686 * If the buffer is empty we must insert the GSD record type
3688 if (Object_Record_Offset
== 0)
3689 PUT_CHAR (OBJ_S_C_GSD
);
3691 * We are writing a Global (or local) symbol definition subrecord.
3693 PUT_CHAR ((Flags
& GBLSYM_LCL
) != 0 ? GSD_S_C_LSY
:
3694 ((unsigned) Psect_Number
<= 255) ? GSD_S_C_SYM
: GSD_S_C_SYMW
);
3696 * Data type is undefined
3700 * Switch on Definition/Reference
3702 if ((Flags
& GBLSYM_DEF
) == 0)
3707 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ? GSY_S_M_REL
: 0);
3708 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3709 PUT_SHORT (Current_Environment
);
3715 *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
3717 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ?
3718 GSY_S_M_DEF
| GSY_S_M_REL
: GSY_S_M_DEF
);
3719 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3720 PUT_SHORT (Current_Environment
);
3724 if ((Flags
& GBLSYM_LCL
) == 0 && (unsigned) Psect_Number
<= 255)
3726 PUT_CHAR (Psect_Number
);
3730 PUT_SHORT (Psect_Number
);
3735 PUT_LONG (Psect_Offset
);
3738 * Finally, the global symbol name
3740 VMS_Case_Hack_Symbol (Name
, Local
);
3741 PUT_COUNTED_STRING (Local
);
3743 * Flush the buffer if it is more than 75% full
3745 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3746 Flush_VMS_Object_Record_Buffer ();
3750 * Define an environment to support local symbol references.
3751 * This is just to mollify the linker; we don't actually do
3752 * anything useful with it.
3755 VMS_Local_Environment_Setup (Env_Name
)
3756 const char *Env_Name
;
3758 /* We are writing a GSD record. */
3759 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3760 /* If the buffer is empty we must insert the GSD record type. */
3761 if (Object_Record_Offset
== 0)
3762 PUT_CHAR (OBJ_S_C_GSD
);
3763 /* We are writing an ENV subrecord. */
3764 PUT_CHAR (GSD_S_C_ENV
);
3766 ++Current_Environment
; /* index of environment being defined */
3768 /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
3769 PUT_SHORT (ENV_S_M_DEF
);
3770 /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
3773 /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
3774 if (!Env_Name
) Env_Name
= "";
3775 PUT_COUNTED_STRING ((char *)Env_Name
);
3777 /* Flush the buffer if it is more than 75% full. */
3778 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3779 Flush_VMS_Object_Record_Buffer ();
3787 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3791 struct VMS_Symbol
*vsp
;
3794 int Psect_Attributes
;
3797 * Generate the appropriate PSECT flags given the PSECT type
3799 if (strcmp (Type
, "COMMON") == 0)
3802 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3804 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3805 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3807 else if (strcmp (Type
, "CONST") == 0)
3810 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3812 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3813 GPS_S_M_SHR
| GPS_S_M_RD
);
3815 else if (strcmp (Type
, "DATA") == 0)
3818 * The Data psects are PIC,REL,RD,WRT
3821 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3823 else if (strcmp (Type
, "TEXT") == 0)
3826 * The Text psects are PIC,REL,SHR,EXE,RD
3829 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3830 GPS_S_M_EXE
| GPS_S_M_RD
);
3835 * Error: Unknown psect type
3837 error ("Unknown VMS psect type");
3840 * Modify the psect attributes according to any attribute string
3842 if (vsp
&& S_GET_TYPE (vsp
->Symbol
) == N_ABS
)
3843 Psect_Attributes
|= GLOBALVALUE_BIT
;
3844 else if (HAS_PSECT_ATTRIBUTES (Name
))
3845 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3847 * Check for globalref/def/val.
3849 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3852 * globalvalue symbols were generated before. This code
3853 * prevents unsightly psect buildup, and makes sure that
3854 * fixup references are emitted correctly.
3856 vsp
->Psect_Index
= -1; /* to catch errors */
3857 S_SET_TYPE (vsp
->Symbol
, N_UNDF
); /* make refs work */
3858 return 1; /* decrement psect counter */
3861 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3863 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3865 case N_UNDF
| N_EXT
:
3866 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3867 vsp
->Psect_Offset
, GBLSYM_REF
);
3868 vsp
->Psect_Index
= -1;
3869 S_SET_TYPE (vsp
->Symbol
, N_UNDF
);
3870 return 1; /* return and indicate no psect */
3871 case N_DATA
| N_EXT
:
3872 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3873 vsp
->Psect_Offset
, GBLSYM_DEF
);
3874 /* In this case we still generate the psect */
3877 as_fatal ("Globalsymbol attribute for symbol %s was unexpected.",
3883 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3885 * We are writing a GSD record
3887 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3889 * If the buffer is empty we must insert the GSD record type
3891 if (Object_Record_Offset
== 0)
3892 PUT_CHAR (OBJ_S_C_GSD
);
3894 * We are writing a PSECT definition subrecord
3896 PUT_CHAR (GSD_S_C_PSC
);
3898 * Psects are always LONGWORD aligned
3902 * Specify the psect attributes
3904 PUT_SHORT (Psect_Attributes
);
3906 * Specify the allocation
3910 * Finally, the psect name
3912 VMS_Case_Hack_Symbol (Name
, Local
);
3913 PUT_COUNTED_STRING (Local
);
3915 * Flush the buffer if it is more than 75% full
3917 if (Object_Record_Offset
>
3918 (sizeof (Object_Record_Buffer
) * 3 / 4))
3919 Flush_VMS_Object_Record_Buffer ();
3925 * Given the pointer to a symbol we calculate how big the data at the
3926 * symbol is. We do this by looking for the next symbol (local or
3927 * global) which will indicate the start of another datum.
3930 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3931 register struct symbol
*sp
;
3934 struct symbol
*sp1
, *Next_Symbol
;
3935 /* Cache values to avoid extra lookups. */
3936 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
= 0;
3939 * Find the next symbol
3940 * it delimits this datum
3943 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3946 * The data type must match
3948 if (S_GET_TYPE (sp1
) != N_DATA
)
3951 sp1_val
= S_GET_VALUE (sp1
);
3954 * The symbol must be AFTER this symbol
3956 if (sp1_val
<= sp_val
)
3959 * We ignore THIS symbol
3964 * If there is already a candidate selected for the
3965 * next symbol, see if we are a better candidate
3970 * We are a better candidate if we are "closer"
3973 if (sp1_val
> next_val
)
3977 * Make this the candidate
3983 * Calculate its size
3985 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
3989 * Check symbol names for the Psect hack with a globalvalue, and then
3990 * generate globalvalues for those that have it.
3993 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3998 register symbolS
*sp
;
3999 char *stripped_name
, *Name
;
4001 int Psect_Attributes
;
4006 * Scan the symbol table for globalvalues, and emit def/ref when
4007 * required. These will be caught again later and converted to
4010 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
4012 typ
= S_GET_RAW_TYPE (sp
);
4013 abstyp
= ((typ
& ~N_EXT
) == N_ABS
);
4015 * See if this is something we want to look at.
4018 typ
!= (N_DATA
| N_EXT
) &&
4019 typ
!= (N_UNDF
| N_EXT
))
4022 * See if this has globalvalue specification.
4024 Name
= S_GET_NAME (sp
);
4029 Psect_Attributes
= GLOBALVALUE_BIT
;
4031 else if (HAS_PSECT_ATTRIBUTES (Name
))
4033 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
4034 strcpy (stripped_name
, Name
);
4035 Psect_Attributes
= 0;
4036 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
4041 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
4046 /* Local symbol references will want
4047 to have an environment defined. */
4048 if (Current_Environment
< 0)
4049 VMS_Local_Environment_Setup (".N_ABS");
4050 VMS_Global_Symbol_Spec (Name
, 0,
4052 GBLSYM_DEF
|GBLSYM_VAL
|GBLSYM_LCL
);
4055 VMS_Global_Symbol_Spec (Name
, 0,
4057 GBLSYM_DEF
|GBLSYM_VAL
);
4059 case N_UNDF
| N_EXT
:
4060 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
4062 case N_DATA
| N_EXT
:
4063 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4065 error ("Invalid data type for globalvalue");
4066 globalvalue
= md_chars_to_number (Data_Segment
+
4067 S_GET_VALUE (sp
) - text_siz
, Size
);
4068 /* Three times for good luck. The linker seems to get confused
4069 if there are fewer than three */
4070 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
4071 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
4072 GBLSYM_DEF
|GBLSYM_VAL
);
4073 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
4074 GBLSYM_DEF
|GBLSYM_VAL
);
4077 as_tsktsk ("Invalid globalvalue of %s", stripped_name
);
4081 if (stripped_name
) free (stripped_name
); /* clean up */
4088 * Define a procedure entry pt/mask
4091 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
4100 * We are writing a GSD record
4102 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
4104 * If the buffer is empty we must insert the GSD record type
4106 if (Object_Record_Offset
== 0)
4107 PUT_CHAR (OBJ_S_C_GSD
);
4109 * We are writing a Procedure Entry Pt/Mask subrecord
4111 PUT_CHAR (((unsigned) Psect_Number
<= 255) ? GSD_S_C_EPM
: GSD_S_C_EPMW
);
4113 * Data type is undefined
4117 * Flags = "RELOCATABLE" and "DEFINED"
4119 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4123 if ((unsigned) Psect_Number
<= 255)
4125 PUT_CHAR (Psect_Number
);
4129 PUT_SHORT (Psect_Number
);
4134 PUT_LONG (Psect_Offset
);
4138 PUT_SHORT (Entry_Mask
);
4140 * Finally, the global symbol name
4142 VMS_Case_Hack_Symbol (Name
, Local
);
4143 PUT_COUNTED_STRING (Local
);
4145 * Flush the buffer if it is more than 75% full
4147 if (Object_Record_Offset
>
4148 (sizeof (Object_Record_Buffer
) * 3 / 4))
4149 Flush_VMS_Object_Record_Buffer ();
4154 * Set the current location counter to a particular Psect and Offset
4157 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4163 * We are writing a "Record_Type" record
4165 Set_VMS_Object_File_Record (Record_Type
);
4167 * If the buffer is empty we must insert the record type
4169 if (Object_Record_Offset
== 0)
4170 PUT_CHAR (Record_Type
);
4172 * Stack the Psect base + Offset
4174 vms_tir_stack_psect (Psect_Index
, Offset
, 0);
4176 * Set relocation base
4178 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4180 * Flush the buffer if it is more than 75% full
4182 if (Object_Record_Offset
>
4183 (sizeof (Object_Record_Buffer
) * 3 / 4))
4184 Flush_VMS_Object_Record_Buffer ();
4189 * Store repeated immediate data in current Psect
4192 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4194 register char *Pointer
;
4200 * Ignore zero bytes/words/longwords
4205 if (Pointer
[3] != 0 || Pointer
[2] != 0) break;
4208 if (Pointer
[1] != 0) break;
4211 if (Pointer
[0] != 0) break;
4218 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4219 * then we do it manually
4223 while (--Repeat_Count
>= 0)
4224 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4228 * We are writing a "Record_Type" record
4230 Set_VMS_Object_File_Record (Record_Type
);
4232 * If the buffer is empty we must insert record type
4234 if (Object_Record_Offset
== 0)
4235 PUT_CHAR (Record_Type
);
4237 * Stack the repeat count
4239 PUT_CHAR (TIR_S_C_STA_LW
);
4240 PUT_LONG (Repeat_Count
);
4242 * And now the command and its data
4244 PUT_CHAR (TIR_S_C_STO_RIVB
);
4247 PUT_CHAR (*Pointer
++);
4249 * Flush the buffer if it is more than 75% full
4251 if (Object_Record_Offset
>
4252 (sizeof (Object_Record_Buffer
) * 3 / 4))
4253 Flush_VMS_Object_Record_Buffer ();
4258 * Store a Position Independent Reference
4261 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4262 Psect
, Psect_Offset
, Record_Type
)
4263 struct symbol
*Symbol
;
4270 register struct VMS_Symbol
*vsp
= Symbol
->sy_obj
;
4275 * We are writing a "Record_Type" record
4277 Set_VMS_Object_File_Record (Record_Type
);
4279 * If the buffer is empty we must insert record type
4281 if (Object_Record_Offset
== 0)
4282 PUT_CHAR (Record_Type
);
4284 * Set to the appropriate offset in the Psect
4289 * For a Code reference we need to fix the operand
4290 * specifier as well (so back up 1 byte)
4292 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4297 * For a Data reference we just store HERE
4299 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4302 * Make sure we are still generating a "Record Type" record
4304 if (Object_Record_Offset
== 0)
4305 PUT_CHAR (Record_Type
);
4307 * Dispatch on symbol type (so we can stack its value)
4309 switch (S_GET_RAW_TYPE (Symbol
))
4318 #ifdef NOT_VAX_11_C_COMPATIBLE
4319 case N_UNDF
| N_EXT
:
4320 case N_DATA
| N_EXT
:
4321 #endif /* NOT_VAX_11_C_COMPATIBLE */
4323 case N_TEXT
| N_EXT
:
4325 * Get the symbol name (case hacked)
4327 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4329 * Stack the global symbol value
4333 PUT_CHAR (TIR_S_C_STA_GBL
);
4337 /* Local symbols have an extra field. */
4338 PUT_CHAR (TIR_S_C_STA_LSY
);
4339 PUT_SHORT (Current_Environment
);
4341 PUT_COUNTED_STRING (Local
);
4345 * Stack the longword offset
4347 PUT_CHAR (TIR_S_C_STA_LW
);
4350 * Add the two, leaving the result on the stack
4352 PUT_CHAR (TIR_S_C_OPR_ADD
);
4356 * Uninitialized local data
4360 * Stack the Psect (+offset)
4362 vms_tir_stack_psect (vsp
->Psect_Index
,
4363 vsp
->Psect_Offset
+ Offset
,
4371 * Stack the Psect (+offset)
4373 vms_tir_stack_psect (vsp
->Psect_Index
,
4374 S_GET_VALUE (Symbol
) + Offset
,
4378 * Initialized local or global data
4381 #ifndef NOT_VAX_11_C_COMPATIBLE
4382 case N_UNDF
| N_EXT
:
4383 case N_DATA
| N_EXT
:
4384 #endif /* NOT_VAX_11_C_COMPATIBLE */
4386 * Stack the Psect (+offset)
4388 vms_tir_stack_psect (vsp
->Psect_Index
,
4389 vsp
->Psect_Offset
+ Offset
,
4394 * Store either a code or data reference
4396 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4398 * Flush the buffer if it is more than 75% full
4400 if (Object_Record_Offset
>
4401 (sizeof (Object_Record_Buffer
) * 3 / 4))
4402 Flush_VMS_Object_Record_Buffer ();
4407 * Check in the text area for an indirect pc-relative reference
4408 * and fix it up with addressing mode 0xff [PC indirect]
4410 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4411 * PIC CODE GENERATING FIXUP ROUTINE.
4414 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4417 register fragS
*fragP
;
4418 struct frag
*text_frag_root
;
4421 * The addressing mode byte is 1 byte before the address
4425 * Is it in THIS frag??
4427 if ((Offset
< fragP
->fr_address
) ||
4428 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4431 * We need to search for the fragment containing this
4434 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4436 if ((Offset
>= fragP
->fr_address
) &&
4437 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4441 * If we couldn't find the frag, things are BAD!!
4444 error ("Couldn't find fixup fragment when checking for indirect reference");
4447 * Check for indirect PC relative addressing mode
4449 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4451 static char Address_Mode
= 0xff;
4454 * Yes: Store the indirect mode back into the image
4455 * to fix up the damage done by STO_PICR
4457 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4458 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4463 * If the procedure "main()" exists we have to add the instruction
4464 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4467 vms_check_for_main ()
4469 register symbolS
*symbolP
;
4470 #ifdef HACK_DEC_C_STARTUP /* JF */
4471 register struct frchain
*frchainP
;
4472 register fragS
*fragP
;
4473 register fragS
**prev_fragPP
;
4474 register struct fix
*fixP
;
4475 register fragS
*New_Frag
;
4477 #endif /* HACK_DEC_C_STARTUP */
4479 symbolP
= (struct symbol
*) symbol_find ("_main");
4480 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4481 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4483 #ifdef HACK_DEC_C_STARTUP
4484 if (!flag_hash_long_names
)
4488 * Remember the entry point symbol
4490 Entry_Point_Symbol
= symbolP
;
4491 #ifdef HACK_DEC_C_STARTUP
4496 * Scan all the fragment chains for the one with "_main"
4497 * (Actually we know the fragment from the symbol, but we need
4498 * the previous fragment so we can change its pointer)
4500 frchainP
= frchain_root
;
4504 * Scan all the fragments in this chain, remembering
4505 * the "previous fragment"
4507 prev_fragPP
= &frchainP
->frch_root
;
4508 fragP
= frchainP
->frch_root
;
4509 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4512 * Is this the fragment?
4514 if (fragP
== symbolP
->sy_frag
)
4517 * Yes: Modify the fragment by replacing
4518 * it with a new fragment.
4520 New_Frag
= (fragS
*)
4521 xmalloc (sizeof (*New_Frag
) +
4526 * The fragments are the same except
4527 * that the "fixed" area is larger
4530 New_Frag
->fr_fix
+= 6;
4532 * Copy the literal data opening a hole
4533 * 2 bytes after "_main" (i.e. just after
4534 * the entry mask). Into which we place
4535 * the JSB instruction.
4537 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4538 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4539 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4540 New_Frag
->fr_literal
[3] = 0xef;
4541 New_Frag
->fr_literal
[4] = 0;
4542 New_Frag
->fr_literal
[5] = 0;
4543 New_Frag
->fr_literal
[6] = 0;
4544 New_Frag
->fr_literal
[7] = 0;
4545 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4546 New_Frag
->fr_literal
[i
+ 6] =
4547 fragP
->fr_literal
[i
];
4549 * Now replace the old fragment with the
4550 * newly generated one.
4552 *prev_fragPP
= New_Frag
;
4554 * Remember the entry point symbol
4556 Entry_Point_Symbol
= symbolP
;
4558 * Scan the text area fixup structures
4559 * as offsets in the fragment may have
4562 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4565 * Look for references to this
4568 if (fixP
->fx_frag
== fragP
)
4571 * Change the fragment
4574 fixP
->fx_frag
= New_Frag
;
4576 * If the offset is after
4577 * the entry mask we need
4578 * to account for the JSB
4579 * instruction we just
4582 if (fixP
->fx_where
>= 2)
4583 fixP
->fx_where
+= 6;
4587 * Scan the symbols as offsets in the
4588 * fragment may have changed
4590 for (symbolP
= symbol_rootP
;
4592 symbolP
= symbol_next (symbolP
))
4595 * Look for references to this
4598 if (symbolP
->sy_frag
== fragP
)
4601 * Change the fragment
4604 symbolP
->sy_frag
= New_Frag
;
4606 * If the offset is after
4607 * the entry mask we need
4608 * to account for the JSB
4609 * instruction we just
4612 if (S_GET_VALUE (symbolP
) >= 2)
4613 S_SET_VALUE (symbolP
,
4614 S_GET_VALUE (symbolP
) + 6);
4618 * Make a symbol reference to
4619 * "_c$main_args" so we can get
4620 * its address inserted into the
4623 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4624 S_SET_NAME (symbolP
, "_C$MAIN_ARGS");
4625 S_SET_TYPE (symbolP
, N_UNDF
);
4626 S_SET_OTHER (symbolP
, 0);
4627 S_SET_DESC (symbolP
, 0);
4628 S_SET_VALUE (symbolP
, 0);
4629 symbolP
->sy_name_offset
= 0;
4630 symbolP
->sy_number
= 0;
4631 symbolP
->sy_obj
= 0;
4632 symbolP
->sy_frag
= New_Frag
;
4633 symbolP
->sy_resolved
= 0;
4634 symbolP
->sy_resolving
= 0;
4635 /* this actually inserts at the beginning of the list */
4636 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4638 symbol_rootP
= symbolP
;
4640 * Generate a text fixup structure
4641 * to get "_c$main_args" stored into the
4644 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4645 fixP
->fx_frag
= New_Frag
;
4647 fixP
->fx_addsy
= symbolP
;
4649 fixP
->fx_offset
= 0;
4652 fixP
->fx_next
= text_fix_root
;
4653 text_fix_root
= fixP
;
4655 * Now make sure we exit from the loop
4661 * Try the next fragment
4663 prev_fragPP
= &fragP
->fr_next
;
4664 fragP
= fragP
->fr_next
;
4667 * Try the next fragment chain
4670 frchainP
= frchainP
->frch_next
;
4673 #endif /* HACK_DEC_C_STARTUP */
4678 * Write a VAX/VMS object file (everything else has been done!)
4681 vms_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4686 struct frag
*text_frag_root
;
4687 struct frag
*data_frag_root
;
4689 register fragS
*fragP
;
4690 register symbolS
*symbolP
;
4691 register symbolS
*sp
;
4692 register struct fix
*fixP
;
4693 register struct VMS_Symbol
*vsp
;
4694 char *Data_Segment
= 0;
4695 int Local_Initialized_Data_Size
= 0;
4697 int Psect_Number
= 0; /* Psect Index Number */
4698 int Text_Psect
= -1; /* Text Psect Index */
4699 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4700 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4703 * Create the VMS object file
4705 Create_VMS_Object_File ();
4707 * Write the module header records
4709 Write_VMS_MHD_Records ();
4712 * Store the Data segment:
4714 * Since this is REALLY hard to do any other way,
4715 * we actually manufacture the data segment and
4716 * the store the appropriate values out of it.
4717 * We need to generate this early, so that globalvalues
4718 * can be properly emitted.
4723 * Allocate the data segment
4725 Data_Segment
= (char *) xmalloc (data_siz
);
4727 * Run through the data fragments, filling in the segment
4729 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4731 register long int count
;
4732 register char *fill_literal
;
4733 register long int fill_size
;
4736 i
= fragP
->fr_address
- text_siz
;
4738 memcpy (Data_Segment
+ i
,
4743 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4744 fill_size
= fragP
->fr_var
;
4745 for (count
= fragP
->fr_offset
; count
; count
--)
4748 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4756 * Generate the VMS object file records
4757 * 1st GSD then TIR records
4760 /******* Global Symbol Dictionary *******/
4762 * Emit globalvalues now. We must do this before the text psect
4763 * is defined, or we will get linker warnings about multiply defined
4764 * symbols. All of the globalvalues "reference" psect 0, although
4765 * it really does not have anything to do with it.
4767 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4769 * Define the Text Psect
4771 Text_Psect
= Psect_Number
++;
4772 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4774 * Define the BSS Psect
4778 Bss_Psect
= Psect_Number
++;
4779 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4781 #ifndef gxx_bug_fixed
4783 * The g++ compiler does not write out external references to vtables
4784 * correctly. Check for this and holler if we see it happening.
4785 * If that compiler bug is ever fixed we can remove this.
4787 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4790 * Dispatch on symbol type
4792 switch (S_GET_RAW_TYPE (sp
)) {
4798 * Make a GSD global symbol reference
4801 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4803 S_SET_TYPE (sp
, N_UNDF
| N_EXT
);
4804 S_SET_OTHER (sp
, 1);
4805 /* Is this warning still needed? It sounds like it describes
4806 a compiler bug. Does it? If not, let's dump it. */
4807 as_warn("g++ wrote an extern reference to %s as a routine.",
4809 as_warn("I will fix it, but I hope that it was not really a routine");
4816 #endif /* gxx_bug_fixed */
4818 * Now scan the symbols and emit the appropriate GSD records
4820 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4823 * Dispatch on symbol type
4825 switch (S_GET_RAW_TYPE (sp
))
4828 * Global uninitialized data
4830 case N_UNDF
| N_EXT
:
4832 * Make a VMS data symbol entry
4834 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof (*vsp
));
4836 vsp
->Size
= S_GET_VALUE (sp
);
4837 vsp
->Psect_Index
= Psect_Number
++;
4838 vsp
->Psect_Offset
= 0;
4839 vsp
->Next
= VMS_Symbols
;
4843 * Make the psect for this data
4845 Globalref
= VMS_Psect_Spec (
4848 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
4853 /* See if this is an external vtable. We want to help the linker find
4854 these things in libraries, so we make a symbol reference. This
4855 is not compatible with VAX-C usage for variables, but since vtables are
4856 only used internally by g++, we can get away with this hack. */
4858 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4859 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4864 #ifdef NOT_VAX_11_C_COMPATIBLE
4866 * Place a global symbol at the
4867 * beginning of the Psect
4869 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4873 #endif /* NOT_VAX_11_C_COMPATIBLE */
4876 * Local uninitialized data
4880 * Make a VMS data symbol entry
4882 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof (*vsp
));
4885 vsp
->Psect_Index
= Bss_Psect
;
4886 vsp
->Psect_Offset
= S_GET_VALUE (sp
) - bss_address_frag
.fr_address
;
4887 vsp
->Next
= VMS_Symbols
;
4892 * Global initialized data
4894 case N_DATA
| N_EXT
:
4896 * Make a VMS data symbol entry
4898 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof (*vsp
));
4900 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4901 vsp
->Psect_Index
= Psect_Number
++;
4902 vsp
->Psect_Offset
= 0;
4903 vsp
->Next
= VMS_Symbols
;
4909 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
4911 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
4916 /* See if this is an external vtable. We want to help the linker find
4917 these things in libraries, so we make a symbol definition. This
4918 is not compatible with VAX-C usage for variables, but since vtables are
4919 only used internally by g++, we can get away with this hack. */
4921 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4922 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4927 #ifdef NOT_VAX_11_C_COMPATIBLE
4929 * Place a global symbol at the
4930 * beginning of the Psect
4932 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4936 #endif /* NOT_VAX_11_C_COMPATIBLE */
4939 * Local initialized data
4943 char *sym_name
= S_GET_NAME (sp
);
4945 /* Always suppress local numeric labels. */
4946 if (!sym_name
|| strcmp (sym_name
, FAKE_LABEL_NAME
) != 0)
4949 * Make a VMS data symbol entry.
4951 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof (*vsp
));
4953 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4954 vsp
->Psect_Index
= Data_Psect
;
4955 vsp
->Psect_Offset
= Local_Initialized_Data_Size
;
4956 Local_Initialized_Data_Size
+= vsp
->Size
;
4957 vsp
->Next
= VMS_Symbols
;
4964 * Global Text definition
4966 case N_TEXT
| N_EXT
:
4968 unsigned short Entry_Mask
;
4971 * Get the entry mask
4973 fragP
= sp
->sy_frag
;
4975 /* If first frag doesn't contain the data, what do we do?
4976 If it's possibly smaller than two bytes, that would
4977 imply that the entry mask is not stored where we're
4980 If you can find a test case that triggers this, report
4981 it (and tell me what the entry mask field ought to be),
4982 and I'll try to fix it. KR */
4983 /* First frag might be empty if we're generating listings.
4984 So skip empty rs_fill frags. */
4985 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
4986 fragP
= fragP
->fr_next
;
4988 if (fragP
->fr_fix
< 2)
4991 Entry_Mask
= (fragP
->fr_literal
[0] & 0x00ff) |
4992 ((fragP
->fr_literal
[1] & 0x00ff) << 8);
4994 * Define the Procedure entry pt.
4996 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
5003 * Local Text definition
5007 * Make a VMS data symbol entry
5009 if (Text_Psect
!= -1)
5011 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof (*vsp
));
5014 vsp
->Psect_Index
= Text_Psect
;
5015 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
5016 vsp
->Next
= VMS_Symbols
;
5026 * Make a GSD global symbol reference
5029 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
5040 * gcc doesn't generate these;
5041 * VMS_Emit_Globalvalue handles them though.
5043 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof (*vsp
));
5046 vsp
->Psect_Index
= 0;
5047 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
5048 vsp
->Next
= VMS_Symbols
;
5057 * Ignore STAB symbols
5058 * Including .stabs emitted by g++
5060 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
5065 if (S_GET_TYPE (sp
) != 22)
5066 as_tsktsk ("unhandled stab type %d", S_GET_TYPE (sp
));
5071 * Define the Data Psect
5073 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
5078 Data_Psect
= Psect_Number
++;
5079 VMS_Psect_Spec ("$data",
5080 Local_Initialized_Data_Size
,
5083 * Scan the VMS symbols and fill in the data psect
5085 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5088 * Only look for undefined psects
5090 if (vsp
->Psect_Index
< 0)
5093 * And only initialized data
5095 if (S_GET_TYPE (vsp
->Symbol
) == N_DATA
5096 && !S_IS_EXTERNAL (vsp
->Symbol
))
5097 vsp
->Psect_Index
= Data_Psect
;
5102 /******* Text Information and Relocation Records *******/
5104 * Write the text segment data
5109 * Scan the text fragments
5111 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
5114 * Stop if we get to the data fragments
5116 if (fragP
== data_frag_root
)
5119 * Ignore fragments with no data
5121 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
5124 * Go the the appropriate offset in the
5127 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
5129 * Store the "fixed" part
5132 VMS_Store_Immediate_Data (fragP
->fr_literal
,
5136 * Store the "variable" part
5138 if (fragP
->fr_var
&& fragP
->fr_offset
)
5139 VMS_Store_Repeated_Data (fragP
->fr_offset
,
5146 * Now we go through the text segment fixups and
5147 * generate TIR records to fix up addresses within
5150 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5153 * We DO handle the case of "Symbol - Symbol" as
5154 * long as it is in the same segment.
5156 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5161 * They need to be in the same segment
5163 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5164 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5165 error ("Fixup data addsy and subsy didn't have the same type");
5167 * And they need to be in one that we
5168 * can check the psect on
5170 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5171 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5172 error ("Fixup data addsy and subsy didn't have an appropriate type");
5174 * This had better not be PC relative!
5177 error ("Fixup data was erroneously \"pcrel\"");
5179 * Subtract their values to get the
5182 i
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
5184 * Now generate the fixup object records
5185 * Set the psect and store the data
5187 VMS_Set_Psect (Text_Psect
,
5188 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
5190 VMS_Store_Immediate_Data (&i
,
5199 * Size will HAVE to be "long"
5201 if (fixP
->fx_size
!= 4)
5202 error ("Fixup datum was not a longword");
5204 * Symbol must be "added" (if it is ever
5206 * fix this assumption)
5208 if (fixP
->fx_addsy
== 0)
5209 error ("Fixup datum was not \"fixP->fx_addsy\"");
5211 * Store the symbol value in a PIC fashion
5213 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5218 fixP
->fx_frag
->fr_address
,
5221 * Check for indirect address reference,
5222 * which has to be fixed up (as the linker
5223 * will screw it up with TIR_S_C_STO_PICR).
5226 VMS_Fix_Indirect_Reference (Text_Psect
,
5228 fixP
->fx_frag
->fr_address
,
5234 * Store the Data segment:
5236 * Since this is REALLY hard to do any other way,
5237 * we actually manufacture the data segment and
5238 * the store the appropriate values out of it.
5239 * The segment was manufactured before, now we just
5240 * dump it into the appropriate psects.
5246 * Now we can run through all the data symbols
5247 * and store the data
5249 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5252 * Ignore anything other than data symbols
5254 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
5257 * Set the Psect + Offset
5259 VMS_Set_Psect (vsp
->Psect_Index
,
5265 VMS_Store_Immediate_Data (Data_Segment
+
5266 S_GET_VALUE (vsp
->Symbol
) -
5272 * Now we go through the data segment fixups and
5273 * generate TIR records to fix up addresses within
5276 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5279 * Find the symbol for the containing datum
5281 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5284 * Only bother with Data symbols
5287 if (S_GET_TYPE (sp
) != N_DATA
)
5290 * Ignore symbol if After fixup
5292 if (S_GET_VALUE (sp
) >
5294 fixP
->fx_frag
->fr_address
))
5297 * See if the datum is here
5299 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5301 fixP
->fx_frag
->fr_address
))
5304 * We DO handle the case of "Symbol - Symbol" as
5305 * long as it is in the same segment.
5307 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5312 * They need to be in the same segment
5314 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5315 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5316 error ("Fixup data addsy and subsy didn't have the same type");
5318 * And they need to be in one that we
5319 * can check the psect on
5321 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5322 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5323 error ("Fixup data addsy and subsy didn't have an appropriate type");
5325 * This had better not be PC relative!
5328 error ("Fixup data was erroneously \"pcrel\"");
5330 * Subtract their values to get the
5333 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5334 S_GET_VALUE (fixP
->fx_subsy
);
5336 * Now generate the fixup object records
5337 * Set the psect and store the data
5339 VMS_Set_Psect (vsp
->Psect_Index
,
5340 fixP
->fx_frag
->fr_address
+
5342 S_GET_VALUE (vsp
->Symbol
) +
5345 VMS_Store_Immediate_Data (&i
,
5354 * Size will HAVE to be "long"
5356 if (fixP
->fx_size
!= 4)
5357 error ("Fixup datum was not a longword");
5359 * Symbol must be "added" (if it is ever
5361 * fix this assumption)
5363 if (fixP
->fx_addsy
== 0)
5364 error ("Fixup datum was not \"fixP->fx_addsy\"");
5366 * Store the symbol value in a PIC fashion
5368 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
5372 fixP
->fx_frag
->fr_address
+
5374 S_GET_VALUE (vsp
->Symbol
) +
5387 * Write the Traceback Begin Module record
5389 VMS_TBT_Module_Begin ();
5391 * Scan the symbols and write out the routines
5392 * (this makes the assumption that symbols are in
5393 * order of ascending text segment offset)
5396 struct symbol
*Current_Routine
= 0;
5397 int Current_Line_Number
= 0;
5398 int Current_Offset
= -1;
5399 struct input_file
*Current_File
= 0;
5401 /* Output debugging info for global variables and static variables that are not
5402 * specific to one routine. We also need to examine all stabs directives, to
5403 * find the definitions to all of the advanced data types, and this is done by
5404 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5405 * the object file, since there can be forward references in the stabs
5406 * directives. When through with parsing, the text of the stabs directive
5407 * is altered, with the definitions removed, so that later passes will see
5408 * directives as they would be written if the type were already defined.
5410 * We also look for files and include files, and make a list of them. We
5411 * examine the source file numbers to establish the actual lines that code was
5412 * generated from, and then generate offsets.
5415 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5418 * Deal with STAB symbols
5420 if (S_IS_DEBUG (symbolP
))
5423 * Dispatch on STAB type
5425 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5428 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5429 Current_File
->max_line
= S_GET_DESC (symbolP
);
5430 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5431 Current_File
->min_line
= S_GET_DESC (symbolP
);
5434 Current_File
= find_file (symbolP
);
5435 Current_File
->flag
= 1;
5436 Current_File
->min_line
= 1;
5439 Current_File
= find_file (symbolP
);
5442 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5445 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5447 case N_FUN
: /* For static constant symbols */
5449 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5455 /* now we take a quick sweep through the files and assign offsets
5456 to each one. This will essentially be the starting line number to the
5457 debugger for each file. Output the info for the debugger to specify the
5458 files, and then tell it how many lines to use */
5460 int File_Number
= 0;
5461 int Debugger_Offset
= 0;
5463 Current_File
= file_root
;
5464 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5466 if (Current_File
== (struct input_file
*) NULL
)
5468 if (Current_File
->max_line
== 0)
5470 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5473 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5476 /* show a few extra lines at the start of the region selected */
5477 if (Current_File
->min_line
> 2)
5478 Current_File
->min_line
-= 2;
5479 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5480 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5481 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5482 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5485 Current_File
->file_number
= ++File_Number
;
5486 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5487 Current_File
->file_number
);
5488 if (!file_available
)
5490 Current_File
->file_number
= 0;
5495 VMS_TBT_Source_Lines (Current_File
->file_number
,
5496 Current_File
->min_line
,
5497 Current_File
->max_line
- Current_File
->min_line
+ 1);
5500 Current_File
= (struct input_file
*) NULL
;
5502 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5505 * Deal with text symbols
5507 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5510 * Ignore symbols starting with "L",
5511 * as they are local symbols
5513 if (*S_GET_NAME (symbolP
) == 'L')
5516 * If there is a routine start defined,
5519 if (Current_Routine
)
5524 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5527 * Check for & skip dummy labels like "gcc_compiled.".
5528 * They're identified by the IN_DEFAULT_SECTION flag.
5530 if ((S_GET_OTHER (symbolP
) & IN_DEFAULT_SECTION
) != 0 &&
5531 (S_GET_VALUE (symbolP
) == 0))
5534 * Store the routine begin traceback info
5536 if (Text_Psect
!= -1)
5538 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5539 Current_Routine
= symbolP
;
5541 /* Output local symbols, i.e. all symbols that are associated with a specific
5542 * routine. We output them now so the debugger recognizes them as local to
5549 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5551 if (!S_IS_DEBUG (symbolP1
))
5553 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5555 pnt
= S_GET_NAME (symbolP
);
5556 pnt1
= S_GET_NAME (symbolP1
);
5559 while (*pnt
++ == *pnt1
++)
5562 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5563 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5566 if (symbolP1
!= (symbolS
*) NULL
)
5567 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5568 } /* local symbol block */
5575 * Deal with STAB symbols
5577 if (S_IS_DEBUG (symbolP
))
5580 * Dispatch on STAB type
5582 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5588 /* Offset the line into the correct portion
5590 if (Current_File
->file_number
== 0)
5592 /* Sometimes the same offset gets several source
5593 * lines assigned to it.
5594 * We should be selective about which lines
5595 * we allow, we should prefer lines that are
5596 * in the main source file when debugging
5597 * inline functions. */
5598 if ((Current_File
->file_number
!= 1) &&
5599 S_GET_VALUE (symbolP
) ==
5602 /* calculate actual debugger source line */
5603 S_GET_DESC (symbolP
)
5604 += Current_File
->offset
;
5606 * If this is the 1st N_SLINE, setup
5607 * PC/Line correlation. Otherwise
5608 * do the delta PC/Line. If the offset
5609 * for the line number is not +ve we need
5610 * to do another PC/Line correlation
5613 if (Current_Offset
== -1)
5615 VMS_TBT_Line_PC_Correlation (
5616 S_GET_DESC (symbolP
),
5617 S_GET_VALUE (symbolP
),
5623 if ((S_GET_DESC (symbolP
) -
5624 Current_Line_Number
) <= 0)
5627 * Line delta is not +ve, we
5628 * need to close the line and
5629 * start a new PC/Line
5632 VMS_TBT_Line_PC_Correlation (0,
5633 S_GET_VALUE (symbolP
) -
5637 VMS_TBT_Line_PC_Correlation (
5638 S_GET_DESC (symbolP
),
5639 S_GET_VALUE (symbolP
),
5646 * Line delta is +ve, all is well
5648 VMS_TBT_Line_PC_Correlation (
5649 S_GET_DESC (symbolP
) -
5650 Current_Line_Number
,
5651 S_GET_VALUE (symbolP
) -
5658 * Update the current line/PC
5660 Current_Line_Number
= S_GET_DESC (symbolP
);
5661 Current_Offset
= S_GET_VALUE (symbolP
);
5671 * Remember that we had a source file
5672 * and emit the source file debugger
5676 find_file (symbolP
);
5678 /* We need to make sure that we are really in the actual source file when
5679 * we compute the maximum line number. Otherwise the debugger gets really
5683 find_file (symbolP
);
5689 * If there is a routine start defined,
5690 * terminate it (and the line numbers)
5692 if (Current_Routine
)
5695 * Terminate the line numbers
5697 VMS_TBT_Line_PC_Correlation (0,
5698 text_siz
- S_GET_VALUE (Current_Routine
),
5702 * Terminate the routine
5704 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5708 * Write the Traceback End Module TBT record
5710 VMS_TBT_Module_End ();
5713 * Write the End Of Module record
5715 if (Entry_Point_Symbol
== 0)
5716 Write_VMS_EOM_Record (-1, 0);
5718 Write_VMS_EOM_Record (Text_Psect
,
5719 S_GET_VALUE (Entry_Point_Symbol
));
5722 * All done, close the object file
5724 Close_VMS_Object_File ();
5727 /* end of obj-vms.c */