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
24 /* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h). */
25 #define WANT_VMS_OBJ_DEFS
32 /* What we do if there is a goof. */
33 #define error as_fatal
35 #ifdef VMS /* These are of no use if we are cross assembling. */
36 #include <fab.h> /* Define File Access Block */
37 #include <nam.h> /* Define NAM Block */
38 #include <xab.h> /* Define XAB - all different types*/
39 extern int sys$open(), sys$close(), sys$asctim();
43 * Version string of the compiler that produced the code we are
44 * assembling. (And this assembler, if we do not have compiler info.)
46 char *compiler_version_string;
48 extern int flag_hash_long_names; /* -+ */
49 extern int flag_one; /* -1; compatibility with gcc 1.x */
50 extern int flag_show_after_trunc; /* -H */
51 extern int flag_no_hash_mixed_case; /* -h NUM */
53 /* Flag that determines how we map names. This takes several values, and
54 * is set with the -h switch. A value of zero implies names should be
55 * upper case, and the presence of the -h switch inhibits the case hack.
56 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
57 * A value of 2 (set with -h2) implies names should be
58 * all lower case, with no case hack. A value of 3 (set with -h3) implies
59 * that case should be preserved. */
61 /* If the -+ switch is given, then the hash is appended to any name that is
62 * longer than 31 characters, regardless of the setting of the -h switch.
65 char vms_name_mapping = 0;
67 static symbolS *Entry_Point_Symbol = 0; /* Pointer to "_main" */
70 * We augment the "gas" symbol structure with this
74 struct VMS_Symbol *Next;
81 struct VMS_Symbol *VMS_Symbols = 0;
83 /* We need this to keep track of the various input files, so that we can
84 * give the debugger the correct source line.
89 struct input_file *next;
90 struct input_file *same_file_fpnt;
100 static struct input_file *file_root = (struct input_file *) NULL;
104 * This enum is used to keep track of the various types of variables that
110 BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN
114 * This structure contains the information from the stabs directives, and the
115 * information is filled in by VMS_typedef_parse. Everything that is needed
116 * to generate the debugging record for a given symbol is present here.
117 * This could be done more efficiently, using nested struct/unions, but for now
118 * I am happy that it works.
120 struct VMS_DBG_Symbol
122 struct VMS_DBG_Symbol *next;
123 /* description of what this is */
124 enum advanced_type advanced;
125 /* this record is for this type */
127 /* For advanced types this is the type referred to. I.e., the type
128 a pointer points to, or the type of object that makes up an
131 /* Use this type when generating a variable def */
133 /* used for arrays - this will be present for all */
135 /* entries, but will be meaningless for non-arrays */
137 /* Size in bytes of the data type. For an array, this is the size
138 of one element in the array */
140 /* Number of the structure/union/enum - used for ref */
144 #define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */
145 #define SYMTYP_HASH(x) ((unsigned)(x) & (SYMTYPLST_SIZE-1))
146 struct VMS_DBG_Symbol *VMS_Symbol_type_list[SYMTYPLST_SIZE];
149 * We need this structure to keep track of forward references to
150 * struct/union/enum that have not been defined yet. When they are ultimately
151 * defined, then we can go back and generate the TIR commands to make a back
157 struct forward_ref *next;
163 struct forward_ref *f_ref_root = (struct forward_ref *) NULL;
166 * This routine is used to compare the names of certain types to various
167 * fixed types that are known by the debugger.
169 #define type_check(X) !strcmp (symbol_name, X)
172 * This variable is used to keep track of the name of the symbol we are
173 * working on while we are parsing the stabs directives.
175 static const char *symbol_name;
177 /* We use this counter to assign numbers to all of the structures, unions
178 * and enums that we define. When we actually declare a variable to the
179 * debugger, we can simply do it by number, rather than describing the
180 * whole thing each time.
183 static structure_count = 0;
185 /* This variable is used to indicate that we are making the last attempt to
186 parse the stabs, and that we should define as much as we can, and ignore
189 static int final_pass;
191 /* This variable is used to keep track of the current structure number
192 * for a given variable. If this is < 0, that means that the structure
193 * has not yet been defined to the debugger. This is still cool, since
194 * the VMS object language has ways of fixing things up after the fact,
195 * so we just make a note of this, and generate fixups at the end.
197 static int struct_number;
199 /* This is used to distinguish between D_float and G_float for telling
200 the debugger about doubles. gcc outputs the same .stabs regardless
201 of whether -mg is used to select alternate doubles. */
203 static int vax_g_doubles = 0;
205 /* Local symbol references (used to handle N_ABS symbols; gcc does not
206 generate those, but they're possible with hand-coded assembler input)
207 are always made relative to some particular environment. If the current
208 input has any such symbols, then we expect this to get incremented
209 exactly once and end up having all of them be in environment #0. */
211 static int Current_Environment = -1;
215 * Variable descriptors are used tell the debugger the data types of certain
216 * more complicated variables (basically anything involving a structure,
217 * union, enum, array or pointer). Some non-pointer variables of the
218 * basic types that the debugger knows about do not require a variable
221 * Since it is impossible to have a variable descriptor longer than 128
222 * bytes by virtue of the way that the VMS object language is set up,
223 * it makes not sense to make the arrays any longer than this, or worrying
224 * about dynamic sizing of the array.
226 * These are the arrays and counters that we use to build a variable
230 #define MAX_DEBUG_RECORD 128
231 static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
232 static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
233 static int Lpnt; /* index into Local */
234 static int Apoint; /* index into Asuffix */
235 static char overflow; /* flag to indicate we have written too much*/
236 static int total_len; /* used to calculate the total length of variable
237 descriptor plus array descriptor - used for len byte*/
239 /* Flag if we have told user about finding global constants in the text
241 static int gave_compiler_message = 0;
243 /* A pointer to the current routine that we are working on. */
245 static symbolS *Current_Routine;
247 /* The psect number for $code a.k.a. the text section. */
249 static int Text_Psect;
253 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
255 static int VMS_Object_File_FD; /* File Descriptor for object file */
256 static char Object_Record_Buffer[512]; /* Buffer for object file records */
257 static int Object_Record_Offset;/* Offset to end of data */
258 static int Current_Object_Record_Type; /* Type of record in above */
261 * Macros for moving data around. Must work on big-endian systems.
263 #ifdef VMS /* These are more efficient for VMS->VMS systems */
264 #define COPY_LONG(dest,val) {*(long *) dest = val; }
265 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
267 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
268 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
271 * Macros for placing data into the object record buffer
273 #define PUT_LONG(val) \
274 { COPY_LONG(&Object_Record_Buffer[Object_Record_Offset], val); \
275 Object_Record_Offset += 4; }
277 #define PUT_SHORT(val) \
278 { COPY_SHORT(&Object_Record_Buffer[Object_Record_Offset], val); \
279 Object_Record_Offset += 2; }
281 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
283 #define PUT_COUNTED_STRING(cp) {\
284 register const char *p = cp; \
285 PUT_CHAR(strlen(p)); \
286 while (*p) PUT_CHAR(*p++);}
289 * Macro for determining if a Name has psect attributes attached
292 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
293 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
295 #define HAS_PSECT_ATTRIBUTES(Name) \
296 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
297 PSECT_ATTRIBUTES_STRING, \
298 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
301 /* in: segT out: N_TYPE bits */
302 const short seg_N_TYPE[] =
308 N_UNDF, /* unknown */
310 N_UNDF, /* expression */
314 N_REGISTER, /* register */
317 const segT N_TYPE_seg[N_TYPE + 2] =
318 { /* N_TYPE == 0x1E = 32-2 */
319 SEG_UNKNOWN, /* N_UNDF == 0 */
321 SEG_ABSOLUTE, /* N_ABS == 2 */
323 SEG_TEXT, /* N_TEXT == 4 */
325 SEG_DATA, /* N_DATA == 6 */
327 SEG_BSS, /* N_BSS == 8 */
329 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
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,
332 SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
337 /* Local support routines which return a value. */
339 static struct input_file *find_file PARAMS ((symbolS *));
340 static struct VMS_DBG_Symbol *find_symbol PARAMS ((int));
341 static symbolS *Define_Routine PARAMS ((symbolS *,int));
343 static char *cvt_integer PARAMS ((char *,int *));
344 static char *fix_name PARAMS ((char *));
345 static char *get_struct_name PARAMS ((char *));
347 static int VMS_TBT_Source_File PARAMS ((char *,int));
348 static int gen1 PARAMS ((struct VMS_DBG_Symbol *,int));
349 static int forward_reference PARAMS ((char *));
350 static int final_forward_reference PARAMS ((struct VMS_DBG_Symbol *));
351 static int VMS_typedef_parse PARAMS ((char *));
352 static int hash_string PARAMS ((const char *));
353 static int VMS_Psect_Spec PARAMS ((const char *,int,const char *,
354 struct VMS_Symbol *));
355 static int VMS_Initialized_Data_Size PARAMS ((symbolS *,int));
357 /* Local support routines which don't directly return any value. */
359 static void s_const PARAMS ((int));
360 static void Create_VMS_Object_File PARAMS ((void));
361 static void Flush_VMS_Object_Record_Buffer PARAMS ((void));
362 static void Set_VMS_Object_File_Record PARAMS ((int));
363 static void Close_VMS_Object_File PARAMS ((void));
364 static void vms_tir_stack_psect PARAMS ((int,int,int));
365 static void VMS_Store_Immediate_Data PARAMS ((const char *,int,int));
366 static void VMS_Set_Data PARAMS ((int,int,int,int));
367 static void VMS_Store_Struct PARAMS ((int));
368 static void VMS_Def_Struct PARAMS ((int));
369 static void VMS_Set_Struct PARAMS ((int));
370 static void VMS_TBT_Module_Begin PARAMS ((void));
371 static void VMS_TBT_Module_End PARAMS ((void));
372 static void VMS_TBT_Routine_Begin PARAMS ((symbolS *,int));
373 static void VMS_TBT_Routine_End PARAMS ((int,symbolS *));
374 static void VMS_TBT_Block_Begin PARAMS ((symbolS *,int,char *));
375 static void VMS_TBT_Block_End PARAMS ((int));
376 static void VMS_TBT_Line_PC_Correlation PARAMS ((int,int,int,int));
377 static void VMS_TBT_Source_Lines PARAMS ((int,int,int));
378 static void fpush PARAMS ((int,int));
379 static void rpush PARAMS ((int,int));
380 static void array_suffix PARAMS ((struct VMS_DBG_Symbol *));
381 static void new_forward_ref PARAMS ((int));
382 static void generate_suffix PARAMS ((struct VMS_DBG_Symbol *,int));
383 static void bitfield_suffix PARAMS ((struct VMS_DBG_Symbol *,int));
384 static void setup_basic_type PARAMS ((struct VMS_DBG_Symbol *));
385 static void VMS_DBG_record PARAMS ((struct VMS_DBG_Symbol *,int,int,char *));
386 static void VMS_local_stab_Parse PARAMS ((symbolS *));
387 static void VMS_stab_parse PARAMS ((symbolS *,int,int,int,int));
388 static void VMS_GSYM_Parse PARAMS ((symbolS *,int));
389 static void VMS_LCSYM_Parse PARAMS ((symbolS *,int));
390 static void VMS_STSYM_Parse PARAMS ((symbolS *,int));
391 static void VMS_RSYM_Parse PARAMS ((symbolS *,symbolS *,int));
392 static void VMS_LSYM_Parse PARAMS ((void));
393 static void Define_Local_Symbols PARAMS ((symbolS *,symbolS *));
394 static void VMS_DBG_Define_Routine PARAMS ((symbolS *,symbolS *,int));
395 static void Write_VMS_MHD_Records PARAMS ((void));
396 static void Write_VMS_EOM_Record PARAMS ((int,int));
397 static void VMS_Case_Hack_Symbol PARAMS ((const char *,char *));
398 static void VMS_Modify_Psect_Attributes PARAMS ((const char *,int *));
399 static void VMS_Global_Symbol_Spec PARAMS ((const char *,int,int,int));
400 static void VMS_Local_Environment_Setup PARAMS ((const char *));
401 static void VMS_Emit_Globalvalues PARAMS ((unsigned,unsigned,char *));
402 static void VMS_Procedure_Entry_Pt PARAMS ((char *,int,int,int));
403 static void VMS_Set_Psect PARAMS ((int,int,int));
404 static void VMS_Store_Repeated_Data PARAMS ((int,char *,int,int));
405 static void VMS_Store_PIC_Symbol_Reference PARAMS ((symbolS *,int,
407 static void VMS_Fix_Indirect_Reference PARAMS ((int,int,fragS *,fragS *));
410 /* The following code defines the special types of pseudo-ops that we
414 char const_flag = IN_DEFAULT_SECTION;
418 int arg; /* 3rd field from obj_pseudo_table[]; not needed here */
420 /* Since we don't need `arg', use it as our scratch variable so that
421 we won't get any "not used" warnings about it. */
422 arg = get_absolute_expression ();
423 subseg_set (SEG_DATA, (subsegT) arg);
425 demand_empty_rest_of_line ();
428 const pseudo_typeS obj_pseudo_table[] =
430 {"const", s_const, 0},
432 }; /* obj_pseudo_table */
435 vms_resolve_symbol_redef (sym)
439 * If the new symbol is .comm AND it has a size of zero,
440 * we ignore it (i.e. the old symbol overrides it)
442 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)
443 && frag_now_fix () == 0)
445 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
450 * If the old symbol is .comm and it has a size of zero,
451 * we override it with the new symbol value.
453 if (S_IS_EXTERNAL(sym) && S_IS_DEFINED(sym)
454 && (S_GET_VALUE(sym) == 0))
456 as_warn ("compiler redefined zero-size common symbol `%s'",
458 sym->sy_frag = frag_now;
459 S_SET_OTHER(sym, const_flag);
460 S_SET_VALUE(sym, frag_now_fix ());
461 /* Keep N_EXT bit. */
462 sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE((int) now_seg);
469 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
470 dummy label(s) gcc inserts at the beginning of each file it generates.
471 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
472 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
475 vms_check_for_special_label (symbolP)
478 /* Special labels only occur prior to explicit section directives. */
479 if ((const_flag & IN_DEFAULT_SECTION) != 0)
481 char *sym_name = S_GET_NAME(symbolP);
483 if (*sym_name == '_')
486 if (!strcmp (sym_name, "__vax_g_doubles"))
488 #if 0 /* not necessary */
489 else if (!strcmp (sym_name, "__vax_d_doubles"))
492 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
493 else if (!strcmp (sym_name, "gcc_compiled."))
495 else if (!strcmp (sym_name, "__gnu_language_cplusplus"))
496 flag_hash_long_names = 1;
503 obj_read_begin_hook ()
509 obj_crawl_symbol_chain (headers)
510 object_headers *headers;
514 int symbol_number = 0;
516 symbolPP = &symbol_rootP; /* -> last symbol chain link. */
517 while ((symbolP = *symbolPP) != NULL)
519 resolve_symbol_value (symbolP);
521 /* OK, here is how we decide which symbols go out into the
522 brave new symtab. Symbols that do are:
524 * symbols with no name (stabd's?)
525 * symbols with debug info in their N_TYPE
526 * symbols with \1 as their 3rd character (numeric labels)
527 * "local labels" needed for PIC fixups
529 Symbols that don't are:
530 * symbols that are registers
532 All other symbols are output. We complain if a deleted
533 symbol was marked external. */
535 if (!S_IS_REGISTER (symbolP))
537 symbolP->sy_number = symbol_number++;
538 symbolP->sy_name_offset = 0;
539 symbolPP = &(symbol_next (symbolP));
543 if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
545 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP));
548 /* Unhook it from the chain. */
549 *symbolPP = symbol_next (symbolP);
550 } /* if this symbol should be in the output */
552 } /* for each symbol */
554 H_SET_STRING_SIZE (headers, string_byte_count);
555 H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
556 } /* obj_crawl_symbol_chain() */
559 /****** VMS OBJECT FILE HACKING ROUTINES *******/
563 * Create the VMS object file
566 Create_VMS_Object_File ()
568 #if defined(eunice) || !defined(VMS)
569 VMS_Object_File_FD = creat (out_file_name, 0777, "var");
571 VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var",
572 "mbc=16", "deq=64", "fop=tef", "shr=nil");
577 if (VMS_Object_File_FD < 0)
578 as_fatal ("Couldn't create VMS object file \"%s\"", out_file_name);
580 * Initialize object file hacking variables
582 Object_Record_Offset = 0;
583 Current_Object_Record_Type = -1;
588 * Flush the object record buffer to the object file
591 Flush_VMS_Object_Record_Buffer ()
600 * If the buffer is empty, we are done
602 if (Object_Record_Offset == 0)
605 * Write the data to the file
607 #ifndef VMS /* For cross-assembly purposes. */
608 md_number_to_chars((char *) &RecLen, Object_Record_Offset, 2);
609 i = write (VMS_Object_File_FD, &RecLen, 2);
611 i = write (VMS_Object_File_FD,
612 Object_Record_Buffer,
613 Object_Record_Offset);
614 if (i != Object_Record_Offset)
615 error ("I/O error writing VMS object file");
616 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
618 /* pad it if needed */
620 if ((Object_Record_Offset & 1) != 0)
621 write (VMS_Object_File_FD, &zero, 1);
624 * The buffer is now empty
626 Object_Record_Offset = 0;
631 * Declare a particular type of object file record
634 Set_VMS_Object_File_Record (Type)
638 * If the type matches, we are done
640 if (Type == Current_Object_Record_Type)
643 * Otherwise: flush the buffer
645 Flush_VMS_Object_Record_Buffer ();
649 Current_Object_Record_Type = Type;
655 * Close the VMS Object file
658 Close_VMS_Object_File ()
660 #ifndef VMS /* For cross-assembly purposes. */
661 short int m_one = -1;
663 /* Write a record-length field of 0xffff into the file, which means
664 end-of-file when read later. It is only needed for variable-length
665 record files transferred to VMS as fixed-length record files
666 (typical for binary ftp). */
667 write (VMS_Object_File_FD, &m_one, 2);
669 /* When written on a VMS system, the file header (cf inode) will record
670 the actual end-of-file position and no inline marker is needed. */
673 close (VMS_Object_File_FD);
678 * Stack Psect base followed by signed, varying-sized offset.
679 * Common to several object records.
682 vms_tir_stack_psect (Psect_Index, Offset, Force)
687 int psect_width, offset_width;
689 psect_width = ((unsigned) Psect_Index > 255) ? 2 : 1;
690 offset_width = (Force || Offset > 32767 || Offset < -32768) ? 4
691 : (Offset > 127 || Offset < -128) ? 2 : 1;
692 #define Sta_P(p,o) (((o)<<1) | ((p)-1))
693 /* byte or word psect; byte, word, or longword offset */
694 switch (Sta_P(psect_width,offset_width))
696 case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB);
697 PUT_CHAR ((char)(unsigned char) Psect_Index);
698 PUT_CHAR ((char) Offset);
700 case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW);
701 PUT_CHAR ((char)(unsigned char) Psect_Index);
704 case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL);
705 PUT_CHAR ((char)(unsigned char) Psect_Index);
708 case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB);
709 PUT_SHORT (Psect_Index);
710 PUT_CHAR ((char) Offset);
712 case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW);
713 PUT_SHORT (Psect_Index);
716 case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL);
717 PUT_SHORT (Psect_Index);
725 * Store immediate data in current Psect
728 VMS_Store_Immediate_Data (Pointer, Size, Record_Type)
736 * We are writing a "Record_Type" record
738 Set_VMS_Object_File_Record (Record_Type);
740 * We can only store 128 bytes at a time
745 * Store a maximum of 128 bytes
747 i = (Size > 128) ? 128 : Size;
750 * If we cannot accommodate this record, flush the
753 if ((Object_Record_Offset + i + 1) >= sizeof (Object_Record_Buffer))
754 Flush_VMS_Object_Record_Buffer ();
756 * If the buffer is empty we must insert record type
758 if (Object_Record_Offset == 0)
759 PUT_CHAR (Record_Type);
763 PUT_CHAR (-i & 0xff);
768 PUT_CHAR (*Pointer++);
771 * Flush the buffer if it is more than 75% full.
773 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
774 Flush_VMS_Object_Record_Buffer ();
778 * Make a data reference
781 VMS_Set_Data (Psect_Index, Offset, Record_Type, Force)
788 * We are writing a "Record_Type" record
790 Set_VMS_Object_File_Record (Record_Type);
792 * If the buffer is empty we must insert the record type
794 if (Object_Record_Offset == 0)
795 PUT_CHAR (Record_Type);
797 * Stack the Psect base with its offset
799 vms_tir_stack_psect (Psect_Index, Offset, Force);
801 * Set relocation base
803 PUT_CHAR (TIR_S_C_STO_PIDR);
805 * Flush the buffer if it is more than 75% full
807 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
808 Flush_VMS_Object_Record_Buffer ();
812 * Make a debugger reference to a struct, union or enum.
815 VMS_Store_Struct (Struct_Index)
819 * We are writing a "OBJ_S_C_DBG" record
821 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
823 * If the buffer is empty we must insert the record type
825 if (Object_Record_Offset == 0)
826 PUT_CHAR (OBJ_S_C_DBG);
827 PUT_CHAR (TIR_S_C_STA_UW);
828 PUT_SHORT (Struct_Index);
829 PUT_CHAR (TIR_S_C_CTL_STKDL);
830 PUT_CHAR (TIR_S_C_STO_L);
832 * Flush the buffer if it is more than 75% full
834 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
835 Flush_VMS_Object_Record_Buffer ();
839 * Make a debugger reference to partially define a struct, union or enum.
842 VMS_Def_Struct (Struct_Index)
846 * We are writing a "OBJ_S_C_DBG" record
848 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
850 * If the buffer is empty we must insert the record type
852 if (Object_Record_Offset == 0)
853 PUT_CHAR (OBJ_S_C_DBG);
854 PUT_CHAR (TIR_S_C_STA_UW);
855 PUT_SHORT (Struct_Index);
856 PUT_CHAR (TIR_S_C_CTL_DFLOC);
858 * Flush the buffer if it is more than 75% full
860 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
861 Flush_VMS_Object_Record_Buffer ();
865 VMS_Set_Struct (Struct_Index)
867 { /* see previous functions for comments */
868 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
869 if (Object_Record_Offset == 0)
870 PUT_CHAR (OBJ_S_C_DBG);
871 PUT_CHAR (TIR_S_C_STA_UW);
872 PUT_SHORT (Struct_Index);
873 PUT_CHAR (TIR_S_C_CTL_STLOC);
874 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
875 Flush_VMS_Object_Record_Buffer ();
879 * Write the Traceback Module Begin record
882 VMS_TBT_Module_Begin ()
884 register char *cp, *cp1;
886 char Module_Name[256];
890 * Get module name (the FILENAME part of the object file)
896 if ((*cp == ']') || (*cp == '>') ||
897 (*cp == ':') || (*cp == '/'))
903 *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
907 * Limit it to 31 characters
909 while (--cp1 >= Module_Name)
912 if (strlen (Module_Name) > 31)
914 if (flag_hash_long_names)
915 as_tsktsk ("Module name truncated: %s", Module_Name);
919 * Arrange to store the data locally (leave room for size byte)
925 *cp++ = DST_S_C_MODBEG;
931 * Language type == "C"
933 COPY_LONG (cp, DST_S_C_C);
936 * Store the module name
938 *cp++ = strlen (Module_Name);
943 * Now we can store the record size
948 * Put it into the object record
950 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
955 * Write the Traceback Module End record
958 VMS_TBT_Module_End ()
966 Local[1] = DST_S_C_MODEND;
968 * Put it into the object record
970 VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT);
975 * Write the Traceback Routine Begin record
978 VMS_TBT_Routine_Begin (symbolP, Psect)
982 register char *cp, *cp1;
989 * Strip the leading "_" from the name
991 Name = S_GET_NAME (symbolP);
995 * Get the text psect offset
997 Offset = S_GET_VALUE (symbolP);
999 * Calculate the record size
1001 Size = 1 + 1 + 4 + 1 + strlen (Name);
1009 Local[1] = DST_S_C_RTNBEG;
1015 * Store the data so far
1017 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
1019 * Make sure we are still generating a OBJ_S_C_TBT record
1021 if (Object_Record_Offset == 0)
1022 PUT_CHAR (OBJ_S_C_TBT);
1026 vms_tir_stack_psect (Psect, Offset, 0);
1028 * Store the data reference
1030 PUT_CHAR (TIR_S_C_STO_PIDR);
1032 * Store the counted string as data
1036 Size = strlen (cp1) + 1;
1040 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
1045 * Write the Traceback Routine End record
1046 * We *must* search the symbol table to find the next routine, since
1047 * the assember has a way of reassembling the symbol table OUT OF ORDER
1048 * Thus the next routine in the symbol list is not necessarily the
1049 * next one in memory. For debugging to work correctly we must know the
1050 * size of the routine.
1053 VMS_TBT_Routine_End (Max_Size, sp)
1058 int Size = 0x7fffffff;
1060 valueT sym_value, sp_value = S_GET_VALUE (sp);
1062 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1064 if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
1066 if (*S_GET_NAME (symbolP) == 'L')
1068 sym_value = S_GET_VALUE (symbolP);
1069 if (sym_value > sp_value && sym_value < Size)
1073 * Dummy labels like "gcc_compiled." should no longer reach here.
1077 /* check if gcc_compiled. has size of zero */
1078 if (sym_value == sp_value &&
1080 (!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
1081 !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
1086 if (Size == 0x7fffffff)
1088 Size -= sp_value; /* and get the size of the routine */
1096 Local[1] = DST_S_C_RTNEND;
1104 COPY_LONG (&Local[3], Size);
1108 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
1112 * Write the Traceback Block End record
1115 VMS_TBT_Block_Begin (symbolP, Psect, Name)
1120 register char *cp, *cp1;
1127 Size = 1 + 1 + 4 + 1 + strlen (Name);
1133 * Begin Block - We simulate with a phony routine
1135 Local[1] = DST_S_C_BLKBEG;
1141 * Store the data so far
1143 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG);
1145 * Make sure we are still generating a OBJ_S_C_DBG record
1147 if (Object_Record_Offset == 0)
1148 PUT_CHAR (OBJ_S_C_DBG);
1150 * Now get the symbol address
1152 PUT_CHAR (TIR_S_C_STA_WPL);
1155 * Get the text psect offset
1157 Offset = S_GET_VALUE (symbolP);
1160 * Store the data reference
1162 PUT_CHAR (TIR_S_C_STO_PIDR);
1164 * Store the counted string as data
1168 Size = strlen (cp1) + 1;
1172 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG);
1177 * Write the Traceback Block End record
1180 VMS_TBT_Block_End (Size)
1186 * End block - simulate with a phony end routine
1189 Local[1] = DST_S_C_BLKEND;
1190 Local[2] = 0; /* unused, must be zero */
1191 COPY_LONG (&Local[3], Size);
1192 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG);
1198 * Write a Line number / PC correlation record
1201 VMS_TBT_Line_PC_Correlation (Line_Number, Offset, Psect, Do_Delta)
1211 * If not delta, set our PC/Line number correlation
1218 Local[0] = 1 + 1 + 2 + 1 + 4;
1220 * Line Number/PC correlation
1222 Local[1] = DST_S_C_LINE_NUM;
1226 Local[2] = DST_S_C_SET_LINE_NUM;
1227 COPY_SHORT (&Local[3], Line_Number - 1);
1231 Local[5] = DST_S_C_SET_ABS_PC;
1232 VMS_Store_Immediate_Data (Local, 6, OBJ_S_C_TBT);
1234 * Make sure we are still generating a OBJ_S_C_TBT record
1236 if (Object_Record_Offset == 0)
1237 PUT_CHAR (OBJ_S_C_TBT);
1238 vms_tir_stack_psect (Psect, Offset, 0);
1239 PUT_CHAR (TIR_S_C_STO_PIDR);
1241 * Do a PC offset of 0 to register the line number
1244 Local[1] = DST_S_C_LINE_NUM;
1245 Local[2] = 0; /* Increment PC by 0 and register line # */
1246 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
1251 * If Delta is negative, terminate the line numbers
1255 Local[0] = 1 + 1 + 4;
1256 Local[1] = DST_S_C_LINE_NUM;
1257 Local[2] = DST_S_C_TERM_L;
1258 COPY_LONG (&Local[3], Offset);
1259 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
1266 * Do a PC/Line delta
1269 *cp++ = DST_S_C_LINE_NUM;
1270 if (Line_Number > 1)
1273 * We need to increment the line number
1275 if (Line_Number - 1 <= 255)
1277 *cp++ = DST_S_C_INCR_LINUM;
1278 *cp++ = Line_Number - 1;
1282 *cp++ = DST_S_C_INCR_LINUM_W;
1283 COPY_SHORT (cp, Line_Number - 1);
1296 if (Offset < 0x10000)
1298 *cp++ = DST_S_C_DELTA_PC_W;
1299 COPY_SHORT (cp, Offset);
1304 *cp++ = DST_S_C_DELTA_PC_L;
1305 COPY_LONG (cp, Offset);
1309 Local[0] = cp - (Local + 1);
1310 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1316 * Describe a source file to the debugger
1319 VMS_TBT_Source_File (Filename, ID_Number)
1323 register char *cp, *cp1;
1326 #ifndef VMS /* Used for cross-assembly */
1327 i = strlen (Filename);
1329 static struct FAB Fab;
1330 static struct NAM Nam;
1331 static struct XABDAT Date_Xab;
1332 static struct XABFHC File_Header_Xab;
1333 char Es_String[255], Rs_String[255];
1338 Fab.fab$b_bid = FAB$C_BID;
1339 Fab.fab$b_bln = sizeof (Fab);
1340 Fab.fab$l_nam = (&Nam);
1341 Fab.fab$l_xab = (char *) &Date_Xab;
1343 * Setup the Nam block so we can find out the FULL name
1344 * of the source file.
1346 Nam.nam$b_bid = NAM$C_BID;
1347 Nam.nam$b_bln = sizeof (Nam);
1348 Nam.nam$l_rsa = Rs_String;
1349 Nam.nam$b_rss = sizeof (Rs_String);
1350 Nam.nam$l_esa = Es_String;
1351 Nam.nam$b_ess = sizeof (Es_String);
1353 * Setup the Date and File Header Xabs
1355 Date_Xab.xab$b_cod = XAB$C_DAT;
1356 Date_Xab.xab$b_bln = sizeof (Date_Xab);
1357 Date_Xab.xab$l_nxt = (char *) &File_Header_Xab;
1358 File_Header_Xab.xab$b_cod = XAB$C_FHC;
1359 File_Header_Xab.xab$b_bln = sizeof (File_Header_Xab);
1361 * Get the file information
1363 Fab.fab$l_fna = Filename;
1364 Fab.fab$b_fns = strlen (Filename);
1365 Status = sys$open (&Fab);
1368 as_tsktsk ("Couldn't find source file \"%s\", status=%%X%x",
1374 * Calculate the size of the resultant string
1381 Local[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i + 1;
1383 * Source declaration
1385 Local[1] = DST_S_C_SOURCE;
1387 * Make formfeeds count as source records
1389 Local[2] = DST_S_C_SRC_FORMFEED;
1391 * Declare source file
1393 Local[3] = DST_S_C_SRC_DECLFILE;
1394 Local[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i + 1;
1403 COPY_SHORT (cp, ID_Number);
1407 * Creation Date. Unknown, so we fill with zeroes.
1432 #else /* Use this code when assembling for VMS on a VMS system */
1436 memcpy (cp, (char *) &Date_Xab.xab$q_cdt, 8);
1441 COPY_LONG (cp, File_Header_Xab.xab$l_ebk);
1446 COPY_SHORT (cp, File_Header_Xab.xab$w_ffb);
1451 *cp++ = File_Header_Xab.xab$b_rfo;
1461 * Library module name (none)
1467 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1473 * Give the number of source lines to the debugger
1476 VMS_TBT_Source_Lines (ID_Number, Starting_Line_Number, Number_Of_Lines)
1478 int Starting_Line_Number;
1479 int Number_Of_Lines;
1487 Local[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1489 * Source declaration
1491 Local[1] = DST_S_C_SOURCE;
1496 *cp++ = DST_S_C_SRC_SETFILE;
1500 COPY_SHORT (cp, ID_Number);
1505 *cp++ = DST_S_C_SRC_SETREC_L;
1506 COPY_LONG (cp, Starting_Line_Number);
1511 *cp++ = DST_S_C_SRC_DEFLINES_W;
1512 COPY_SHORT (cp, Number_Of_Lines);
1517 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1523 * This routine locates a file in the list of files. If an entry does not
1524 * exist, one is created. For include files, a new entry is always created
1525 * such that inline functions can be properly debugged.
1527 static struct input_file *
1531 struct input_file *same_file = 0;
1532 struct input_file *fpnt, *last = 0;
1535 for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1537 if (fpnt->spnt == sp)
1541 sp_name = S_GET_NAME (sp);
1542 for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1544 if (strcmp (sp_name, fpnt->name) == 0)
1546 if (fpnt->flag == 1)
1552 fpnt = (struct input_file *) xmalloc (sizeof (struct input_file));
1558 fpnt->name = sp_name;
1559 fpnt->min_line = 0x7fffffff;
1563 fpnt->file_number = 0;
1565 fpnt->same_file_fpnt = same_file;
1570 * The following functions and definitions are used to generate object records
1571 * that will describe program variables to the VMS debugger.
1573 * This file contains many of the routines needed to output debugging info into
1574 * the object file that the VMS debugger needs to understand symbols. These
1575 * routines are called very late in the assembly process, and thus we can be
1576 * fairly lax about changing things, since the GSD and the TIR sections have
1577 * already been output.
1581 /* This routine converts a number string into an integer, and stops when it
1582 * sees an invalid character. The return value is the address of the character
1583 * just past the last character read. No error is generated.
1586 cvt_integer (str, rtn)
1591 neg = *str == '-' ? ++str, -1 : 1;
1593 while ((*str <= '9') && (*str >= '0'))
1594 ival = 10 * ival + *str++ - '0';
1599 /* this routine fixes the names that are generated by C++, ".this" is a good
1600 * example. The period does not work for the debugger, since it looks like
1601 * the syntax for a structure element, and thus it gets mightily confused
1603 * We also use this to strip the PsectAttribute hack from the name before we
1604 * write a debugger record */
1612 * Kill any leading "_"
1617 * Is there a Psect Attribute to skip??
1619 if (HAS_PSECT_ATTRIBUTES (pnt))
1624 pnt += PSECT_ATTRIBUTES_STRING_LENGTH;
1627 if ((pnt[0] == '$') && (pnt[1] == '$'))
1635 /* Here we fix the .this -> $this conversion */
1636 for (pnt1 = pnt; *pnt1 != 0; pnt1++)
1644 /* When defining a structure, this routine is called to find the name of
1645 * the actual structure. It is assumed that str points to the equal sign
1646 * in the definition, and it moves backward until it finds the start of the
1647 * name. If it finds a 0, then it knows that this structure def is in the
1648 * outermost level, and thus symbol_name points to the symbol name.
1651 get_struct_name (str)
1656 while ((*pnt != ':') && (*pnt != '\0'))
1659 return (char *) symbol_name;
1661 while ((*pnt != ';') && (*pnt != '='))
1665 while ((*pnt < '0') || (*pnt > '9'))
1667 while ((*pnt >= '0') && (*pnt <= '9'))
1672 /* search symbol list for type number dbx_type. Return a pointer to struct */
1673 static struct VMS_DBG_Symbol *
1674 find_symbol (dbx_type)
1677 struct VMS_DBG_Symbol *spnt;
1679 spnt = VMS_Symbol_type_list[SYMTYP_HASH(dbx_type)];
1680 while (spnt != (struct VMS_DBG_Symbol *) NULL)
1682 if (spnt->dbx_type == dbx_type)
1686 if (!spnt || spnt->advanced != ALIAS)
1688 return find_symbol(spnt->type2);
1692 #if 0 /* obsolete */
1693 /* this routine puts info into either Local or Asuffix, depending on the sign
1694 * of size. The reason is that it is easier to build the variable descriptor
1695 * backwards, while the array descriptor is best built forwards. In the end
1696 * they get put together, if there is not a struct/union/enum along the way
1712 md_number_to_chars (&Local[Lpnt + 1], value, size1);
1716 if (Apoint + size1 >= MAX_DEBUG_RECORD)
1719 Apoint = MAX_DEBUG_RECORD - 1;
1722 md_number_to_chars (&Asuffix[Apoint], value, size1);
1733 if (Apoint + size >= MAX_DEBUG_RECORD)
1736 Apoint = MAX_DEBUG_RECORD - 1;
1740 Asuffix[Apoint++] = (char) value;
1743 md_number_to_chars (&Asuffix[Apoint], value, size);
1759 Local[Lpnt--] = (char) value;
1763 md_number_to_chars (&Local[Lpnt + 1], value, size);
1767 /* this routine generates the array descriptor for a given array */
1769 array_suffix (spnt2)
1770 struct VMS_DBG_Symbol *spnt2;
1772 struct VMS_DBG_Symbol *spnt;
1773 struct VMS_DBG_Symbol *spnt1;
1779 while (spnt->advanced != ARRAY)
1781 spnt = find_symbol (spnt->type2);
1782 if (spnt == (struct VMS_DBG_Symbol *) NULL)
1787 while (spnt1->advanced == ARRAY)
1790 total_size *= (spnt1->index_max - spnt1->index_min + 1);
1791 spnt1 = find_symbol (spnt1->type2);
1793 total_size = total_size * spnt1->data_size;
1794 fpush (spnt1->data_size, 2); /* element size */
1795 if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
1798 fpush (spnt1->VMS_type, 1); /* element type */
1799 fpush (DSC_K_CLASS_A, 1); /* descriptor class */
1800 fpush (0, 4); /* base address */
1801 fpush (0, 1); /* scale factor -- not applicable */
1802 fpush (0, 1); /* digit count -- not applicable */
1803 fpush (0xc0, 1); /* flags: multiplier block & bounds present */
1804 fpush (rank, 1); /* number of dimensions */
1805 fpush (total_size, 4);
1806 fpush (0, 4); /* pointer to element [0][0]...[0] */
1808 while (spnt1->advanced == ARRAY)
1810 fpush (spnt1->index_max - spnt1->index_min + 1, 4);
1811 spnt1 = find_symbol (spnt1->type2);
1814 while (spnt1->advanced == ARRAY)
1816 fpush (spnt1->index_min, 4);
1817 fpush (spnt1->index_max, 4);
1818 spnt1 = find_symbol (spnt1->type2);
1822 /* this routine generates the start of a variable descriptor based upon
1823 * a struct/union/enum that has yet to be defined. We define this spot as
1824 * a new location, and save four bytes for the address. When the struct is
1825 * finally defined, then we can go back and plug in the correct address.
1828 new_forward_ref (dbx_type)
1831 struct forward_ref *fpnt;
1832 fpnt = (struct forward_ref *) xmalloc (sizeof (struct forward_ref));
1833 fpnt->next = f_ref_root;
1835 fpnt->dbx_type = dbx_type;
1836 fpnt->struc_numb = ++structure_count;
1837 fpnt->resolved = 'N';
1838 rpush (DST_K_TS_IND, 1); /* indirect type specification */
1840 rpush (total_len, 2);
1841 struct_number = -fpnt->struc_numb;
1844 /* this routine generates the variable descriptor used to describe non-basic
1845 * variables. It calls itself recursively until it gets to the bottom of it
1846 * all, and then builds the descriptor backwards. It is easiest to do it this
1847 *way since we must periodically write length bytes, and it is easiest if we know
1848 *the value when it is time to write it.
1851 gen1 (spnt, array_suffix_len)
1852 struct VMS_DBG_Symbol *spnt;
1853 int array_suffix_len;
1855 struct VMS_DBG_Symbol *spnt1;
1858 switch (spnt->advanced)
1861 rpush (DBG_S_C_VOID, 1);
1863 rpush (total_len, 2);
1867 if (array_suffix_len == 0)
1869 rpush (spnt->VMS_type, 1);
1870 rpush (DBG_S_C_BASIC, 1);
1872 rpush (total_len, 2);
1876 rpush (DST_K_VFLAGS_DSC, 1);
1877 rpush (DST_K_TS_DSC, 1); /* descriptor type specification */
1883 struct_number = spnt->struc_numb;
1884 if (struct_number < 0)
1886 new_forward_ref (spnt->dbx_type);
1889 rpush (DBG_S_C_STRUCT, 1);
1891 rpush (total_len, 2);
1894 spnt1 = find_symbol (spnt->type2);
1897 new_forward_ref (spnt->type2);
1899 i = gen1 (spnt1, 0);
1901 { /* (*void) is a special case, do not put pointer suffix */
1902 rpush (DBG_S_C_POINTER, 1);
1904 rpush (total_len, 2);
1909 while (spnt1->advanced == ARRAY)
1911 spnt1 = find_symbol (spnt1->type2);
1914 as_tsktsk ("debugger forward reference error, dbx type %d",
1919 /* It is too late to generate forward references, so the user gets a message.
1920 * This should only happen on a compiler error */
1921 (void) gen1 (spnt1, 1);
1923 array_suffix (spnt);
1924 array_suffix_len = Apoint - i;
1925 switch (spnt1->advanced)
1933 rpush (total_len, 2);
1934 rpush (DST_K_VFLAGS_DSC, 1);
1935 rpush (1, 1); /* flags: element value spec included */
1936 rpush (1, 1); /* one dimension */
1937 rpush (DBG_S_C_COMPLEX_ARRAY, 1);
1939 total_len += array_suffix_len + 8;
1940 rpush (total_len, 2);
1942 default: /* lint suppression */
1948 /* This generates a suffix for a variable. If it is not a defined type yet,
1949 * then dbx_type contains the type we are expecting so we can generate a
1950 * forward reference. This calls gen1 to build most of the descriptor, and
1951 * then it puts the icing on at the end. It then dumps whatever is needed
1952 * to get a complete descriptor (i.e. struct reference, array suffix ).
1955 generate_suffix (spnt, dbx_type)
1956 struct VMS_DBG_Symbol *spnt;
1959 static const char pvoid[6] = {
1960 5, /* record.length == 5 */
1961 DST_K_TYPSPEC, /* record.type == 1 (type specification) */
1962 0, /* name.length == 0, no name follows */
1963 1, 0, /* type.length == 1 {2 bytes, little endian} */
1964 DBG_S_C_VOID /* type.type == 5 (pointer to unspecified) */
1969 Lpnt = MAX_DEBUG_RECORD - 1;
1974 new_forward_ref (dbx_type);
1977 if (spnt->VMS_type != DBG_S_C_ADVANCED_TYPE)
1978 return; /* no suffix needed */
1981 rpush (0, 1); /* no name (len==0) */
1982 rpush (DST_K_TYPSPEC, 1);
1984 rpush (total_len, 1);
1985 /* if the variable descriptor overflows the record, output a descriptor for
1986 * a pointer to void.
1988 if ((total_len >= MAX_DEBUG_RECORD) || overflow)
1990 as_warn ("Variable descriptor %d too complicated. Defined as `void *'.",
1992 VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG);
1996 while (Lpnt < MAX_DEBUG_RECORD - 1)
1997 Local[i++] = Local[++Lpnt];
1999 /* we use this for a reference to a structure that has already been defined */
2000 if (struct_number > 0)
2002 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
2004 VMS_Store_Struct (struct_number);
2006 /* We use this for a forward reference to a structure that has yet to be
2007 * defined. We store four bytes of zero to make room for the actual address
2010 if (struct_number < 0)
2012 struct_number = -struct_number;
2013 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
2015 VMS_Def_Struct (struct_number);
2016 COPY_LONG(&Local[Lpnt], 0L);
2018 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
2023 Local[Lpnt++] = Asuffix[i++];
2025 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
2029 /* "novel length" type doesn't work for simple atomic types */
2030 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
2031 #undef SETUP_BASIC_TYPES
2034 bitfield_suffix (spnt, width)
2035 struct VMS_DBG_Symbol *spnt;
2038 Local[Lpnt++] = 13; /* rec.len==13 */
2039 Local[Lpnt++] = DST_K_TYPSPEC; /* a type specification record */
2040 Local[Lpnt++] = 0; /* not named */
2041 COPY_SHORT(&Local[Lpnt], 9); /* typ.len==9 */
2043 Local[Lpnt++] = DST_K_TS_NOV_LENG; /* This type is a "novel length"
2044 incarnation of some other type. */
2045 COPY_LONG(&Local[Lpnt], width); /* size in bits == novel length */
2047 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
2049 /* assert( spnt->struc_numb > 0 ); */
2050 VMS_Store_Struct (spnt->struc_numb); /* output 4 more bytes */
2053 /* Formally define a builtin type, so that it can serve as the target of
2054 an indirect reference. It makes bitfield_suffix() easier by avoiding
2055 the need to use a forward reference for the first occurrence of each
2056 type used in a bitfield. */
2058 setup_basic_type (spnt)
2059 struct VMS_DBG_Symbol *spnt;
2061 #ifdef SETUP_BASIC_TYPES
2062 /* This would be very useful if "novel length" fields actually worked
2063 with basic types like they do with enumerated types. However,
2064 they do not, so this isn't worth doing just so that you can use
2065 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
2067 #ifndef SETUP_SYNONYM_TYPES
2068 /* This determines whether compatible things like `int' and `long int'
2069 ought to have distinct type records rather than sharing one. */
2070 struct VMS_DBG_Symbol *spnt2;
2072 /* first check whether this type has already been seen by another name */
2073 for (spnt2 = VMS_Symbol_type_list[SYMTYP_HASH(spnt->VMS_type)];
2075 spnt2 = spnt2->next)
2076 if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type)
2078 spnt->struc_numb = spnt2->struc_numb;
2083 /* `structure number' doesn't really mean `structure'; it means an index
2084 into a linker maintained set of saved locations which can be referenced
2086 spnt->struc_numb = ++structure_count;
2087 VMS_Def_Struct (spnt->struc_numb); /* remember where this type lives */
2088 /* define the simple scalar type */
2089 Local[Lpnt++] = 6 + strlen (symbol_name) + 2; /* rec.len */
2090 Local[Lpnt++] = DST_K_TYPSPEC; /* rec.typ==type specification */
2091 Local[Lpnt++] = strlen (symbol_name) + 2;
2092 Local[Lpnt++] = '_'; /* prefix name with "__" */
2093 Local[Lpnt++] = '_';
2094 for (p = symbol_name; *p; p++)
2095 Local[Lpnt++] = *p == ' ' ? '_' : *p;
2096 COPY_SHORT(&Local[Lpnt], 2); /* typ.len==2 */
2098 Local[Lpnt++] = DST_K_TS_ATOM; /* typ.kind is simple type */
2099 Local[Lpnt++] = spnt->VMS_type; /* typ.type */
2100 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
2102 #endif /* SETUP_BASIC_TYPES */
2106 /* This routine generates a symbol definition for a C symbol for the debugger.
2107 * It takes a psect and offset for global symbols; if psect < 0, then this is
2108 * a local variable and the offset is relative to FP. In this case it can
2109 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2112 VMS_DBG_record (spnt, Psect, Offset, Name)
2113 struct VMS_DBG_Symbol *spnt;
2122 /* if there are bad characters in name, convert them */
2123 Name_pnt = fix_name (Name);
2125 len = strlen(Name_pnt);
2127 { /* this is a local variable, referenced to SP */
2128 Local[i++] = 7 + len;
2129 Local[i++] = spnt->VMS_type;
2130 Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM;
2131 COPY_LONG (&Local[i], Offset);
2136 Local[i++] = 7 + len;
2137 Local[i++] = spnt->VMS_type;
2138 Local[i++] = DST_K_VALKIND_ADDR;
2139 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2141 VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
2144 while (*Name_pnt != '\0')
2145 Local[i++] = *Name_pnt++;
2146 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2147 if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
2148 generate_suffix (spnt, 0);
2152 /* This routine parses the stabs entries in order to make the definition
2153 * for the debugger of local symbols and function parameters
2156 VMS_local_stab_Parse (sp)
2162 struct VMS_DBG_Symbol *spnt;
2166 str = S_GET_NAME (sp);
2167 pnt = (char *) strchr (str, ':');
2168 if (pnt == (char *) NULL)
2169 return; /* no colon present */
2170 pnt1 = pnt++; /* save this for later, and skip colon */
2172 return; /* ignore static constants */
2174 /* there is one little catch that we must be aware of. Sometimes function
2175 * parameters are optimized into registers, and the compiler, in its infiite
2176 * wisdom outputs stabs records for *both*. In general we want to use the
2177 * register if it is present, so we must search the rest of the symbols for
2178 * this function to see if this parameter is assigned to a register.
2186 for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1))
2188 if (!S_IS_DEBUG (sp1))
2190 if (S_GET_RAW_TYPE (sp1) == N_FUN)
2192 char * pnt3=(char*) strchr (S_GET_NAME (sp1), ':') + 1;
2193 if (*pnt3 == 'F' || *pnt3 == 'f') break;
2195 if (S_GET_RAW_TYPE (sp1) != N_RSYM)
2197 str1 = S_GET_NAME (sp1); /* and get the name */
2199 while (*pnt2 != ':')
2206 if ((*str1 != ':') || (*pnt2 != ':'))
2208 return; /* they are the same! lets skip this one */
2210 /* first find the dbx symbol type from list, and then find VMS type */
2211 pnt++; /* skip p in case no register */
2214 pnt = cvt_integer (pnt, &dbx_type);
2215 spnt = find_symbol (dbx_type);
2217 return; /*Dunno what this is*/
2219 VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
2220 *pnt1 = ':'; /* and restore the string */
2224 /* This routine parses a stabs entry to find the information required to define
2225 * a variable. It is used for global and static variables.
2226 * Basically we need to know the address of the symbol. With older versions
2227 * of the compiler, const symbols are
2228 * treated differently, in that if they are global they are written into the
2229 * text psect. The global symbol entry for such a const is actually written
2230 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2231 * of psects, we must search the entry points as well. static consts are even
2232 * harder, since they are never assigned a memory address. The compiler passes
2233 * a stab to tell us the value, but I am not sure what to do with it.
2237 VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect)
2239 int expected_type; /* char */
2240 int type1, type2, Text_Psect;
2246 struct VMS_DBG_Symbol *spnt;
2247 struct VMS_Symbol *vsp;
2251 str = S_GET_NAME (sp);
2252 pnt = (char *) strchr (str, ':');
2253 if (pnt == (char *) NULL)
2254 return; /* no colon present */
2255 pnt1 = pnt; /* save this for later*/
2257 if (*pnt == expected_type)
2259 pnt = cvt_integer (pnt + 1, &dbx_type);
2260 spnt = find_symbol (dbx_type);
2261 if (spnt == (struct VMS_DBG_Symbol *) NULL)
2262 return; /*Dunno what this is*/
2263 /* now we need to search the symbol table to find the psect and offset for
2268 while (vsp != (struct VMS_Symbol *) NULL)
2270 pnt = S_GET_NAME (vsp->Symbol);
2271 if (pnt != (char *) NULL)
2273 /* make sure name is the same, and make sure correct symbol type */
2274 if ((strlen (pnt) == strlen (str)) && (strcmp (pnt, str) == 0)
2275 && ((S_GET_RAW_TYPE (vsp->Symbol) == type1) ||
2276 (S_GET_RAW_TYPE (vsp->Symbol) == type2)))
2280 if (vsp != (struct VMS_Symbol *) NULL)
2282 VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str);
2283 *pnt1 = ':'; /* and restore the string */
2286 /* the symbol was not in the symbol list, but it may be an "entry point"
2287 if it was a constant */
2288 for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
2291 * Dispatch on STAB type
2293 if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT))
2295 pnt = S_GET_NAME (sp1);
2298 if (strcmp (pnt, str) == 0)
2300 if (!gave_compiler_message && expected_type == 'G')
2302 static const char long_const_msg[] = "\
2303 ***Warning - the assembly code generated by the compiler has placed \n\
2304 global constant(s) in the text psect. These will not be available to \n\
2305 other modules, since this is not the correct way to handle this. You \n\
2306 have two options: 1) get a patched compiler that does not put global \n\
2307 constants in the text psect, or 2) remove the 'const' keyword from \n\
2308 definitions of global variables in your source module(s). Don't say \n\
2309 I didn't warn you! \n";
2311 as_tsktsk (long_const_msg);
2312 gave_compiler_message = 1;
2314 VMS_DBG_record (spnt,
2319 *S_GET_NAME (sp1) = 'L';
2320 /* fool assembler to not output this
2321 * as a routine in the TBT */
2326 *pnt1 = ':'; /* and restore the string */
2331 VMS_GSYM_Parse (sp, Text_Psect)
2334 { /* Global variables */
2335 VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect);
2340 VMS_LCSYM_Parse (sp, Text_Psect)
2343 { /* Static symbols - uninitialized */
2344 VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
2348 VMS_STSYM_Parse (sp, Text_Psect)
2351 { /* Static symbols - initialized */
2352 VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect);
2356 /* for register symbols, we must figure out what range of addresses within the
2357 * psect are valid. We will use the brackets in the stab directives to give us
2358 * guidance as to the PC range that this variable is in scope. I am still not
2359 * completely comfortable with this but as I learn more, I seem to get a better
2360 * handle on what is going on.
2364 VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
2365 symbolS *sp, *Current_Routine;
2372 struct VMS_DBG_Symbol *spnt;
2376 int Min_Offset = -1; /* min PC of validity */
2377 int Max_Offset = 0; /* max PC of validity */
2380 for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
2383 * Dispatch on STAB type
2385 switch (S_GET_RAW_TYPE (symbolP))
2389 Min_Offset = S_GET_VALUE (symbolP);
2393 Max_Offset = S_GET_VALUE (symbolP) - 1;
2396 if ((Min_Offset != -1) && (bcnt == 0))
2398 if (S_GET_RAW_TYPE (symbolP) == N_FUN)
2400 pnt=(char*) strchr (S_GET_NAME (symbolP), ':') + 1;
2401 if (*pnt == 'F' || *pnt == 'f') break;
2405 /* Check to see that the addresses were defined. If not, then there were no
2406 * brackets in the function, and we must try to search for the next function.
2407 * Since functions can be in any order, we should search all of the symbol
2408 * list to find the correct ending address. */
2409 if (Min_Offset == -1)
2411 int Max_Source_Offset;
2413 Min_Offset = S_GET_VALUE (sp);
2414 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2417 * Dispatch on STAB type
2419 switch (S_GET_RAW_TYPE (symbolP))
2421 case N_TEXT | N_EXT:
2422 This_Offset = S_GET_VALUE (symbolP);
2423 if ((This_Offset > Min_Offset) && (This_Offset < Max_Offset))
2424 Max_Offset = This_Offset;
2427 This_Offset = S_GET_VALUE (symbolP);
2428 if (This_Offset > Max_Source_Offset)
2429 Max_Source_Offset = This_Offset;
2433 /* if this is the last routine, then we use the PC of the last source line
2434 * as a marker of the max PC for which this reg is valid */
2435 if (Max_Offset == 0x7fffffff)
2436 Max_Offset = Max_Source_Offset;
2439 str = S_GET_NAME (sp);
2440 pnt = (char *) strchr (str, ':');
2441 if (pnt == (char *) NULL)
2442 return; /* no colon present */
2443 pnt1 = pnt; /* save this for later*/
2447 pnt = cvt_integer (pnt + 1, &dbx_type);
2448 spnt = find_symbol (dbx_type);
2450 return; /*Dunno what this is yet*/
2452 pnt = fix_name (S_GET_NAME (sp)); /* if there are bad characters in name, convert them */
2454 Local[i++] = 25 + len;
2455 Local[i++] = spnt->VMS_type;
2456 Local[i++] = DST_K_VFLAGS_TVS; /* trailing value specified */
2457 COPY_LONG(&Local[i], 1 + len); /* relative offset, beyond name */
2459 Local[i++] = len; /* name length (ascic prefix) */
2460 while (*pnt != '\0')
2461 Local[i++] = *pnt++;
2462 Local[i++] = DST_K_VS_FOLLOWS; /* value specification follows */
2463 COPY_SHORT(&Local[i], 15); /* length of rest of record */
2465 Local[i++] = DST_K_VS_ALLOC_SPLIT; /* split lifetime */
2466 Local[i++] = 1; /* one binding follows */
2467 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2469 VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
2470 VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
2471 Local[i++] = DST_K_VALKIND_REG; /* nested value spec */
2472 COPY_LONG(&Local[i], S_GET_VALUE (sp));
2474 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2476 if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
2477 generate_suffix (spnt, 0);
2480 /* this function examines a structure definition, checking all of the elements
2481 * to make sure that all of them are fully defined. The only thing that we
2482 * kick out are arrays of undefined structs, since we do not know how big
2483 * they are. All others we can handle with a normal forward reference.
2486 forward_reference (pnt)
2490 struct VMS_DBG_Symbol *spnt;
2491 struct VMS_DBG_Symbol *spnt1;
2492 pnt = cvt_integer (pnt + 1, &i);
2494 return 0; /* no forward references */
2497 pnt = (char *) strchr (pnt, ':');
2498 pnt = cvt_integer (pnt + 1, &i);
2499 spnt = find_symbol (i);
2500 if(spnt != (struct VMS_DBG_Symbol*) NULL) {
2501 while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY))
2504 spnt1 = find_symbol (spnt->type2);
2505 if ((spnt->advanced == ARRAY) &&
2506 (spnt1 == (struct VMS_DBG_Symbol *) NULL))
2508 if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
2513 pnt = cvt_integer (pnt + 1, &i);
2514 pnt = cvt_integer (pnt + 1, &i);
2515 } while (*++pnt != ';');
2516 return 0; /* no forward refences found */
2519 /* Used to check a single element of a structure on the final pass*/
2522 final_forward_reference (spnt)
2523 struct VMS_DBG_Symbol *spnt;
2525 struct VMS_DBG_Symbol *spnt1;
2527 while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
2529 spnt1 = find_symbol(spnt->type2);
2530 if (spnt->advanced == ARRAY && !spnt1) return 1;
2533 return 0; /* no forward refences found */
2536 /* This routine parses the stabs directives to find any definitions of dbx type
2537 * numbers. It makes a note of all of them, creating a structure element
2538 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2539 * debugger that describes the struct/union/enum, so that further references
2540 * to these data types will be by number
2541 * We have to process pointers right away, since there can be references
2542 * to them later in the same stabs directive. We cannot have forward
2543 * references to pointers, (but we can have a forward reference to a pointer to
2544 * a structure/enum/union) and this is why we process them immediately.
2545 * After we process the pointer, then we search for defs that are nested even
2547 * 8/15/92: We have to process arrays right away too, because there can
2548 * be multiple references to identical array types in one structure
2549 * definition, and only the first one has the definition. (We tend to
2550 * parse from the back going forward.
2553 VMS_typedef_parse (str)
2561 struct forward_ref *fpnt;
2562 int i1, i2, i3, len;
2563 struct VMS_DBG_Symbol *spnt;
2564 struct VMS_DBG_Symbol *spnt1;
2566 /* check for any nested def's */
2567 pnt = (char *) strchr (str + 1, '=');
2568 if ((pnt != (char *) NULL) && (*(str + 1) != '*')
2569 && (str[1] != 'a' || str[2] != 'r'))
2570 if (VMS_typedef_parse (pnt) == 1)
2572 /* now find dbx_type of entry */
2575 { /* check for static constants */
2576 *str = '\0'; /* for now we ignore them */
2579 while ((*pnt <= '9') && (*pnt >= '0'))
2581 pnt++; /* and get back to the number */
2582 cvt_integer (pnt, &i1);
2583 spnt = find_symbol (i1);
2584 /* first we see if this has been defined already, due to a forward reference*/
2587 i2 = SYMTYP_HASH(i1);
2588 spnt = (struct VMS_DBG_Symbol *) xmalloc (sizeof (struct VMS_DBG_Symbol));
2589 spnt->next = VMS_Symbol_type_list[i2];
2590 VMS_Symbol_type_list[i2] = spnt;
2591 spnt->dbx_type = i1; /* and save the type */
2592 spnt->type2 = spnt->VMS_type = spnt->data_size = 0;
2593 spnt->index_min = spnt->index_max = spnt->struc_numb = 0;
2595 /* for structs and unions, do a partial parse, otherwise we sometimes get
2596 * circular definitions that are impossible to resolve. We read enough info
2597 * so that any reference to this type has enough info to be resolved
2599 pnt = str + 1; /* point to character past equal sign */
2600 if ((*pnt == 'u') || (*pnt == 's'))
2603 if ((*pnt <= '9') && (*pnt >= '0'))
2605 if (type_check ("void"))
2606 { /* this is the void symbol */
2608 spnt->advanced = VOID;
2611 if (type_check ("unknown type"))
2614 spnt->advanced = UNKNOWN;
2617 pnt1 = cvt_integer(pnt,&i1);
2618 if(i1 != spnt->dbx_type)
2620 spnt->advanced = ALIAS;
2625 as_tsktsk ("debugginer output: %d is an unknown untyped variable.",
2627 return 1; /* do not know what this is */
2629 /* now define this module*/
2630 pnt = str + 1; /* point to character past equal sign */
2634 spnt->advanced = BASIC;
2635 if (type_check ("int"))
2637 spnt->VMS_type = DBG_S_C_SLINT;
2638 spnt->data_size = 4;
2640 else if (type_check ("long int"))
2642 spnt->VMS_type = DBG_S_C_SLINT;
2643 spnt->data_size = 4;
2645 else if (type_check ("unsigned int"))
2647 spnt->VMS_type = DBG_S_C_ULINT;
2648 spnt->data_size = 4;
2650 else if (type_check ("long unsigned int"))
2652 spnt->VMS_type = DBG_S_C_ULINT;
2653 spnt->data_size = 4;
2655 else if (type_check ("short int"))
2657 spnt->VMS_type = DBG_S_C_SSINT;
2658 spnt->data_size = 2;
2660 else if (type_check ("short unsigned int"))
2662 spnt->VMS_type = DBG_S_C_USINT;
2663 spnt->data_size = 2;
2665 else if (type_check ("char"))
2667 spnt->VMS_type = DBG_S_C_SCHAR;
2668 spnt->data_size = 1;
2670 else if (type_check ("signed char"))
2672 spnt->VMS_type = DBG_S_C_SCHAR;
2673 spnt->data_size = 1;
2675 else if (type_check ("unsigned char"))
2677 spnt->VMS_type = DBG_S_C_UCHAR;
2678 spnt->data_size = 1;
2680 else if (type_check ("float"))
2682 spnt->VMS_type = DBG_S_C_REAL4;
2683 spnt->data_size = 4;
2685 else if (type_check ("double"))
2687 spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
2688 spnt->data_size = 8;
2690 else if (type_check ("long double"))
2692 /* same as double, at least for now */
2693 spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
2694 spnt->data_size = 8;
2696 else if (type_check ("long long int"))
2698 spnt->VMS_type = DBG_S_C_SQUAD; /* signed quadword */
2699 spnt->data_size = 8;
2701 else if (type_check ("long long unsigned int"))
2703 spnt->VMS_type = DBG_S_C_UQUAD; /* unsigned quadword */
2704 spnt->data_size = 8;
2706 else if (type_check ("complex float"))
2708 spnt->VMS_type = DBG_S_C_COMPLX4;
2709 spnt->data_size = 2 * 4;
2711 else if (type_check ("complex double"))
2713 spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
2714 spnt->data_size = 2 * 8;
2716 else if (type_check ("complex long double"))
2718 /* same as complex double, at least for now */
2719 spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
2720 spnt->data_size = 2 * 8;
2725 * Shouldn't get here, but if we do, something
2726 * more substantial ought to be done...
2729 spnt->data_size = 0;
2731 if (spnt->VMS_type != 0)
2732 setup_basic_type(spnt);
2733 pnt1 = (char *) strchr (str, ';') + 1;
2737 spnt->advanced = (*pnt == 's') ? STRUCT : UNION;
2738 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2739 pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
2740 if (!final_pass && forward_reference(pnt))
2742 spnt->struc_numb = -1;
2745 spnt->struc_numb = ++structure_count;
2747 pnt = get_struct_name (str);
2748 VMS_Def_Struct (spnt->struc_numb);
2750 for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
2751 if (fpnt->dbx_type == spnt->dbx_type)
2753 fpnt->resolved = 'Y';
2754 VMS_Set_Struct (fpnt->struc_numb);
2755 VMS_Store_Struct (spnt->struc_numb);
2759 VMS_Set_Struct (spnt->struc_numb);
2761 Local[i++] = 11 + strlen (pnt);
2762 Local[i++] = DBG_S_C_STRUCT_START;
2763 Local[i++] = DST_K_VFLAGS_NOVAL; /* structure definition only */
2764 COPY_LONG(&Local[i], 0L); /* hence value is unused */
2766 Local[i++] = strlen (pnt);
2768 while (*pnt2 != '\0')
2769 Local[i++] = *pnt2++;
2770 i2 = spnt->data_size * 8; /* number of bits */
2771 COPY_LONG(&Local[i], i2);
2773 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2775 if (pnt != symbol_name)
2777 pnt += strlen (pnt);
2779 } /* replace colon for later */
2780 while (*++pnt1 != ';')
2782 pnt = (char *) strchr (pnt1, ':');
2785 pnt1 = cvt_integer (pnt + 1, &dtype);
2786 pnt1 = cvt_integer (pnt1 + 1, &i2);
2787 pnt1 = cvt_integer (pnt1 + 1, &i3);
2788 spnt1 = find_symbol (dtype);
2789 len = strlen (pnt2);
2790 if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM)
2791 && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0)))
2793 if (USE_BITSTRING_DESCRIPTOR (spnt1))
2795 /* This uses a type descriptor, which doesn't work if
2796 the enclosing structure has been placed in a register.
2797 Also, enum bitfields degenerate to simple integers. */
2798 int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT
2799 || spnt1->VMS_type == DBG_S_C_USINT
2800 || spnt1->VMS_type == DBG_S_C_UCHAR
2801 || spnt1->VMS_type == DBG_S_C_UQUAD
2802 || spnt1->advanced == ENUM); /* (approximate) */
2804 fpush (19 + len, 1);
2805 fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
2806 fpush (DST_K_VFLAGS_DSC, 1); /* specified by descriptor */
2807 fpush (1 + len, 4); /* relative offset to descriptor */
2808 fpush (len, 1); /* length byte (ascic prefix) */
2809 while (*pnt2 != '\0') /* name bytes */
2811 fpush (i3, 2); /* dsc length == size of bitfield */
2812 /* dsc type == un?signed bitfield */
2813 fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
2814 fpush (DSC_K_CLASS_UBS, 1); /* dsc class == unaligned bitstring */
2815 fpush (0x00, 4); /* dsc pointer == zeroes */
2816 fpush (i2, 4); /* start position */
2817 VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
2822 /* Use a "novel length" type specification, which works
2823 right for register structures and for enum bitfields
2824 but results in larger object modules. */
2825 Local[i++] = 7 + len;
2826 Local[i++] = DBG_S_C_ADVANCED_TYPE; /* type spec follows */
2827 Local[i++] = DBG_S_C_STRUCT_ITEM; /* value is a bit offset */
2828 COPY_LONG (&Local[i], i2); /* bit offset */
2830 Local[i++] = strlen (pnt2);
2831 while (*pnt2 != '\0')
2832 Local[i++] = *pnt2++;
2833 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2835 bitfield_suffix (spnt1, i3);
2839 { /* not a bitfield */
2840 /* check if this is a forward reference */
2841 if(final_pass && final_forward_reference(spnt1))
2843 as_tsktsk ("debugger output: structure element `%s' has undefined type",
2847 Local[i++] = 7 + len;
2848 Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE;
2849 Local[i++] = DBG_S_C_STRUCT_ITEM;
2850 COPY_LONG (&Local[i], i2); /* bit offset */
2852 Local[i++] = strlen (pnt2);
2853 while (*pnt2 != '\0')
2854 Local[i++] = *pnt2++;
2855 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2858 generate_suffix (spnt1, dtype);
2859 else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
2860 generate_suffix (spnt1, 0);
2864 Local[i++] = 0x01; /* length byte */
2865 Local[i++] = DBG_S_C_STRUCT_END;
2866 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2870 spnt->advanced = ENUM;
2871 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2872 spnt->struc_numb = ++structure_count;
2873 spnt->data_size = 4;
2874 VMS_Def_Struct (spnt->struc_numb);
2876 for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
2877 if (fpnt->dbx_type == spnt->dbx_type)
2879 fpnt->resolved = 'Y';
2880 VMS_Set_Struct (fpnt->struc_numb);
2881 VMS_Store_Struct (spnt->struc_numb);
2885 VMS_Set_Struct (spnt->struc_numb);
2887 len = strlen (symbol_name);
2888 Local[i++] = 3 + len;
2889 Local[i++] = DBG_S_C_ENUM_START;
2890 Local[i++] = 4 * 8; /* enum values are 32 bits */
2893 while (*pnt2 != '\0')
2894 Local[i++] = *pnt2++;
2895 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2897 while (*++pnt != ';')
2899 pnt1 = (char *) strchr (pnt, ':');
2901 pnt1 = cvt_integer (pnt1, &i1);
2903 Local[i++] = 7 + len;
2904 Local[i++] = DBG_S_C_ENUM_ITEM;
2905 Local[i++] = DST_K_VALKIND_LITERAL;
2906 COPY_LONG (&Local[i], i1);
2910 while (*pnt != '\0')
2911 Local[i++] = *pnt++;
2912 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2914 pnt = pnt1; /* Skip final semicolon */
2916 Local[i++] = 0x01; /* len byte */
2917 Local[i++] = DBG_S_C_ENUM_END;
2918 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2923 spnt->advanced = ARRAY;
2924 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2925 pnt = (char *) strchr (pnt, ';');
2928 pnt1 = cvt_integer (pnt + 1, &spnt->index_min);
2929 pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max);
2930 pnt1 = cvt_integer (pnt1 + 1, &spnt->type2);
2931 pnt = (char *) strchr (str + 1, '=');
2932 if (pnt && VMS_typedef_parse (pnt) == 1)
2936 spnt->advanced = FUNCTION;
2937 spnt->VMS_type = DBG_S_C_FUNCTION_ADDR;
2938 /* this masquerades as a basic type*/
2939 spnt->data_size = 4;
2940 pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2943 spnt->advanced = POINTER;
2944 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2945 spnt->data_size = 4;
2946 pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2947 pnt = (char *) strchr (str + 1, '=');
2948 if (pnt && VMS_typedef_parse (pnt) == 1)
2952 spnt->advanced = UNKNOWN;
2954 as_tsktsk ("debugger output: %d is an unknown type of variable.",
2956 return 1; /* unable to decipher */
2958 /* this removes the evidence of the definition so that the outer levels of
2959 parsing do not have to worry about it */
2961 while (*pnt1 != '\0')
2969 * This is the root routine that parses the stabs entries for definitions.
2970 * it calls VMS_typedef_parse, which can in turn call itself.
2971 * We need to be careful, since sometimes there are forward references to
2972 * other symbol types, and these cannot be resolved until we have completed
2975 * Also check and see if we are using continuation stabs, if we are, then
2976 * paste together the entire contents of the stab before we pass it to
2977 * VMS_typedef_parse.
2986 char *parse_buffer = 0;
2988 int incomplete, pass, incom1;
2989 struct forward_ref *fpnt;
2997 incom1 = incomplete;
2999 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
3002 * Deal with STAB symbols
3004 if (S_IS_DEBUG (sp))
3007 * Dispatch on STAB type
3009 switch (S_GET_RAW_TYPE (sp))
3017 case N_FUN: /*sometimes these contain typedefs*/
3018 str = S_GET_NAME (sp);
3020 pnt = str + strlen(str) -1;
3021 if (*pnt == '?') /* Continuation stab. */
3028 tlen += strlen(str) - 1;
3029 spnext = symbol_next (spnext);
3030 str = S_GET_NAME (spnext);
3031 pnt = str + strlen(str) - 1;
3032 } while (*pnt == '?');
3033 tlen += strlen(str);
3034 parse_buffer = (char *) xmalloc (tlen + 1);
3035 strcpy(parse_buffer, S_GET_NAME (sp));
3036 pnt2 = parse_buffer + strlen(S_GET_NAME (sp)) - 1;
3040 spnext = symbol_next (spnext);
3041 str = S_GET_NAME (spnext);
3042 strcat (pnt2, S_GET_NAME (spnext));
3043 pnt2 += strlen(str) - 1;
3044 *str = '\0'; /* Erase this string */
3045 if (*pnt2 != '?') break;
3051 pnt = (char *) strchr (str, ':');
3052 if (pnt != (char *) NULL)
3056 pnt2 = (char *) strchr (pnt1, '=');
3057 if (pnt2 != (char *) NULL)
3058 incomplete += VMS_typedef_parse (pnt2);
3061 /* At this point the parse buffer should just
3062 contain name:nn. If it does not, then we
3063 are in real trouble. Anyway, this is always
3064 shorter than the original line. */
3065 strcpy (S_GET_NAME (sp), parse_buffer);
3066 free (parse_buffer);
3069 *pnt = ':'; /* put back colon to restore dbx_type */
3076 /* Make one last pass, if needed, and define whatever we can that is left */
3077 if(final_pass == 0 && incomplete == incom1)
3080 incom1 ++; /* Force one last pass through */
3082 } while ((incomplete != 0) && (incomplete != incom1));
3083 /* repeat until all refs resolved if possible */
3084 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
3085 if (incomplete != 0)
3087 as_tsktsk ("debugger output: Unable to resolve %d circular references.",
3092 while (fpnt != (struct forward_ref *) NULL)
3094 if (fpnt->resolved != 'Y')
3096 if (find_symbol (fpnt->dbx_type) !=
3097 (struct VMS_DBG_Symbol *) NULL)
3099 as_tsktsk ("debugger forward reference error, dbx type %d",
3104 sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type);
3105 pnt2 = (char *) strchr (&fixit[1], '=');
3106 VMS_typedef_parse (pnt2);
3113 Define_Local_Symbols (s1, s2)
3117 for (symbolP1 = symbol_next (s1); symbolP1 != s2; symbolP1 = symbol_next (symbolP1))
3119 if (symbolP1 == (symbolS *) NULL)
3121 if (S_GET_RAW_TYPE (symbolP1) == N_FUN)
3123 char * pnt=(char*) strchr (S_GET_NAME (symbolP1), ':') + 1;
3124 if (*pnt == 'F' || *pnt == 'f') break;
3127 * Deal with STAB symbols
3129 if (S_IS_DEBUG (symbolP1))
3132 * Dispatch on STAB type
3134 switch (S_GET_RAW_TYPE (symbolP1))
3138 VMS_local_stab_Parse (symbolP1);
3141 VMS_RSYM_Parse (symbolP1, Current_Routine, Text_Psect);
3149 /* This function crawls the symbol chain searching for local symbols that need
3150 * to be described to the debugger. When we enter a new scope with a "{", it
3151 * creates a new "block", which helps the debugger keep track of which scope
3152 * we are currently in.
3156 Define_Routine (symbolP, Level)
3166 for (symbolP1 = symbol_next (symbolP); symbolP1; symbolP1 = symbol_next (symbolP1))
3168 if (S_GET_RAW_TYPE (symbolP1) == N_FUN)
3170 char * pnt=(char*) strchr (S_GET_NAME (symbolP1), ':') + 1;
3171 if (*pnt == 'F' || *pnt == 'f') break;
3174 * Deal with STAB symbols
3176 if (S_IS_DEBUG (symbolP1))
3179 * Dispatch on STAB type
3181 switch (S_GET_RAW_TYPE (symbolP1))
3186 sprintf (str, "$%d", rcount++);
3187 VMS_TBT_Block_Begin (symbolP1, Text_Psect, str);
3189 Offset = S_GET_VALUE (symbolP1);
3190 Define_Local_Symbols (sstart, symbolP1);
3192 Define_Routine (symbolP1, Level + 1);
3194 VMS_TBT_Block_End (S_GET_VALUE (symbolP1) -
3203 /* we end up here if there were no brackets in this function. Define
3205 Define_Local_Symbols (sstart, (symbolS *) 0);
3211 VMS_DBG_Define_Routine (symbolP, Curr_Routine, Txt_Psect)
3213 symbolS *Curr_Routine;
3216 Current_Routine = Curr_Routine;
3217 Text_Psect = Txt_Psect;
3218 Define_Routine (symbolP, 0);
3223 #include <sys/types.h>
3225 static void get_VMS_time_on_unix PARAMS ((char *));
3227 /* Manufacture a VMS-like time string on a Unix based system. */
3229 get_VMS_time_on_unix (Now)
3236 pnt = ctime (&timeb);
3242 sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
3244 #endif /* not VMS */
3247 * Write the MHD (Module Header) records
3250 Write_VMS_MHD_Records ()
3252 register const char *cp;
3256 struct { unsigned short len, mbz; char *ptr; } Descriptor;
3258 char Module_Name[255+1];
3262 * We are writing a module header record
3264 Set_VMS_Object_File_Record (OBJ_S_C_HDR);
3266 * ***************************
3267 * *MAIN MODULE HEADER RECORD*
3268 * ***************************
3270 * Store record type and header type
3272 PUT_CHAR (OBJ_S_C_HDR);
3273 PUT_CHAR (MHD_S_C_MHD);
3275 * Structure level is 0
3277 PUT_CHAR (OBJ_S_C_STRLVL);
3279 * Maximum record size is size of the object record buffer
3281 PUT_SHORT (sizeof (Object_Record_Buffer));
3284 * FIXME: module name and version should be user
3285 * specifiable via `.ident' and/or `#pragma ident'.
3289 * Get module name (the FILENAME part of the object file)
3295 if ((*cp == ']') || (*cp == '>') ||
3296 (*cp == ':') || (*cp == '/'))
3302 *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
3306 * Limit it to 31 characters and store in the object record
3308 while (--cp1 >= Module_Name)
3311 if (strlen (Module_Name) > 31)
3313 if (flag_hash_long_names)
3314 as_tsktsk ("Module name truncated: %s\n", Module_Name);
3315 Module_Name[31] = 0;
3317 PUT_COUNTED_STRING (Module_Name);
3319 * Module Version is "V1.0"
3321 PUT_COUNTED_STRING ("V1.0");
3323 * Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm".
3326 get_VMS_time_on_unix (Now);
3328 Descriptor.len = sizeof Now - 1;
3329 Descriptor.mbz = 0; /* type & class unspecified */
3330 Descriptor.ptr = Now;
3331 (void) sys$asctim ((unsigned short *)0, &Descriptor, (long *)0, 0);
3333 for (i = 0; i < 17; i++)
3336 * Patch time is "never" (17 zeros)
3338 for (i = 0; i < 17; i++)
3343 Flush_VMS_Object_Record_Buffer ();
3345 * *************************
3346 * *LANGUAGE PROCESSOR NAME*
3347 * *************************
3349 * Store record type and header type
3351 PUT_CHAR (OBJ_S_C_HDR);
3352 PUT_CHAR (MHD_S_C_LNM);
3354 * Store language processor name and version
3355 * (not a counted string!)
3357 * This is normally supplied by the gcc driver for the command line
3358 * which invokes gas. If absent, we fall back to gas's version.
3360 cp = compiler_version_string;
3373 Flush_VMS_Object_Record_Buffer ();
3378 * Write the EOM (End Of Module) record
3381 Write_VMS_EOM_Record (Psect, Offset)
3386 * We are writing an end-of-module record
3387 * (this assumes that the entry point will always be in a psect
3388 * represented by a single byte, which is the case for code in
3391 Set_VMS_Object_File_Record (OBJ_S_C_EOM);
3395 PUT_CHAR (OBJ_S_C_EOM);
3397 * Store the error severity (0)
3401 * Store the entry point, if it exists
3406 * Store the entry point Psect
3410 * Store the entry point Psect offset
3417 Flush_VMS_Object_Record_Buffer ();
3421 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3427 register const unsigned char *p = (unsigned char *) ptr;
3428 register const unsigned char *end = p + strlen (ptr);
3429 register unsigned char c;
3430 register int hash = 0;
3435 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
3441 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3444 VMS_Case_Hack_Symbol (In, Out)
3445 register const char *In;
3452 const char *old_name;
3454 int destructor = 0; /*hack to allow for case sens in a destructor*/
3456 int Case_Hack_Bits = 0;
3458 static char Hex_Table[16] =
3459 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3462 * Kill any leading "_"
3464 if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0')))
3467 new_name = Out; /* save this for later*/
3469 #if barfoo /* Dead code */
3470 if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_'))
3474 /* We may need to truncate the symbol, save the hash for later*/
3475 result = (strlen (In) > 23) ? hash_string (In) : 0;
3477 * Is there a Psect Attribute to skip??
3479 if (HAS_PSECT_ATTRIBUTES (In))
3484 In += PSECT_ATTRIBUTES_STRING_LENGTH;
3487 if ((In[0] == '$') && (In[1] == '$'))
3497 /* if (strlen(In) > 31 && flag_hash_long_names)
3498 as_tsktsk("Symbol name truncated: %s\n", In); */
3500 * Do the case conversion
3502 i = 23; /* Maximum of 23 chars */
3503 while (*In && (--i >= 0))
3505 Case_Hack_Bits <<= 1;
3508 if ((destructor == 1) && (i == 21))
3510 switch (vms_name_mapping)
3515 Case_Hack_Bits |= 1;
3517 *Out++ = islower(*In) ? toupper(*In++) : *In++;
3520 case 3: *Out++ = *In++;
3526 *Out++ = isupper(*In) ? tolower(*In++) : *In++;
3532 * If we saw a dollar sign, we don't do case hacking
3534 if (flag_no_hash_mixed_case || Saw_Dollar)
3538 * If we have more than 23 characters and everything is lowercase
3539 * we can insert the full 31 characters
3544 * We have more than 23 characters
3545 * If we must add the case hack, then we have truncated the str
3549 if (Case_Hack_Bits == 0)
3552 * And so far they are all lower case:
3553 * Check up to 8 more characters
3554 * and ensure that they are lowercase
3556 for (i = 0; (In[i] != 0) && (i < 8); i++)
3557 if (isupper(In[i]) && !Saw_Dollar && !flag_no_hash_mixed_case)
3563 if ((i == 8) || (In[i] == 0))
3566 * They are: Copy up to 31 characters
3567 * to the output string
3570 while ((--i >= 0) && (*In))
3571 switch (vms_name_mapping){
3572 case 0: *Out++ = islower(*In) ?
3576 case 3: *Out++ = *In++;
3578 case 2: *Out++ = isupper(*In) ?
3587 * If there were any uppercase characters in the name we
3588 * take on the case hacking string
3591 /* Old behavior for regular GNU-C compiler */
3592 if (!flag_hash_long_names)
3594 if ((Case_Hack_Bits != 0) || (truncate == 1))
3599 for (i = 0; i < 6; i++)
3601 *Out++ = Hex_Table[Case_Hack_Bits & 0xf];
3602 Case_Hack_Bits >>= 4;
3608 Out = pnt; /*Cut back to 23 characters maximum */
3610 for (i = 0; i < 7; i++)
3612 init = result & 0x01f;
3613 *Out++ = (init < 10) ? ('0' + init) : ('A' + init - 10);
3614 result = result >> 5;
3622 if (truncate == 1 && flag_hash_long_names && flag_show_after_trunc)
3623 as_tsktsk ("Symbol %s replaced by %s\n", old_name, new_name);
3628 * Scan a symbol name for a psect attribute specification
3630 #define GLOBALSYMBOL_BIT 0x10000
3631 #define GLOBALVALUE_BIT 0x20000
3635 VMS_Modify_Psect_Attributes (Name, Attribute_Pointer)
3637 int *Attribute_Pointer;
3640 register const char *cp;
3648 {"PIC", GPS_S_M_PIC},
3649 {"LIB", GPS_S_M_LIB},
3650 {"OVR", GPS_S_M_OVR},
3651 {"REL", GPS_S_M_REL},
3652 {"GBL", GPS_S_M_GBL},
3653 {"SHR", GPS_S_M_SHR},
3654 {"EXE", GPS_S_M_EXE},
3656 {"WRT", GPS_S_M_WRT},
3657 {"VEC", GPS_S_M_VEC},
3658 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT},
3659 {"GLOBALVALUE", GLOBALVALUE_BIT},
3669 * Check for a PSECT attribute list
3671 if (!HAS_PSECT_ATTRIBUTES (Name))
3672 return; /* If not, return */
3674 * Skip the attribute list indicator
3676 Name += PSECT_ATTRIBUTES_STRING_LENGTH;
3678 * Process the attributes ("_" separated, "$" terminated)
3680 while (*Name != '$')
3683 * Assume not negating
3689 if ((Name[0] == 'N') && (Name[1] == 'O'))
3692 * We are negating (and skip the NO)
3698 * Find the token delimiter
3701 while (*cp && (*cp != '_') && (*cp != '$'))
3704 * Look for the token in the attribute list
3706 for (i = 0; Attributes[i].Name; i++)
3709 * If the strings match, set/clear the attr.
3711 if (strncmp (Name, Attributes[i].Name, cp - Name) == 0)
3717 *Attribute_Pointer &=
3718 ~Attributes[i].Value;
3720 *Attribute_Pointer |=
3721 Attributes[i].Value;
3729 * Now skip the attribute
3738 #define GBLSYM_REF 0
3739 #define GBLSYM_DEF 1
3740 #define GBLSYM_VAL 2
3741 #define GBLSYM_LCL 4 /* not GBL after all... */
3744 * Define a global symbol (or possibly a local one).
3747 VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags)
3756 * We are writing a GSD record
3758 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3760 * If the buffer is empty we must insert the GSD record type
3762 if (Object_Record_Offset == 0)
3763 PUT_CHAR (OBJ_S_C_GSD);
3765 * We are writing a Global (or local) symbol definition subrecord.
3767 PUT_CHAR ((Flags & GBLSYM_LCL) != 0 ? GSD_S_C_LSY :
3768 ((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW);
3770 * Data type is undefined
3774 * Switch on Definition/Reference
3776 if ((Flags & GBLSYM_DEF) == 0)
3781 PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ? GSY_S_M_REL : 0);
3782 if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
3783 PUT_SHORT (Current_Environment);
3789 *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
3791 PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ?
3792 GSY_S_M_DEF | GSY_S_M_REL : GSY_S_M_DEF);
3793 if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
3794 PUT_SHORT (Current_Environment);
3798 if ((Flags & GBLSYM_LCL) == 0 && (unsigned) Psect_Number <= 255)
3799 PUT_CHAR (Psect_Number);
3801 PUT_SHORT (Psect_Number);
3805 PUT_LONG (Psect_Offset);
3808 * Finally, the global symbol name
3810 VMS_Case_Hack_Symbol (Name, Local);
3811 PUT_COUNTED_STRING (Local);
3813 * Flush the buffer if it is more than 75% full
3815 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3816 Flush_VMS_Object_Record_Buffer ();
3820 * Define an environment to support local symbol references.
3821 * This is just to mollify the linker; we don't actually do
3822 * anything useful with it.
3825 VMS_Local_Environment_Setup (Env_Name)
3826 const char *Env_Name;
3828 /* We are writing a GSD record. */
3829 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3830 /* If the buffer is empty we must insert the GSD record type. */
3831 if (Object_Record_Offset == 0)
3832 PUT_CHAR (OBJ_S_C_GSD);
3833 /* We are writing an ENV subrecord. */
3834 PUT_CHAR (GSD_S_C_ENV);
3836 ++Current_Environment; /* index of environment being defined */
3838 /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
3839 PUT_SHORT (ENV_S_M_DEF);
3840 /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
3843 /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
3844 if (!Env_Name) Env_Name = "";
3845 PUT_COUNTED_STRING ((char *)Env_Name);
3847 /* Flush the buffer if it is more than 75% full. */
3848 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3849 Flush_VMS_Object_Record_Buffer ();
3857 VMS_Psect_Spec (Name, Size, Type, vsp)
3861 struct VMS_Symbol *vsp;
3864 int Psect_Attributes;
3867 * Generate the appropriate PSECT flags given the PSECT type
3869 if (strcmp (Type, "COMMON") == 0)
3872 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3874 Psect_Attributes = (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL |
3875 GPS_S_M_SHR | GPS_S_M_RD | GPS_S_M_WRT);
3877 else if (strcmp (Type, "CONST") == 0)
3880 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3882 Psect_Attributes = (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL |
3883 GPS_S_M_SHR | GPS_S_M_RD);
3885 else if (strcmp (Type, "DATA") == 0)
3888 * The Data psects are PIC,REL,RD,WRT
3891 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT);
3893 else if (strcmp (Type, "TEXT") == 0)
3896 * The Text psects are PIC,REL,SHR,EXE,RD
3899 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR |
3900 GPS_S_M_EXE | GPS_S_M_RD);
3905 * Error: Unknown psect type
3907 error ("Unknown VMS psect type");
3910 * Modify the psect attributes according to any attribute string
3912 if (vsp && S_GET_TYPE (vsp->Symbol) == N_ABS)
3913 Psect_Attributes |= GLOBALVALUE_BIT;
3914 else if (HAS_PSECT_ATTRIBUTES (Name))
3915 VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
3917 * Check for globalref/def/val.
3919 if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3922 * globalvalue symbols were generated before. This code
3923 * prevents unsightly psect buildup, and makes sure that
3924 * fixup references are emitted correctly.
3926 vsp->Psect_Index = -1; /* to catch errors */
3927 S_SET_TYPE (vsp->Symbol, N_UNDF); /* make refs work */
3928 return 1; /* decrement psect counter */
3931 if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0)
3933 switch (S_GET_RAW_TYPE (vsp->Symbol))
3935 case N_UNDF | N_EXT:
3936 VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3937 vsp->Psect_Offset, GBLSYM_REF);
3938 vsp->Psect_Index = -1;
3939 S_SET_TYPE (vsp->Symbol, N_UNDF);
3940 return 1; /* return and indicate no psect */
3941 case N_DATA | N_EXT:
3942 VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3943 vsp->Psect_Offset, GBLSYM_DEF);
3944 /* In this case we still generate the psect */
3947 as_fatal ("Globalsymbol attribute for symbol %s was unexpected.",
3953 Psect_Attributes &= 0xffff; /* clear out the globalref/def stuff */
3955 * We are writing a GSD record
3957 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3959 * If the buffer is empty we must insert the GSD record type
3961 if (Object_Record_Offset == 0)
3962 PUT_CHAR (OBJ_S_C_GSD);
3964 * We are writing a PSECT definition subrecord
3966 PUT_CHAR (GSD_S_C_PSC);
3968 * Psects are always LONGWORD aligned
3972 * Specify the psect attributes
3974 PUT_SHORT (Psect_Attributes);
3976 * Specify the allocation
3980 * Finally, the psect name
3982 VMS_Case_Hack_Symbol (Name, Local);
3983 PUT_COUNTED_STRING (Local);
3985 * Flush the buffer if it is more than 75% full
3987 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3988 Flush_VMS_Object_Record_Buffer ();
3994 * Given the pointer to a symbol we calculate how big the data at the
3995 * symbol is. We do this by looking for the next symbol (local or
3996 * global) which will indicate the start of another datum.
3999 VMS_Initialized_Data_Size (sp, End_Of_Data)
4000 register symbolS *sp;
4003 symbolS *sp1, *Next_Symbol;
4004 /* Cache values to avoid extra lookups. */
4005 valueT sp_val = S_GET_VALUE (sp), sp1_val, next_val = 0;
4008 * Find the next symbol
4009 * it delimits this datum
4012 for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
4015 * The data type must match
4017 if (S_GET_TYPE (sp1) != N_DATA)
4020 sp1_val = S_GET_VALUE (sp1);
4023 * The symbol must be AFTER this symbol
4025 if (sp1_val <= sp_val)
4028 * We ignore THIS symbol
4033 * If there is already a candidate selected for the
4034 * next symbol, see if we are a better candidate
4039 * We are a better candidate if we are "closer"
4042 if (sp1_val > next_val)
4046 * Make this the candidate
4052 * Calculate its size
4054 return Next_Symbol ? (next_val - sp_val) : (End_Of_Data - sp_val);
4058 * Check symbol names for the Psect hack with a globalvalue, and then
4059 * generate globalvalues for those that have it.
4062 VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment)
4067 register symbolS *sp;
4068 char *stripped_name, *Name;
4070 int Psect_Attributes;
4075 * Scan the symbol table for globalvalues, and emit def/ref when
4076 * required. These will be caught again later and converted to
4079 for (sp = symbol_rootP; sp; sp = sp->sy_next)
4081 typ = S_GET_RAW_TYPE (sp);
4082 abstyp = ((typ & ~N_EXT) == N_ABS);
4084 * See if this is something we want to look at.
4087 typ != (N_DATA | N_EXT) &&
4088 typ != (N_UNDF | N_EXT))
4091 * See if this has globalvalue specification.
4093 Name = S_GET_NAME (sp);
4098 Psect_Attributes = GLOBALVALUE_BIT;
4100 else if (HAS_PSECT_ATTRIBUTES (Name))
4102 stripped_name = (char *) xmalloc (strlen (Name) + 1);
4103 strcpy (stripped_name, Name);
4104 Psect_Attributes = 0;
4105 VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
4110 if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
4115 /* Local symbol references will want
4116 to have an environment defined. */
4117 if (Current_Environment < 0)
4118 VMS_Local_Environment_Setup (".N_ABS");
4119 VMS_Global_Symbol_Spec (Name, 0,
4121 GBLSYM_DEF|GBLSYM_VAL|GBLSYM_LCL);
4124 VMS_Global_Symbol_Spec (Name, 0,
4126 GBLSYM_DEF|GBLSYM_VAL);
4128 case N_UNDF | N_EXT:
4129 VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
4131 case N_DATA | N_EXT:
4132 Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
4134 error ("Invalid data type for globalvalue");
4135 globalvalue = md_chars_to_number (Data_Segment +
4136 S_GET_VALUE (sp) - text_siz , Size);
4137 /* Three times for good luck. The linker seems to get confused
4138 if there are fewer than three */
4139 VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
4140 VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
4141 GBLSYM_DEF|GBLSYM_VAL);
4142 VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
4143 GBLSYM_DEF|GBLSYM_VAL);
4146 as_warn ("Invalid globalvalue of %s", stripped_name);
4150 if (stripped_name) free (stripped_name); /* clean up */
4157 * Define a procedure entry pt/mask
4160 VMS_Procedure_Entry_Pt (Name, Psect_Number, Psect_Offset, Entry_Mask)
4169 * We are writing a GSD record
4171 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
4173 * If the buffer is empty we must insert the GSD record type
4175 if (Object_Record_Offset == 0)
4176 PUT_CHAR (OBJ_S_C_GSD);
4178 * We are writing a Procedure Entry Pt/Mask subrecord
4180 PUT_CHAR (((unsigned) Psect_Number <= 255) ? GSD_S_C_EPM : GSD_S_C_EPMW);
4182 * Data type is undefined
4186 * Flags = "RELOCATABLE" and "DEFINED"
4188 PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
4192 if ((unsigned) Psect_Number <= 255)
4193 PUT_CHAR (Psect_Number);
4195 PUT_SHORT (Psect_Number);
4199 PUT_LONG (Psect_Offset);
4203 PUT_SHORT (Entry_Mask);
4205 * Finally, the global symbol name
4207 VMS_Case_Hack_Symbol (Name, Local);
4208 PUT_COUNTED_STRING (Local);
4210 * Flush the buffer if it is more than 75% full
4212 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4213 Flush_VMS_Object_Record_Buffer ();
4218 * Set the current location counter to a particular Psect and Offset
4221 VMS_Set_Psect (Psect_Index, Offset, Record_Type)
4227 * We are writing a "Record_Type" record
4229 Set_VMS_Object_File_Record (Record_Type);
4231 * If the buffer is empty we must insert the record type
4233 if (Object_Record_Offset == 0)
4234 PUT_CHAR (Record_Type);
4236 * Stack the Psect base + Offset
4238 vms_tir_stack_psect (Psect_Index, Offset, 0);
4240 * Set relocation base
4242 PUT_CHAR (TIR_S_C_CTL_SETRB);
4244 * Flush the buffer if it is more than 75% full
4246 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4247 Flush_VMS_Object_Record_Buffer ();
4252 * Store repeated immediate data in current Psect
4255 VMS_Store_Repeated_Data (Repeat_Count, Pointer, Size, Record_Type)
4257 register char *Pointer;
4263 * Ignore zero bytes/words/longwords
4268 if (Pointer[3] != 0 || Pointer[2] != 0) break;
4271 if (Pointer[1] != 0) break;
4274 if (Pointer[0] != 0) break;
4281 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4282 * then we do it manually
4286 while (--Repeat_Count >= 0)
4287 VMS_Store_Immediate_Data (Pointer, Size, Record_Type);
4291 * We are writing a "Record_Type" record
4293 Set_VMS_Object_File_Record (Record_Type);
4295 * If the buffer is empty we must insert record type
4297 if (Object_Record_Offset == 0)
4298 PUT_CHAR (Record_Type);
4300 * Stack the repeat count
4302 PUT_CHAR (TIR_S_C_STA_LW);
4303 PUT_LONG (Repeat_Count);
4305 * And now the command and its data
4307 PUT_CHAR (TIR_S_C_STO_RIVB);
4310 PUT_CHAR (*Pointer++);
4312 * Flush the buffer if it is more than 75% full
4314 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4315 Flush_VMS_Object_Record_Buffer ();
4320 * Store a Position Independent Reference
4323 VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative,
4324 Psect, Psect_Offset, Record_Type)
4332 register struct VMS_Symbol *vsp = Symbol->sy_obj;
4337 * We are writing a "Record_Type" record
4339 Set_VMS_Object_File_Record (Record_Type);
4341 * If the buffer is empty we must insert record type
4343 if (Object_Record_Offset == 0)
4344 PUT_CHAR (Record_Type);
4346 * Set to the appropriate offset in the Psect.
4347 * For a Code reference we need to fix the operand
4348 * specifier as well, so back up 1 byte;
4349 * for a Data reference we just store HERE.
4351 VMS_Set_Psect (Psect,
4352 PC_Relative ? Psect_Offset - 1 : Psect_Offset,
4355 * Make sure we are still generating a "Record Type" record
4357 if (Object_Record_Offset == 0)
4358 PUT_CHAR (Record_Type);
4360 * Dispatch on symbol type (so we can stack its value)
4362 switch (S_GET_RAW_TYPE (Symbol))
4371 #ifdef NOT_VAX_11_C_COMPATIBLE
4372 case N_UNDF | N_EXT:
4373 case N_DATA | N_EXT:
4374 #endif /* NOT_VAX_11_C_COMPATIBLE */
4376 case N_TEXT | N_EXT:
4378 * Get the symbol name (case hacked)
4380 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local);
4382 * Stack the global symbol value
4386 PUT_CHAR (TIR_S_C_STA_GBL);
4390 /* Local symbols have an extra field. */
4391 PUT_CHAR (TIR_S_C_STA_LSY);
4392 PUT_SHORT (Current_Environment);
4394 PUT_COUNTED_STRING (Local);
4398 * Stack the longword offset
4400 PUT_CHAR (TIR_S_C_STA_LW);
4403 * Add the two, leaving the result on the stack
4405 PUT_CHAR (TIR_S_C_OPR_ADD);
4409 * Uninitialized local data
4413 * Stack the Psect (+offset)
4415 vms_tir_stack_psect (vsp->Psect_Index,
4416 vsp->Psect_Offset + Offset,
4424 * Stack the Psect (+offset)
4426 vms_tir_stack_psect (vsp->Psect_Index,
4427 S_GET_VALUE (Symbol) + Offset,
4431 * Initialized local or global data
4434 #ifndef NOT_VAX_11_C_COMPATIBLE
4435 case N_UNDF | N_EXT:
4436 case N_DATA | N_EXT:
4437 #endif /* NOT_VAX_11_C_COMPATIBLE */
4439 * Stack the Psect (+offset)
4441 vms_tir_stack_psect (vsp->Psect_Index,
4442 vsp->Psect_Offset + Offset,
4447 * Store either a code or data reference
4449 PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR);
4451 * Flush the buffer if it is more than 75% full
4453 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4454 Flush_VMS_Object_Record_Buffer ();
4459 * Check in the text area for an indirect pc-relative reference
4460 * and fix it up with addressing mode 0xff [PC indirect]
4462 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4463 * PIC CODE GENERATING FIXUP ROUTINE.
4466 VMS_Fix_Indirect_Reference (Text_Psect, Offset, fragP, text_frag_root)
4469 register fragS *fragP;
4470 fragS *text_frag_root;
4473 * The addressing mode byte is 1 byte before the address
4477 * Is it in THIS frag??
4479 if ((Offset < fragP->fr_address) ||
4480 (Offset >= (fragP->fr_address + fragP->fr_fix)))
4483 * We need to search for the fragment containing this
4486 for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
4488 if ((Offset >= fragP->fr_address) &&
4489 (Offset < (fragP->fr_address + fragP->fr_fix)))
4493 * If we couldn't find the frag, things are BAD!!
4496 error ("Couldn't find fixup fragment when checking for indirect reference");
4499 * Check for indirect PC relative addressing mode
4501 if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff)
4503 static char Address_Mode = (char) 0xff;
4506 * Yes: Store the indirect mode back into the image
4507 * to fix up the damage done by STO_PICR
4509 VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR);
4510 VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR);
4515 * If the procedure "main()" exists we have to add the instruction
4516 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4518 * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed
4519 * to `HACK_VAXCRTL_STARTUP' because Digital's compiler
4520 * named "DEC C" uses run-time library "DECC$SHR", but this
4521 * startup code is for "VAXCRTL", the library for Digital's
4522 * older "VAX C". Also, this extra code isn't needed for
4523 * supporting gcc because it already generates the VAXCRTL
4524 * startup call when compiling main(). The reference to
4525 * `flag_hash_long_names' looks very suspicious too;
4526 * probably an old-style command line option was inadvertently
4527 * overloaded here, then blindly converted into the new one.
4530 vms_check_for_main ()
4532 register symbolS *symbolP;
4533 #ifdef HACK_DEC_C_STARTUP /* JF */
4534 register struct frchain *frchainP;
4535 register fragS *fragP;
4536 register fragS **prev_fragPP;
4537 register struct fix *fixP;
4538 register fragS *New_Frag;
4540 #endif /* HACK_DEC_C_STARTUP */
4542 symbolP = (symbolS *) symbol_find ("_main");
4543 if (symbolP && !S_IS_DEBUG (symbolP) &&
4544 S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
4546 #ifdef HACK_DEC_C_STARTUP
4547 if (!flag_hash_long_names)
4551 * Remember the entry point symbol
4553 Entry_Point_Symbol = symbolP;
4554 #ifdef HACK_DEC_C_STARTUP
4559 * Scan all the fragment chains for the one with "_main"
4560 * (Actually we know the fragment from the symbol, but we need
4561 * the previous fragment so we can change its pointer)
4563 frchainP = frchain_root;
4567 * Scan all the fragments in this chain, remembering
4568 * the "previous fragment"
4570 prev_fragPP = &frchainP->frch_root;
4571 fragP = frchainP->frch_root;
4572 while (fragP && (fragP != frchainP->frch_last))
4575 * Is this the fragment?
4577 if (fragP == symbolP->sy_frag)
4580 * Yes: Modify the fragment by replacing
4581 * it with a new fragment.
4583 New_Frag = (fragS *)
4584 xmalloc (sizeof (*New_Frag) +
4589 * The fragments are the same except
4590 * that the "fixed" area is larger
4593 New_Frag->fr_fix += 6;
4595 * Copy the literal data opening a hole
4596 * 2 bytes after "_main" (i.e. just after
4597 * the entry mask). Into which we place
4598 * the JSB instruction.
4600 New_Frag->fr_literal[0] = fragP->fr_literal[0];
4601 New_Frag->fr_literal[1] = fragP->fr_literal[1];
4602 New_Frag->fr_literal[2] = 0x16; /* Jsb */
4603 New_Frag->fr_literal[3] = 0xef;
4604 New_Frag->fr_literal[4] = 0;
4605 New_Frag->fr_literal[5] = 0;
4606 New_Frag->fr_literal[6] = 0;
4607 New_Frag->fr_literal[7] = 0;
4608 for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++)
4609 New_Frag->fr_literal[i + 6] =
4610 fragP->fr_literal[i];
4612 * Now replace the old fragment with the
4613 * newly generated one.
4615 *prev_fragPP = New_Frag;
4617 * Remember the entry point symbol
4619 Entry_Point_Symbol = symbolP;
4621 * Scan the text area fixup structures
4622 * as offsets in the fragment may have
4625 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
4628 * Look for references to this
4631 if (fixP->fx_frag == fragP)
4634 * Change the fragment
4637 fixP->fx_frag = New_Frag;
4639 * If the offset is after
4640 * the entry mask we need
4641 * to account for the JSB
4642 * instruction we just
4645 if (fixP->fx_where >= 2)
4646 fixP->fx_where += 6;
4650 * Scan the symbols as offsets in the
4651 * fragment may have changed
4653 for (symbolP = symbol_rootP;
4655 symbolP = symbol_next (symbolP))
4658 * Look for references to this
4661 if (symbolP->sy_frag == fragP)
4664 * Change the fragment
4667 symbolP->sy_frag = New_Frag;
4669 * If the offset is after
4670 * the entry mask we need
4671 * to account for the JSB
4672 * instruction we just
4675 if (S_GET_VALUE (symbolP) >= 2)
4676 S_SET_VALUE (symbolP,
4677 S_GET_VALUE (symbolP) + 6);
4681 * Make a symbol reference to
4682 * "_c$main_args" so we can get
4683 * its address inserted into the
4686 symbolP = (symbolS *) xmalloc (sizeof (*symbolP));
4687 S_SET_NAME (symbolP, "_C$MAIN_ARGS");
4688 S_SET_TYPE (symbolP, N_UNDF);
4689 S_SET_OTHER (symbolP, 0);
4690 S_SET_DESC (symbolP, 0);
4691 S_SET_VALUE (symbolP, 0);
4692 symbolP->sy_name_offset = 0;
4693 symbolP->sy_number = 0;
4694 symbolP->sy_obj = 0;
4695 symbolP->sy_frag = New_Frag;
4696 symbolP->sy_resolved = 0;
4697 symbolP->sy_resolving = 0;
4698 /* this actually inserts at the beginning of the list */
4699 symbol_append (symbol_rootP, symbolP,
4700 &symbol_rootP, &symbol_lastP);
4702 symbol_rootP = symbolP;
4704 * Generate a text fixup structure
4705 * to get "_c$main_args" stored into the
4708 fixP = (struct fix *) xmalloc (sizeof (*fixP));
4709 fixP->fx_frag = New_Frag;
4711 fixP->fx_addsy = symbolP;
4713 fixP->fx_offset = 0;
4716 fixP->fx_next = text_fix_root;
4717 text_fix_root = fixP;
4719 * Now make sure we exit from the loop
4725 * Try the next fragment
4727 prev_fragPP = &fragP->fr_next;
4728 fragP = fragP->fr_next;
4731 * Try the next fragment chain
4734 frchainP = frchainP->frch_next;
4737 #endif /* HACK_DEC_C_STARTUP */
4742 #define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
4745 * Write a VAX/VMS object file (everything else has been done!)
4748 vms_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
4753 fragS *text_frag_root;
4754 fragS *data_frag_root;
4756 register fragS *fragP;
4757 register symbolS *symbolP;
4758 register symbolS *sp;
4759 register struct fix *fixP;
4760 register struct VMS_Symbol *vsp;
4761 char *Data_Segment = 0;
4762 int Local_Initialized_Data_Size = 0;
4764 int Psect_Number = 0; /* Psect Index Number */
4765 int Text_Psect = -1; /* Text Psect Index */
4766 int Data_Psect = -2; /* Data Psect Index JF: Was -1 */
4767 int Bss_Psect = -3; /* Bss Psect Index JF: Was -1 */
4770 * Create the VMS object file
4772 Create_VMS_Object_File ();
4774 * Write the module header records
4776 Write_VMS_MHD_Records ();
4779 * Store the Data segment:
4781 * Since this is REALLY hard to do any other way,
4782 * we actually manufacture the data segment and
4783 * the store the appropriate values out of it.
4784 * We need to generate this early, so that globalvalues
4785 * can be properly emitted.
4790 * Allocate the data segment
4792 Data_Segment = (char *) xmalloc (data_siz);
4794 * Run through the data fragments, filling in the segment
4796 for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
4798 register long int count;
4799 register char *fill_literal;
4800 register long int fill_size;
4803 i = fragP->fr_address - text_siz;
4805 memcpy (Data_Segment + i,
4810 fill_literal = fragP->fr_literal + fragP->fr_fix;
4811 if ((fill_size = fragP->fr_var) != 0)
4812 for (count = fragP->fr_offset; count; count--)
4814 memcpy (Data_Segment + i, fill_literal, fill_size);
4822 * Generate the VMS object file records
4823 * 1st GSD then TIR records
4826 /******* Global Symbol Dictionary *******/
4828 * Emit globalvalues now. We must do this before the text psect
4829 * is defined, or we will get linker warnings about multiply defined
4830 * symbols. All of the globalvalues "reference" psect 0, although
4831 * it really does not have anything to do with it.
4833 VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment);
4835 * Define the Text Psect
4837 Text_Psect = Psect_Number++;
4838 VMS_Psect_Spec ("$code", text_siz, "TEXT", 0);
4840 * Define the BSS Psect
4844 Bss_Psect = Psect_Number++;
4845 VMS_Psect_Spec ("$uninitialized_data", bss_siz, "DATA", 0);
4847 #ifndef gxx_bug_fixed
4849 * The g++ compiler does not write out external references to vtables
4850 * correctly. Check for this and holler if we see it happening.
4851 * If that compiler bug is ever fixed we can remove this.
4852 * (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
4854 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4855 if (S_GET_RAW_TYPE (sp) == N_UNDF && IS_GXX_VTABLE (sp))
4857 S_SET_TYPE (sp, N_UNDF | N_EXT);
4858 S_SET_OTHER (sp, 1);
4859 as_warn ("g++ wrote an extern reference to `%s' as a routine.\n%s",
4861 "I will fix it, but I hope that it was not really a routine.");
4863 #endif /* gxx_bug_fixed */
4865 * Now scan the symbols and emit the appropriate GSD records
4867 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4870 * Dispatch on symbol type
4872 switch (S_GET_RAW_TYPE (sp))
4875 * Global uninitialized data
4877 case N_UNDF | N_EXT:
4879 * Make a VMS data symbol entry
4881 vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
4883 vsp->Size = S_GET_VALUE (sp);
4884 vsp->Psect_Index = Psect_Number++;
4885 vsp->Psect_Offset = 0;
4886 vsp->Next = VMS_Symbols;
4890 * Make the psect for this data
4892 Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
4894 S_GET_OTHER (sp) ? "CONST" : "COMMON",
4899 /* See if this is an external vtable. We want to help the linker find
4900 these things in libraries, so we make a symbol reference. This
4901 is not compatible with VAX-C usage for variables, but since vtables are
4902 only used internally by g++, we can get away with this hack. */
4904 if (IS_GXX_VTABLE (sp))
4905 VMS_Global_Symbol_Spec (S_GET_NAME(sp),
4910 #ifdef NOT_VAX_11_C_COMPATIBLE
4912 * Place a global symbol at the
4913 * beginning of the Psect
4915 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4919 #endif /* NOT_VAX_11_C_COMPATIBLE */
4922 * Local uninitialized data
4926 * Make a VMS data symbol entry
4928 vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
4931 vsp->Psect_Index = Bss_Psect;
4932 vsp->Psect_Offset = S_GET_VALUE (sp) - bss_address_frag.fr_address;
4933 vsp->Next = VMS_Symbols;
4938 * Global initialized data
4940 case N_DATA | N_EXT:
4942 * Make a VMS data symbol entry
4944 vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
4946 vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
4947 vsp->Psect_Index = Psect_Number++;
4948 vsp->Psect_Offset = 0;
4949 vsp->Next = VMS_Symbols;
4955 Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
4957 S_GET_OTHER (sp) ? "CONST" : "COMMON",
4962 /* See if this is an external vtable. We want to help the linker find
4963 these things in libraries, so we make a symbol definition. This
4964 is not compatible with VAX-C usage for variables, but since vtables are
4965 only used internally by g++, we can get away with this hack. */
4967 if (IS_GXX_VTABLE (sp))
4968 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4973 #ifdef NOT_VAX_11_C_COMPATIBLE
4975 * Place a global symbol at the
4976 * beginning of the Psect
4978 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4982 #endif /* NOT_VAX_11_C_COMPATIBLE */
4985 * Local initialized data
4989 char *sym_name = S_GET_NAME (sp);
4991 /* Always suppress local numeric labels. */
4992 if (!sym_name || strcmp (sym_name, FAKE_LABEL_NAME) != 0)
4995 * Make a VMS data symbol entry.
4997 vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
4999 vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
5000 vsp->Psect_Index = Data_Psect;
5001 vsp->Psect_Offset = Local_Initialized_Data_Size;
5002 Local_Initialized_Data_Size += vsp->Size;
5003 vsp->Next = VMS_Symbols;
5010 * Global Text definition
5012 case N_TEXT | N_EXT:
5014 unsigned short Entry_Mask;
5017 * Get the entry mask
5019 fragP = sp->sy_frag;
5020 /* First frag might be empty if we're generating listings.
5021 So skip empty rs_fill frags. */
5022 while (fragP && fragP->fr_type == rs_fill && fragP->fr_fix == 0)
5023 fragP = fragP->fr_next;
5025 /* If first frag doesn't contain the data, what do we do?
5026 If it's possibly smaller than two bytes, that would
5027 imply that the entry mask is not stored where we're
5030 If you can find a test case that triggers this, report
5031 it (and tell me what the entry mask field ought to be),
5032 and I'll try to fix it. KR */
5033 if (fragP->fr_fix < 2)
5036 Entry_Mask = (fragP->fr_literal[0] & 0x00ff) |
5037 ((fragP->fr_literal[1] & 0x00ff) << 8);
5039 * Define the procedure entry point.
5041 VMS_Procedure_Entry_Pt (S_GET_NAME (sp),
5048 * Local Text definition
5052 * Make a VMS data symbol entry
5054 if (Text_Psect != -1)
5056 vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
5059 vsp->Psect_Index = Text_Psect;
5060 vsp->Psect_Offset = S_GET_VALUE (sp);
5061 vsp->Next = VMS_Symbols;
5071 * Make a GSD global symbol reference
5074 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
5085 * gcc doesn't generate these;
5086 * VMS_Emit_Globalvalue handles them though.
5088 vsp = (struct VMS_Symbol *) xmalloc (sizeof (*vsp));
5090 vsp->Size = 4; /* always assume 32 bits */
5091 vsp->Psect_Index = 0;
5092 vsp->Psect_Offset = S_GET_VALUE (sp);
5093 vsp->Next = VMS_Symbols;
5102 * Ignore STAB symbols, including .stabs emitted by g++.
5104 if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22))
5109 as_tsktsk ("unhandled stab type %d", S_GET_TYPE (sp));
5114 * Define the Data Psect
5116 if ((data_siz > 0) && (Local_Initialized_Data_Size > 0))
5121 Data_Psect = Psect_Number++;
5122 VMS_Psect_Spec ("$data",
5123 Local_Initialized_Data_Size,
5126 * Scan the VMS symbols and fill in the data psect
5128 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
5131 * Only look for undefined psects
5133 if (vsp->Psect_Index < 0)
5136 * And only initialized data
5138 if (S_GET_TYPE (vsp->Symbol) == N_DATA
5139 && !S_IS_EXTERNAL (vsp->Symbol))
5140 vsp->Psect_Index = Data_Psect;
5145 /******* Text Information and Relocation Records *******/
5147 * Write the text segment data
5152 * Scan the text fragments
5154 for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
5157 * Stop if we get to the data fragments
5159 if (fragP == data_frag_root)
5162 * Ignore fragments with no data
5164 if ((fragP->fr_fix == 0) && (fragP->fr_var == 0))
5167 * Go the the appropriate offset in the
5170 VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR);
5172 * Store the "fixed" part
5175 VMS_Store_Immediate_Data (fragP->fr_literal,
5179 * Store the "variable" part
5181 if (fragP->fr_var && fragP->fr_offset)
5182 VMS_Store_Repeated_Data (fragP->fr_offset,
5189 * Now we go through the text segment fixups and
5190 * generate TIR records to fix up addresses within
5193 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
5196 * We DO handle the case of "Symbol - Symbol" as
5197 * long as it is in the same segment.
5199 if (fixP->fx_subsy && fixP->fx_addsy)
5204 * They need to be in the same segment
5206 if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
5207 S_GET_RAW_TYPE (fixP->fx_addsy))
5208 error ("Fixup data addsy and subsy didn't have the same type");
5210 * And they need to be in one that we
5211 * can check the psect on
5213 if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
5214 (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
5215 error ("Fixup data addsy and subsy didn't have an appropriate type");
5217 * This had better not be PC relative!
5220 error ("Fixup data was erroneously \"pcrel\"");
5222 * Subtract their values to get the
5225 i = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
5227 * Now generate the fixup object records
5228 * Set the psect and store the data
5230 VMS_Set_Psect (Text_Psect,
5231 fixP->fx_where + fixP->fx_frag->fr_address,
5233 VMS_Store_Immediate_Data (&i,
5242 * Size will HAVE to be "long"
5244 if (fixP->fx_size != 4)
5245 error ("Fixup datum was not a longword");
5247 * Symbol must be "added" (if it is ever
5249 * fix this assumption)
5251 if (fixP->fx_addsy == 0)
5252 error ("Fixup datum was not \"fixP->fx_addsy\"");
5254 * Store the symbol value in a PIC fashion
5256 VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
5261 fixP->fx_frag->fr_address,
5264 * Check for indirect address reference,
5265 * which has to be fixed up (as the linker
5266 * will screw it up with TIR_S_C_STO_PICR).
5269 VMS_Fix_Indirect_Reference (Text_Psect,
5271 fixP->fx_frag->fr_address,
5277 * Store the Data segment:
5279 * Since this is REALLY hard to do any other way,
5280 * we actually manufacture the data segment and
5281 * the store the appropriate values out of it.
5282 * The segment was manufactured before, now we just
5283 * dump it into the appropriate psects.
5289 * Now we can run through all the data symbols
5290 * and store the data
5292 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
5295 * Ignore anything other than data symbols
5297 if (S_GET_TYPE (vsp->Symbol) != N_DATA)
5300 * Set the Psect + Offset
5302 VMS_Set_Psect (vsp->Psect_Index,
5308 VMS_Store_Immediate_Data (
5309 Data_Segment + S_GET_VALUE (vsp->Symbol) - text_siz,
5314 * Now we go through the data segment fixups and
5315 * generate TIR records to fix up addresses within
5318 for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
5321 * Find the symbol for the containing datum
5323 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
5326 * Only bother with Data symbols
5329 if (S_GET_TYPE (sp) != N_DATA)
5332 * Ignore symbol if After fixup
5334 if (S_GET_VALUE (sp) >
5336 fixP->fx_frag->fr_address))
5339 * See if the datum is here
5341 if ((S_GET_VALUE (sp) + vsp->Size) <=
5343 fixP->fx_frag->fr_address))
5346 * We DO handle the case of "Symbol - Symbol" as
5347 * long as it is in the same segment.
5349 if (fixP->fx_subsy && fixP->fx_addsy)
5354 * They need to be in the same segment
5356 if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
5357 S_GET_RAW_TYPE (fixP->fx_addsy))
5358 error ("Fixup data addsy and subsy didn't have the same type");
5360 * And they need to be in one that we
5361 * can check the psect on
5363 if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
5364 (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
5365 error ("Fixup data addsy and subsy didn't have an appropriate type");
5367 * This had better not be PC relative!
5370 error ("Fixup data was erroneously \"pcrel\"");
5372 * Subtract their values to get the
5375 i = S_GET_VALUE (fixP->fx_addsy) -
5376 S_GET_VALUE (fixP->fx_subsy);
5378 * Now generate the fixup object records
5379 * Set the psect and store the data
5381 VMS_Set_Psect (vsp->Psect_Index,
5382 fixP->fx_frag->fr_address +
5384 S_GET_VALUE (vsp->Symbol) +
5387 VMS_Store_Immediate_Data (&i,
5396 * Size will HAVE to be "long"
5398 if (fixP->fx_size != 4)
5399 error ("Fixup datum was not a longword");
5401 * Symbol must be "added" (if it is ever
5403 * fix this assumption)
5405 if (fixP->fx_addsy == 0)
5406 error ("Fixup datum was not \"fixP->fx_addsy\"");
5408 * Store the symbol value in a PIC fashion
5410 VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
5414 fixP->fx_frag->fr_address +
5416 S_GET_VALUE (vsp->Symbol) +
5429 * Write the Traceback Begin Module record
5431 VMS_TBT_Module_Begin ();
5433 * Scan the symbols and write out the routines
5434 * (this makes the assumption that symbols are in
5435 * order of ascending text segment offset)
5438 symbolS *Current_Routine = 0;
5439 int Current_Line_Number = 0;
5440 int Current_Offset = -1;
5441 struct input_file *Current_File = 0;
5443 /* Output debugging info for global variables and static variables that are not
5444 * specific to one routine. We also need to examine all stabs directives, to
5445 * find the definitions to all of the advanced data types, and this is done by
5446 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5447 * the object file, since there can be forward references in the stabs
5448 * directives. When through with parsing, the text of the stabs directive
5449 * is altered, with the definitions removed, so that later passes will see
5450 * directives as they would be written if the type were already defined.
5452 * We also look for files and include files, and make a list of them. We
5453 * examine the source file numbers to establish the actual lines that code was
5454 * generated from, and then generate offsets.
5457 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
5460 * Deal with STAB symbols
5462 if (S_IS_DEBUG (symbolP))
5465 * Dispatch on STAB type
5467 switch ((unsigned char) S_GET_RAW_TYPE (symbolP))
5470 if (S_GET_DESC (symbolP) > Current_File->max_line)
5471 Current_File->max_line = S_GET_DESC (symbolP);
5472 if (S_GET_DESC (symbolP) < Current_File->min_line)
5473 Current_File->min_line = S_GET_DESC (symbolP);
5476 Current_File = find_file (symbolP);
5477 Current_File->flag = 1;
5478 Current_File->min_line = 1;
5481 Current_File = find_file (symbolP);
5484 VMS_GSYM_Parse (symbolP, Text_Psect);
5487 VMS_LCSYM_Parse (symbolP, Text_Psect);
5489 case N_FUN: /* For static constant symbols */
5491 VMS_STSYM_Parse (symbolP, Text_Psect);
5497 /* Now we take a quick sweep through the files and assign offsets
5498 to each one. This will essentially be the starting line number to
5499 the debugger for each file. Output the info for the debugger to
5500 specify the files, and then tell it how many lines to use. */
5502 int File_Number = 0;
5503 int Debugger_Offset = 0;
5505 Current_File = file_root;
5506 for (Current_File = file_root; Current_File;
5507 Current_File = Current_File->next)
5509 if (Current_File == (struct input_file *) NULL)
5511 if (Current_File->max_line == 0)
5513 if ((strncmp (Current_File->name, "GNU_GXX_INCLUDE:", 16) == 0) &&
5516 if ((strncmp (Current_File->name, "GNU_CC_INCLUDE:", 15) == 0) &&
5519 /* show a few extra lines at the start of the region selected */
5520 if (Current_File->min_line > 2)
5521 Current_File->min_line -= 2;
5522 Current_File->offset = Debugger_Offset - Current_File->min_line + 1;
5523 Debugger_Offset += Current_File->max_line - Current_File->min_line + 1;
5524 if (Current_File->same_file_fpnt != (struct input_file *) NULL)
5525 Current_File->file_number = Current_File->same_file_fpnt->file_number;
5528 Current_File->file_number = ++File_Number;
5529 file_available = VMS_TBT_Source_File (Current_File->name,
5530 Current_File->file_number);
5531 if (!file_available)
5533 Current_File->file_number = 0;
5538 VMS_TBT_Source_Lines (Current_File->file_number,
5539 Current_File->min_line,
5540 Current_File->max_line - Current_File->min_line + 1);
5543 Current_File = (struct input_file *) NULL;
5545 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
5548 * Deal with text symbols
5550 if (!S_IS_DEBUG (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
5553 * Ignore symbols starting with "L",
5554 * as they are local symbols
5556 if (*S_GET_NAME (symbolP) == 'L')
5559 * If there is a routine start defined,
5562 if (Current_Routine)
5567 VMS_TBT_Routine_End (text_siz, Current_Routine);
5570 * Check for & skip dummy labels like "gcc_compiled.".
5571 * They're identified by the IN_DEFAULT_SECTION flag.
5573 if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 &&
5574 (S_GET_VALUE (symbolP) == 0))
5577 * Store the routine begin traceback info
5579 if (Text_Psect != -1)
5581 VMS_TBT_Routine_Begin (symbolP, Text_Psect);
5582 Current_Routine = symbolP;
5585 /* Output local symbols, i.e. all symbols that are associated with a specific
5586 * routine. We output them now so the debugger recognizes them as local to
5593 for (symbolP1 = Current_Routine; symbolP1; symbolP1 = symbol_next (symbolP1))
5595 if (!S_IS_DEBUG (symbolP1))
5597 if (S_GET_RAW_TYPE (symbolP1) != N_FUN)
5599 pnt = S_GET_NAME (symbolP);
5600 pnt1 = S_GET_NAME (symbolP1);
5603 while (*pnt++ == *pnt1++)
5606 if (*pnt1 != 'F' && *pnt1 != 'f') continue;
5607 if ((*(--pnt) == '\0') && (*(--pnt1) == ':'))
5610 if (symbolP1 != (symbolS *) NULL)
5611 VMS_DBG_Define_Routine (symbolP1, Current_Routine, Text_Psect);
5612 } /* local symbol block */
5619 * Deal with STAB symbols
5621 if (S_IS_DEBUG (symbolP))
5624 * Dispatch on STAB type
5626 switch ((unsigned char) S_GET_RAW_TYPE (symbolP))
5632 /* Offset the line into the correct portion
5634 if (Current_File->file_number == 0)
5636 /* Sometimes the same offset gets several source
5637 * lines assigned to it.
5638 * We should be selective about which lines
5639 * we allow, we should prefer lines that are
5640 * in the main source file when debugging
5641 * inline functions. */
5642 if ((Current_File->file_number != 1) &&
5643 S_GET_VALUE (symbolP) ==
5646 /* calculate actual debugger source line */
5647 S_GET_DESC (symbolP)
5648 += Current_File->offset;
5650 * If this is the 1st N_SLINE, setup
5651 * PC/Line correlation. Otherwise
5652 * do the delta PC/Line. If the offset
5653 * for the line number is not +ve we need
5654 * to do another PC/Line correlation
5657 if (Current_Offset == -1)
5659 VMS_TBT_Line_PC_Correlation (
5660 S_GET_DESC (symbolP),
5661 S_GET_VALUE (symbolP),
5667 if ((S_GET_DESC (symbolP) -
5668 Current_Line_Number) <= 0)
5671 * Line delta is not +ve, we
5672 * need to close the line and
5673 * start a new PC/Line
5676 VMS_TBT_Line_PC_Correlation (0,
5677 S_GET_VALUE (symbolP) -
5681 VMS_TBT_Line_PC_Correlation (
5682 S_GET_DESC (symbolP),
5683 S_GET_VALUE (symbolP),
5690 * Line delta is +ve, all is well
5692 VMS_TBT_Line_PC_Correlation (
5693 S_GET_DESC (symbolP) -
5694 Current_Line_Number,
5695 S_GET_VALUE (symbolP) -
5702 * Update the current line/PC
5704 Current_Line_Number = S_GET_DESC (symbolP);
5705 Current_Offset = S_GET_VALUE (symbolP);
5715 * Remember that we had a source file
5716 * and emit the source file debugger
5720 find_file (symbolP);
5722 /* We need to make sure that we are really in the actual source file when
5723 * we compute the maximum line number. Otherwise the debugger gets really
5727 find_file (symbolP);
5733 * If there is a routine start defined,
5734 * terminate it (and the line numbers)
5736 if (Current_Routine)
5739 * Terminate the line numbers
5741 VMS_TBT_Line_PC_Correlation (0,
5742 text_siz - S_GET_VALUE (Current_Routine),
5746 * Terminate the routine
5748 VMS_TBT_Routine_End (text_siz, Current_Routine);
5752 * Write the Traceback End Module TBT record
5754 VMS_TBT_Module_End ();
5757 * Write the End Of Module record
5759 if (Entry_Point_Symbol == 0)
5760 Write_VMS_EOM_Record (-1, 0);
5762 Write_VMS_EOM_Record (Text_Psect,
5763 S_GET_VALUE (Entry_Point_Symbol));
5767 * All done, close the object file
5769 Close_VMS_Object_File ();
5772 /* end of obj-vms.c */