1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
28 /* What we do if there is a goof. */
29 #define error as_fatal
31 #ifdef HO_VMS /* These are of no use if we are cross assembling. */
32 #include <fab.h> /* Define File Access Block */
33 #include <nam.h> /* Define NAM Block */
34 #include <xab.h> /* Define XAB - all different types*/
37 * Version string of the compiler that produced the code we are
38 * assembling. (And this assembler, if we do not have compiler info.)
40 char *compiler_version_string;
42 /* Flag that determines how we map names. This takes several values, and
43 * is set with the -h switch. A value of zero implies names should be
44 * upper case, and the presence of the -h switch inhibits the case hack.
45 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
46 * A value of 2 (set with -h2) implies names should be
47 * all lower case, with no case hack. A value of 3 (set with -h3) implies
48 * that case should be preserved. */
50 /* If the -+ switch is given, then the hash is appended to any name that is
51 * longer than 31 characters, irregardless of the setting of the -h switch.
54 char vms_name_mapping = 0;
57 extern char *strchr ();
59 static symbolS *Entry_Point_Symbol = 0; /* Pointer to "_main" */
62 * We augment the "gas" symbol structure with this
66 struct VMS_Symbol *Next;
67 struct symbol *Symbol;
72 struct VMS_Symbol *VMS_Symbols = 0;
74 /* We need this to keep track of the various input files, so that we can
75 * give the debugger the correct source line.
80 struct input_file *next;
81 struct input_file *same_file_fpnt;
91 static struct input_file *file_root = (struct input_file *) NULL;
94 static struct input_file *find_file PARAMS ((symbolS *));
97 * This enum is used to keep track of the various types of variables that
103 BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN
107 * This structure contains the information from the stabs directives, and the
108 * information is filled in by VMS_typedef_parse. Everything that is needed
109 * to generate the debugging record for a given symbol is present here.
110 * This could be done more efficiently, using nested struct/unions, but for now
111 * I am happy that it works.
113 struct VMS_DBG_Symbol
115 struct VMS_DBG_Symbol *next;
116 /* description of what this is */
117 enum advanced_type advanced;
118 /* this record is for this type */
120 /* For advanced types this is the type referred to. I.e., the type
121 a pointer points to, or the type of object that makes up an
124 /* Use this type when generating a variable def */
126 /* used for arrays - this will be present for all */
128 /* entries, but will be meaningless for non-arrays */
130 /* Size in bytes of the data type. For an array, this is the size
131 of one element in the array */
133 /* Number of the structure/union/enum - used for ref */
137 struct VMS_DBG_Symbol *VMS_Symbol_type_list;
140 * We need this structure to keep track of forward references to
141 * struct/union/enum that have not been defined yet. When they are ultimately
142 * defined, then we can go back and generate the TIR commands to make a back
148 struct forward_ref *next;
154 struct forward_ref *f_ref_root =
155 {(struct forward_ref *) NULL};
158 * This routine is used to compare the names of certain types to various
159 * fixed types that are known by the debugger.
161 #define type_check(x) !strcmp( symbol_name , x )
164 * This variable is used to keep track of the name of the symbol we are
165 * working on while we are parsing the stabs directives.
167 static char *symbol_name;
169 /* We use this counter to assign numbers to all of the structures, unions
170 * and enums that we define. When we actually declare a variable to the
171 * debugger, we can simply do it by number, rather than describing the
172 * whole thing each time.
175 static structure_count = 0;
177 /* This variable is used to indicate that we are making the last attempt to
178 parse the stabs, and that we should define as much as we can, and ignore
181 static int final_pass;
183 /* This variable is used to keep track of the current structure number
184 * for a given variable. If this is < 0, that means that the structure
185 * has not yet been defined to the debugger. This is still cool, since
186 * the VMS object language has ways of fixing things up after the fact,
187 * so we just make a note of this, and generate fixups at the end.
189 static int struct_number;
193 * Variable descriptors are used tell the debugger the data types of certain
194 * more complicated variables (basically anything involving a structure,
195 * union, enum, array or pointer). Some non-pointer variables of the
196 * basic types that the debugger knows about do not require a variable
199 * Since it is impossible to have a variable descriptor longer than 128
200 * bytes by virtue of the way that the VMS object language is set up,
201 * it makes not sense to make the arrays any longer than this, or worrying
202 * about dynamic sizing of the array.
204 * These are the arrays and counters that we use to build a variable
208 #define MAX_DEBUG_RECORD 128
209 static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
210 static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
211 static int Lpnt; /* index into Local */
212 static int Apoint; /* index into Asuffix */
213 static char overflow; /* flag to indicate we have written too much*/
214 static int total_len; /* used to calculate the total length of variable
215 descriptor plus array descriptor - used for len byte*/
217 /* Flag if we have told user about finding global constants in the text
219 static gave_compiler_message = 0;
221 /* A pointer to the current routine that we are working on. */
223 static symbolS *Current_Routine;
225 /* The psect number for $code a.k.a. the text section. */
227 static int Text_Psect;
231 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
233 static int VMS_Object_File_FD; /* File Descriptor for object file */
234 static char Object_Record_Buffer[512]; /* Buffer for object file records */
235 static int Object_Record_Offset;/* Offset to end of data */
236 static int Current_Object_Record_Type; /* Type of record in above */
239 * Macros for moving data around. Must work on big-endian systems.
241 #ifdef HO_VMS /* These are more efficient for VMS->VMS systems */
242 #define COPY_LONG(dest,val) {*(long *) dest = val; }
243 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
245 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
246 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
249 * Macros for placing data into the object record buffer
252 #define PUT_LONG(val) \
253 { md_number_to_chars(Object_Record_Buffer + \
254 Object_Record_Offset, val, 4); \
255 Object_Record_Offset += 4; }
257 #define PUT_SHORT(val) \
258 { md_number_to_chars(Object_Record_Buffer + \
259 Object_Record_Offset, val, 2); \
260 Object_Record_Offset += 2; }
262 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
264 #define PUT_COUNTED_STRING(cp) {\
265 register char *p = cp; \
266 PUT_CHAR(strlen(p)); \
267 while (*p) PUT_CHAR(*p++);}
270 * Macro for determining if a Name has psect attributes attached
273 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
274 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
276 #define HAS_PSECT_ATTRIBUTES(Name) \
277 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
278 PSECT_ATTRIBUTES_STRING, \
279 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
282 /* in: segT out: N_TYPE bits */
283 const short seg_N_TYPE[] =
289 N_UNDF, /* unknown */
291 N_UNDF, /* expression */
295 N_REGISTER, /* register */
298 const segT N_TYPE_seg[N_TYPE + 2] =
299 { /* N_TYPE == 0x1E = 32-2 */
300 SEG_UNKNOWN, /* N_UNDF == 0 */
302 SEG_ABSOLUTE, /* N_ABS == 2 */
304 SEG_TEXT, /* N_TEXT == 4 */
306 SEG_DATA, /* N_DATA == 6 */
308 SEG_BSS, /* N_BSS == 8 */
310 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
311 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
312 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
313 SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
318 /* The following code defines the special types of pseudo-ops that we
329 temp = get_absolute_expression ();
330 subseg_set (SEG_DATA, (subsegT) temp);
332 demand_empty_rest_of_line ();
335 const pseudo_typeS obj_pseudo_table[] =
337 {"const", s_const, 0},
339 }; /* obj_pseudo_table */
342 vms_resolve_symbol_redef (sym)
346 * If the new symbol is .comm AND it has a size of zero,
347 * we ignore it (i.e. the old symbol overrides it)
349 if ((SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)) &&
350 ((obstack_next_free (&frags) - frag_now->fr_literal) == 0))
352 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
357 * If the old symbol is .comm and it has a size of zero,
358 * we override it with the new symbol value.
360 if (S_IS_EXTERNAL(sym) && S_IS_DEFINED(sym)
361 && (S_GET_VALUE(sym) == 0))
363 as_warn ("compiler redefined zero-size common symbol `%s'",
365 sym->sy_frag = frag_now;
366 S_GET_OTHER(sym) = const_flag;
367 S_SET_VALUE(sym, obstack_next_free(& frags) - frag_now->fr_literal);
368 /* Keep N_EXT bit. */
369 sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE((int) now_seg);
378 obj_read_begin_hook ()
381 } /* obj_read_begin_hook() */
384 obj_crawl_symbol_chain (headers)
385 object_headers *headers;
389 int symbol_number = 0;
391 { /* crawl symbol table */
392 register int symbol_number = 0;
395 symbolPP = &symbol_rootP; /* -> last symbol chain link. */
396 while ((symbolP = *symbolPP) != NULL)
398 resolve_symbol_value (symbolP);
400 /* OK, here is how we decide which symbols go out into the
401 brave new symtab. Symbols that do are:
403 * symbols with no name (stabd's?)
404 * symbols with debug info in their N_TYPE
406 Symbols that don't are:
407 * symbols that are registers
408 * symbols with \1 as their 3rd character (numeric labels)
409 * "local labels" as defined by S_LOCAL_NAME(name)
410 if the -L switch was passed to gas.
412 All other symbols are output. We complain if a deleted
413 symbol was marked external. */
416 if (!S_IS_REGISTER (symbolP))
418 symbolP->sy_name_offset = 0;
419 symbolPP = &(symbol_next (symbolP));
423 if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
425 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP));
428 } /* if this symbol should be in the output */
429 } /* for each symbol */
431 H_SET_STRING_SIZE (headers, string_byte_count);
432 H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
433 } /* crawl symbol table */
435 } /* obj_crawl_symbol_chain() */
438 /****** VMS OBJECT FILE HACKING ROUTINES *******/
442 * Create the VMS object file
445 Create_VMS_Object_File ()
447 #if defined(eunice) || !defined(HO_VMS)
448 VMS_Object_File_FD = creat (out_file_name, 0777, "var");
450 VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var",
451 "mbc=16", "deq=64", "fop=tef", "shr=nil");
456 if (VMS_Object_File_FD < 0)
458 char Error_Line[256];
460 sprintf (Error_Line, "Couldn't create VMS object file \"%s\"",
465 * Initialize object file hacking variables
467 Object_Record_Offset = 0;
468 Current_Object_Record_Type = -1;
473 * Flush the object record buffer to the object file
476 Flush_VMS_Object_Record_Buffer ()
482 * If the buffer is empty, we are done
484 if (Object_Record_Offset == 0)
487 * Write the data to the file
489 #ifndef HO_VMS /* For cross-assembly purposes. */
490 md_number_to_chars((char *) &RecLen, Object_Record_Offset, 2);
491 i = write (VMS_Object_File_FD, &RecLen, 2);
492 #endif /* not HO_VMS */
493 i = write (VMS_Object_File_FD,
494 Object_Record_Buffer,
495 Object_Record_Offset);
496 if (i != Object_Record_Offset)
497 error ("I/O error writing VMS object file");
498 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
500 /* pad it if needed */
502 if (Object_Record_Offset & 1 != 0)
503 write (VMS_Object_File_FD, &zero, 1);
504 #endif /* not HO_VMS */
506 * The buffer is now empty
508 Object_Record_Offset = 0;
513 * Declare a particular type of object file record
516 Set_VMS_Object_File_Record (Type)
520 * If the type matches, we are done
522 if (Type == Current_Object_Record_Type)
525 * Otherwise: flush the buffer
527 Flush_VMS_Object_Record_Buffer ();
531 Current_Object_Record_Type = Type;
537 * Close the VMS Object file
540 Close_VMS_Object_File ()
542 short int m_one = -1;
543 #ifndef HO_VMS /* For cross-assembly purposes. */
544 /* Write a 0xffff into the file, which means "End of File" */
545 write (VMS_Object_File_FD, &m_one, 2);
546 #endif /* not HO_VMS */
547 close (VMS_Object_File_FD);
552 * Store immediate data in current Psect
555 VMS_Store_Immediate_Data (Pointer, Size, Record_Type)
563 * We are writing a "Record_Type" record
565 Set_VMS_Object_File_Record (Record_Type);
567 * We can only store 128 bytes at a time
572 * Store a maximum of 128 bytes
574 i = (Size > 128) ? 128 : Size;
577 * If we cannot accommodate this record, flush the
580 if ((Object_Record_Offset + i + 1) >=
581 sizeof (Object_Record_Buffer))
582 Flush_VMS_Object_Record_Buffer ();
584 * If the buffer is empty we must insert record type
586 if (Object_Record_Offset == 0)
587 PUT_CHAR (Record_Type);
591 PUT_CHAR (-i & 0xff);
596 PUT_CHAR (*Pointer++);
598 * Flush the buffer if it is more than 75% full
600 if (Object_Record_Offset >
601 (sizeof (Object_Record_Buffer) * 3 / 4))
602 Flush_VMS_Object_Record_Buffer ();
607 * Make a data reference
610 VMS_Set_Data (Psect_Index, Offset, Record_Type, Force)
617 * We are writing a "Record_Type" record
619 Set_VMS_Object_File_Record (Record_Type);
621 * If the buffer is empty we must insert the record type
623 if (Object_Record_Offset == 0)
624 PUT_CHAR (Record_Type);
626 * Stack the Psect base + Longword Offset
630 if (Psect_Index > 127)
632 PUT_CHAR (TIR_S_C_STA_WPL);
633 PUT_SHORT (Psect_Index);
638 PUT_CHAR (TIR_S_C_STA_PL);
639 PUT_CHAR (Psect_Index);
647 PUT_CHAR (TIR_S_C_STA_WPL);
648 PUT_SHORT (Psect_Index);
651 else if (Offset > 127)
653 PUT_CHAR (TIR_S_C_STA_WPW);
654 PUT_SHORT (Psect_Index);
659 PUT_CHAR (TIR_S_C_STA_WPB);
660 PUT_SHORT (Psect_Index);
665 * Set relocation base
667 PUT_CHAR (TIR_S_C_STO_PIDR);
669 * Flush the buffer if it is more than 75% full
671 if (Object_Record_Offset >
672 (sizeof (Object_Record_Buffer) * 3 / 4))
673 Flush_VMS_Object_Record_Buffer ();
677 * Make a debugger reference to a struct, union or enum.
680 VMS_Store_Struct (Struct_Index)
684 * We are writing a "OBJ_S_C_DBG" record
686 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
688 * If the buffer is empty we must insert the record type
690 if (Object_Record_Offset == 0)
691 PUT_CHAR (OBJ_S_C_DBG);
692 PUT_CHAR (TIR_S_C_STA_UW);
693 PUT_SHORT (Struct_Index);
694 PUT_CHAR (TIR_S_C_CTL_STKDL);
695 PUT_CHAR (TIR_S_C_STO_L);
697 * Flush the buffer if it is more than 75% full
699 if (Object_Record_Offset >
700 (sizeof (Object_Record_Buffer) * 3 / 4))
701 Flush_VMS_Object_Record_Buffer ();
705 * Make a debugger reference to partially define a struct, union or enum.
708 VMS_Def_Struct (Struct_Index)
712 * We are writing a "OBJ_S_C_DBG" record
714 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
716 * If the buffer is empty we must insert the record type
718 if (Object_Record_Offset == 0)
719 PUT_CHAR (OBJ_S_C_DBG);
720 PUT_CHAR (TIR_S_C_STA_UW);
721 PUT_SHORT (Struct_Index);
722 PUT_CHAR (TIR_S_C_CTL_DFLOC);
724 * Flush the buffer if it is more than 75% full
726 if (Object_Record_Offset >
727 (sizeof (Object_Record_Buffer) * 3 / 4))
728 Flush_VMS_Object_Record_Buffer ();
732 VMS_Set_Struct (Struct_Index)
734 { /* see previous functions for comments */
735 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
736 if (Object_Record_Offset == 0)
737 PUT_CHAR (OBJ_S_C_DBG);
738 PUT_CHAR (TIR_S_C_STA_UW);
739 PUT_SHORT (Struct_Index);
740 PUT_CHAR (TIR_S_C_CTL_STLOC);
741 if (Object_Record_Offset >
742 (sizeof (Object_Record_Buffer) * 3 / 4))
743 Flush_VMS_Object_Record_Buffer ();
747 * Write the Traceback Module Begin record
750 VMS_TBT_Module_Begin ()
752 register char *cp, *cp1;
754 char Module_Name[256];
758 * Get module name (the FILENAME part of the object file)
764 if ((*cp == ']') || (*cp == '>') ||
765 (*cp == ':') || (*cp == '/'))
771 *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
775 * Limit it to 31 characters
777 while (--cp1 >= Module_Name)
780 if (strlen (Module_Name) > 31)
783 printf ("%s: Module name truncated: %s\n", myname, Module_Name);
787 * Arrange to store the data locally (leave room for size byte)
793 *cp++ = DST_S_C_MODBEG;
799 * Language type == "C"
801 COPY_LONG (cp, DST_S_C_C);
804 * Store the module name
806 *cp++ = strlen (Module_Name);
811 * Now we can store the record size
816 * Put it into the object record
818 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
823 * Write the Traceback Module End record
826 VMS_TBT_Module_End ()
834 Local[1] = DST_S_C_MODEND;
836 * Put it into the object record
838 VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT);
843 * Write the Traceback Routine Begin record
846 VMS_TBT_Routine_Begin (symbolP, Psect)
847 struct symbol *symbolP;
850 register char *cp, *cp1;
857 * Strip the leading "_" from the name
859 Name = S_GET_NAME (symbolP);
863 * Get the text psect offset
865 Offset = S_GET_VALUE (symbolP);
867 * Calculate the record size
869 Size = 1 + 1 + 4 + 1 + strlen (Name);
877 Local[1] = DST_S_C_RTNBEG;
883 * Store the data so far
885 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
887 * Make sure we are still generating a OBJ_S_C_TBT record
889 if (Object_Record_Offset == 0)
890 PUT_CHAR (OBJ_S_C_TBT);
892 * Now get the symbol address
894 PUT_CHAR (TIR_S_C_STA_WPL);
898 * Store the data reference
900 PUT_CHAR (TIR_S_C_STO_PIDR);
902 * Store the counted string as data
906 Size = strlen (cp1) + 1;
910 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
915 * Write the Traceback Routine End record
916 * We *must* search the symbol table to find the next routine, since
917 * the assember has a way of reassembling the symbol table OUT OF ORDER
918 * Thus the next routine in the symbol list is not necessarily the
919 * next one in memory. For debugging to work correctly we must know the
920 * size of the routine.
923 VMS_TBT_Routine_End (Max_Size, sp)
928 int Size = 0x7fffffff;
932 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
934 if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
936 if (*S_GET_NAME (symbolP) == 'L')
938 if ((S_GET_VALUE (symbolP) > S_GET_VALUE (sp)) &&
939 (S_GET_VALUE (symbolP) < Size))
940 Size = S_GET_VALUE (symbolP);
941 /* check if gcc_compiled. has size of zero */
942 if ((S_GET_VALUE (symbolP) == S_GET_VALUE (sp)) &&
944 (!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
945 !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
946 Size = S_GET_VALUE (symbolP);
950 if (Size == 0x7fffffff)
952 Size -= S_GET_VALUE (sp); /* and get the size of the routine */
960 Local[1] = DST_S_C_RTNEND;
968 COPY_LONG (&Local[3], Size);
972 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
976 * Write the Traceback Block End record
979 VMS_TBT_Block_Begin (symbolP, Psect, Name)
980 struct symbol *symbolP;
984 register char *cp, *cp1;
991 Size = 1 + 1 + 4 + 1 + strlen (Name);
997 * Begin Block - We simulate with a phony routine
999 Local[1] = DST_S_C_BLKBEG;
1005 * Store the data so far
1007 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG);
1009 * Make sure we are still generating a OBJ_S_C_DBG record
1011 if (Object_Record_Offset == 0)
1012 PUT_CHAR (OBJ_S_C_DBG);
1014 * Now get the symbol address
1016 PUT_CHAR (TIR_S_C_STA_WPL);
1019 * Get the text psect offset
1021 Offset = S_GET_VALUE (symbolP);
1024 * Store the data reference
1026 PUT_CHAR (TIR_S_C_STO_PIDR);
1028 * Store the counted string as data
1032 Size = strlen (cp1) + 1;
1036 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG);
1041 * Write the Traceback Block End record
1044 VMS_TBT_Block_End (Size)
1050 * End block - simulate with a phony end routine
1053 Local[1] = DST_S_C_BLKEND;
1054 COPY_LONG (&Local[3], Size);
1059 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG);
1065 * Write a Line number / PC correlation record
1068 VMS_TBT_Line_PC_Correlation (Line_Number, Offset, Psect, Do_Delta)
1078 * If not delta, set our PC/Line number correlation
1085 Local[0] = 1 + 1 + 2 + 1 + 4;
1087 * Line Number/PC correlation
1089 Local[1] = DST_S_C_LINE_NUM;
1093 Local[2] = DST_S_C_SET_LINE_NUM;
1094 COPY_SHORT (&Local[3], Line_Number - 1);
1098 Local[5] = DST_S_C_SET_ABS_PC;
1099 VMS_Store_Immediate_Data (Local, 6, OBJ_S_C_TBT);
1101 * Make sure we are still generating a OBJ_S_C_TBT record
1103 if (Object_Record_Offset == 0)
1104 PUT_CHAR (OBJ_S_C_TBT);
1107 PUT_CHAR (TIR_S_C_STA_PL);
1112 PUT_CHAR (TIR_S_C_STA_WPL);
1116 PUT_CHAR (TIR_S_C_STO_PIDR);
1118 * Do a PC offset of 0 to register the line number
1121 Local[1] = DST_S_C_LINE_NUM;
1122 Local[2] = 0; /* Increment PC by 0 and register line # */
1123 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
1128 * If Delta is negative, terminate the line numbers
1132 Local[0] = 1 + 1 + 4;
1133 Local[1] = DST_S_C_LINE_NUM;
1134 Local[2] = DST_S_C_TERM_L;
1135 COPY_LONG (&Local[3], Offset);
1136 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
1143 * Do a PC/Line delta
1146 *cp++ = DST_S_C_LINE_NUM;
1147 if (Line_Number > 1)
1150 * We need to increment the line number
1152 if (Line_Number - 1 <= 255)
1154 *cp++ = DST_S_C_INCR_LINUM;
1155 *cp++ = Line_Number - 1;
1159 *cp++ = DST_S_C_INCR_LINUM_W;
1160 COPY_SHORT (cp, Line_Number - 1);
1161 cp += sizeof (short);
1173 if (Offset < 0x10000)
1175 *cp++ = DST_S_C_DELTA_PC_W;
1176 COPY_SHORT (cp, Offset);
1177 cp += sizeof (short);
1181 *cp++ = DST_S_C_DELTA_PC_L;
1182 COPY_LONG (cp, Offset);
1183 cp += sizeof (long);
1186 Local[0] = cp - (Local + 1);
1187 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1193 * Describe a source file to the debugger
1196 VMS_TBT_Source_File (Filename, ID_Number)
1200 register char *cp, *cp1;
1203 #ifndef HO_VMS /* Used for cross-assembly */
1204 i = strlen (Filename);
1206 static struct FAB Fab;
1207 static struct NAM Nam;
1208 static struct XABDAT Date_Xab;
1209 static struct XABFHC File_Header_Xab;
1210 char Es_String[255], Rs_String[255];
1215 Fab.fab$b_bid = FAB$C_BID;
1216 Fab.fab$b_bln = sizeof (Fab);
1217 Fab.fab$l_nam = (&Nam);
1218 Fab.fab$l_xab = (char *) &Date_Xab;
1220 * Setup the Nam block so we can find out the FULL name
1221 * of the source file.
1223 Nam.nam$b_bid = NAM$C_BID;
1224 Nam.nam$b_bln = sizeof (Nam);
1225 Nam.nam$l_rsa = Rs_String;
1226 Nam.nam$b_rss = sizeof (Rs_String);
1227 Nam.nam$l_esa = Es_String;
1228 Nam.nam$b_ess = sizeof (Es_String);
1230 * Setup the Date and File Header Xabs
1232 Date_Xab.xab$b_cod = XAB$C_DAT;
1233 Date_Xab.xab$b_bln = sizeof (Date_Xab);
1234 Date_Xab.xab$l_nxt = (char *) &File_Header_Xab;
1235 File_Header_Xab.xab$b_cod = XAB$C_FHC;
1236 File_Header_Xab.xab$b_bln = sizeof (File_Header_Xab);
1238 * Get the file information
1240 Fab.fab$l_fna = Filename;
1241 Fab.fab$b_fns = strlen (Filename);
1242 Status = sys$open (&Fab);
1245 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1251 * Calculate the size of the resultant string
1258 Local[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i + 1;
1260 * Source declaration
1262 Local[1] = DST_S_C_SOURCE;
1264 * Make formfeeds count as source records
1266 Local[2] = DST_S_C_SRC_FORMFEED;
1268 * Declare source file
1270 Local[3] = DST_S_C_SRC_DECLFILE;
1271 Local[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i + 1;
1280 COPY_SHORT (cp, ID_Number);
1281 cp += sizeof (short);
1284 * Creation Date. Unknown, so we fill with zeroes.
1287 cp += sizeof (long);
1289 cp += sizeof (long);
1294 cp += sizeof (long);
1299 cp += sizeof (short);
1309 #else /* Use this code when assembling for VMS on a VMS system */
1313 *(long *) cp = ((long *) &Date_Xab.xab$q_cdt)[0];
1314 cp += sizeof (long);
1315 *(long *) cp = ((long *) &Date_Xab.xab$q_cdt)[1];
1316 cp += sizeof (long);
1320 *(long *) cp = File_Header_Xab.xab$l_ebk;
1321 cp += sizeof (long);
1325 *(short *) cp = File_Header_Xab.xab$w_ffb;
1326 cp += sizeof (short);
1330 *cp++ = File_Header_Xab.xab$b_rfo;
1340 * Library module name (none)
1346 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1352 * Give the number of source lines to the debugger
1355 VMS_TBT_Source_Lines (ID_Number, Starting_Line_Number, Number_Of_Lines)
1357 int Starting_Line_Number;
1358 int Number_Of_Lines;
1366 Local[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1368 * Source declaration
1370 Local[1] = DST_S_C_SOURCE;
1375 *cp++ = DST_S_C_SRC_SETFILE;
1379 COPY_SHORT (cp, ID_Number);
1380 cp += sizeof (short);
1384 *cp++ = DST_S_C_SRC_SETREC_L;
1385 COPY_LONG (cp, Starting_Line_Number);
1386 cp += sizeof (long);
1390 *cp++ = DST_S_C_SRC_DEFLINES_W;
1391 COPY_SHORT (cp, Number_Of_Lines);
1392 cp += sizeof (short);
1396 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1402 /* This routine locates a file in the list of files. If an entry does not
1403 * exist, one is created. For include files, a new entry is always created
1404 * such that inline functions can be properly debugged. */
1405 static struct input_file *
1409 struct input_file *same_file;
1410 struct input_file *fpnt;
1411 same_file = (struct input_file *) NULL;
1412 for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1414 if (fpnt == (struct input_file *) NULL)
1416 if (fpnt->spnt == sp)
1419 for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1421 if (fpnt == (struct input_file *) NULL)
1423 if (strcmp (S_GET_NAME (sp), fpnt->name) == 0)
1425 if (fpnt->flag == 1)
1431 fpnt = (struct input_file *) malloc (sizeof (struct input_file));
1432 if (file_root == (struct input_file *) NULL)
1436 struct input_file *fpnt1;
1437 for (fpnt1 = file_root; fpnt1->next; fpnt1 = fpnt1->next) ;
1440 fpnt->next = (struct input_file *) NULL;
1441 fpnt->name = S_GET_NAME (sp);
1442 fpnt->min_line = 0x7fffffff;
1446 fpnt->file_number = 0;
1448 fpnt->same_file_fpnt = same_file;
1453 * The following functions and definitions are used to generate object records
1454 * that will describe program variables to the VMS debugger.
1456 * This file contains many of the routines needed to output debugging info into
1457 * the object file that the VMS debugger needs to understand symbols. These
1458 * routines are called very late in the assembly process, and thus we can be
1459 * fairly lax about changing things, since the GSD and the TIR sections have
1460 * already been output.
1464 /* This routine converts a number string into an integer, and stops when it
1465 * sees an invalid character the return value is the address of the character
1466 * just past the last character read. No error is generated.
1469 cvt_integer (str, rtn)
1474 neg = *str == '-' ? ++str, -1 : 1;
1475 ival = 0; /* first get the number of the type for dbx */
1476 while ((*str <= '9') && (*str >= '0'))
1477 ival = 10 * ival + *str++ - '0';
1482 /* this routine fixes the names that are generated by C++, ".this" is a good
1483 * example. The period does not work for the debugger, since it looks like
1484 * the syntax for a structure element, and thus it gets mightily confused
1486 * We also use this to strip the PsectAttribute hack from the name before we
1487 * write a debugger record */
1495 * Kill any leading "_"
1500 * Is there a Psect Attribute to skip??
1502 if (HAS_PSECT_ATTRIBUTES (pnt))
1507 pnt += PSECT_ATTRIBUTES_STRING_LENGTH;
1510 if ((pnt[0] == '$') && (pnt[1] == '$'))
1518 /* Here we fix the .this -> $this conversion */
1519 for (pnt1 = pnt; *pnt1 != 0; pnt1++)
1527 /* When defining a structure, this routine is called to find the name of
1528 * the actual structure. It is assumed that str points to the equal sign
1529 * in the definition, and it moves backward until it finds the start of the
1530 * name. If it finds a 0, then it knows that this structure def is in the
1531 * outermost level, and thus symbol_name points to the symbol name.
1534 get_struct_name (str)
1539 while ((*pnt != ':') && (*pnt != '\0'))
1544 while ((*pnt != ';') && (*pnt != '='))
1548 while ((*pnt < '0') || (*pnt > '9'))
1550 while ((*pnt >= '0') && (*pnt <= '9'))
1555 /* search symbol list for type number dbx_type. Return a pointer to struct */
1556 static struct VMS_DBG_Symbol *
1557 find_symbol (dbx_type)
1560 struct VMS_DBG_Symbol *spnt;
1561 spnt = VMS_Symbol_type_list;
1562 while (spnt != (struct VMS_DBG_Symbol *) NULL)
1564 if (spnt->dbx_type == dbx_type)
1568 if (spnt == (struct VMS_DBG_Symbol *) NULL)
1569 return 0; /*Dunno what this is*/
1570 if(spnt->advanced == ALIAS)
1571 return find_symbol(spnt->type2);
1576 /* this routine puts info into either Local or Asuffix, depending on the sign
1577 * of size. The reason is that it is easier to build the variable descriptor
1578 * backwards, while the array descriptor is best built forwards. In the end
1579 * they get put together, if there is not a struct/union/enum along the way
1598 md_number_to_chars (&Local[Lpnt + 1], value, size1);
1602 if (Apoint + size1 >= MAX_DEBUG_RECORD)
1605 Apoint = MAX_DEBUG_RECORD - 1;
1608 md_number_to_chars (&Asuffix[Apoint], value, size1);
1613 /* this routine generates the array descriptor for a given array */
1615 array_suffix (spnt2)
1616 struct VMS_DBG_Symbol *spnt2;
1618 struct VMS_DBG_Symbol *spnt;
1619 struct VMS_DBG_Symbol *spnt1;
1625 while (spnt->advanced != ARRAY)
1627 spnt = find_symbol (spnt->type2);
1628 if (spnt == (struct VMS_DBG_Symbol *) NULL)
1634 while (spnt1->advanced == ARRAY)
1637 total_size *= (spnt1->index_max - spnt1->index_min + 1);
1638 spnt1 = find_symbol (spnt1->type2);
1640 total_size = total_size * spnt1->data_size;
1641 push (spnt1->data_size, 2);
1642 if (spnt1->VMS_type == 0xa3)
1645 push (spnt1->VMS_type, 1);
1647 for (i = 0; i < 6; i++)
1651 push (total_size, 4);
1654 while (spnt1->advanced == ARRAY)
1656 push (spnt1->index_max - spnt1->index_min + 1, 4);
1657 spnt1 = find_symbol (spnt1->type2);
1660 while (spnt1->advanced == ARRAY)
1662 push (spnt1->index_min, 4);
1663 push (spnt1->index_max, 4);
1664 spnt1 = find_symbol (spnt1->type2);
1668 /* this routine generates the start of a variable descriptor based upon
1669 * a struct/union/enum that has yet to be defined. We define this spot as
1670 * a new location, and save four bytes for the address. When the struct is
1671 * finally defined, then we can go back and plug in the correct address
1674 new_forward_ref (dbx_type)
1677 struct forward_ref *fpnt;
1678 fpnt = (struct forward_ref *) malloc (sizeof (struct forward_ref));
1679 fpnt->next = f_ref_root;
1681 fpnt->dbx_type = dbx_type;
1682 fpnt->struc_numb = ++structure_count;
1683 fpnt->resolved = 'N';
1686 push (total_len, -2);
1687 struct_number = -fpnt->struc_numb;
1690 /* this routine generates the variable descriptor used to describe non-basic
1691 * variables. It calls itself recursively until it gets to the bottom of it
1692 * all, and then builds the descriptor backwards. It is easiest to do it this
1693 *way since we must periodically write length bytes, and it is easiest if we know
1694 *the value when it is time to write it.
1697 gen1 (spnt, array_suffix_len)
1698 struct VMS_DBG_Symbol *spnt;
1699 int array_suffix_len;
1701 struct VMS_DBG_Symbol *spnt1;
1703 switch (spnt->advanced)
1706 push (DBG_S_C_VOID, -1);
1708 push (total_len, -2);
1712 if (array_suffix_len == 0)
1714 push (spnt->VMS_type, -1);
1715 push (DBG_S_C_BASIC, -1);
1717 push (total_len, -2);
1727 struct_number = spnt->struc_numb;
1728 if (struct_number < 0)
1730 new_forward_ref (spnt->dbx_type);
1733 push (DBG_S_C_STRUCT, -1);
1735 push (total_len, -2);
1738 spnt1 = find_symbol (spnt->type2);
1740 if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
1741 new_forward_ref (spnt->type2);
1743 i = gen1 (spnt1, 0);
1745 { /* (*void) is a special case, do not put pointer suffix*/
1746 push (DBG_S_C_POINTER, -1);
1748 push (total_len, -2);
1753 while (spnt1->advanced == ARRAY)
1755 spnt1 = find_symbol (spnt1->type2);
1756 if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
1758 printf ("gcc-as warning(debugger output):");
1759 printf ("Forward reference error, dbx type %d\n",
1764 /* It is too late to generate forward references, so the user gets a message.
1765 * This should only happen on a compiler error */
1766 i = gen1 (spnt1, 1);
1768 array_suffix (spnt);
1769 array_suffix_len = Apoint - i;
1770 switch (spnt1->advanced)
1778 push (total_len, -2);
1781 push (DBG_S_C_COMPLEX_ARRAY, -1);
1783 total_len += array_suffix_len + 8;
1784 push (total_len, -2);
1788 /* This generates a suffix for a variable. If it is not a defined type yet,
1789 * then dbx_type contains the type we are expecting so we can generate a
1790 * forward reference. This calls gen1 to build most of the descriptor, and
1791 * then it puts the icing on at the end. It then dumps whatever is needed
1792 * to get a complete descriptor (i.e. struct reference, array suffix ).
1795 generate_suffix (spnt, dbx_type)
1796 struct VMS_DBG_Symbol *spnt;
1801 static CONST char pvoid[6] = {5, 0xaf, 0, 1, 0, 5};
1802 struct VMS_DBG_Symbol *spnt1;
1804 Lpnt = MAX_DEBUG_RECORD - 1;
1808 if (spnt == (struct VMS_DBG_Symbol *) NULL)
1809 new_forward_ref (dbx_type);
1812 if (spnt->VMS_type != 0xa3)
1813 return 0; /* no suffix needed */
1818 push (total_len, -1);
1819 /* if the variable descriptor overflows the record, output a descriptor for
1820 * a pointer to void.
1822 if ((total_len >= MAX_DEBUG_RECORD) || overflow)
1824 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt->dbx_type);
1825 VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG);
1829 while (Lpnt < MAX_DEBUG_RECORD - 1)
1830 Local[i++] = Local[++Lpnt];
1832 /* we use this for a reference to a structure that has already been defined */
1833 if (struct_number > 0)
1835 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1837 VMS_Store_Struct (struct_number);
1839 /* we use this for a forward reference to a structure that has yet to be
1840 *defined. We store four bytes of zero to make room for the actual address once
1843 if (struct_number < 0)
1845 struct_number = -struct_number;
1846 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1848 VMS_Def_Struct (struct_number);
1849 for (i = 0; i < 4; i++)
1851 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1856 Local[Lpnt++] = Asuffix[i++];
1858 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1862 /* This routine generates a symbol definition for a C sybmol for the debugger.
1863 * It takes a psect and offset for global symbols - if psect < 0, then this is
1864 * a local variable and the offset is relative to FP. In this case it can
1865 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1868 VMS_DBG_record (spnt, Psect, Offset, Name)
1869 struct VMS_DBG_Symbol *spnt;
1879 Name_pnt = fix_name (Name); /* if there are bad characters in name, convert them */
1881 { /* this is a local variable, referenced to SP */
1882 maxlen = 7 + strlen (Name_pnt);
1883 Local[i++] = maxlen;
1884 Local[i++] = spnt->VMS_type;
1886 Local[i++] = DBG_S_C_FUNCTION_PARAMETER;
1888 Local[i++] = DBG_S_C_LOCAL_SYM;
1889 COPY_LONG (&Local[i], Offset);
1894 maxlen = 7 + strlen (Name_pnt); /* symbols fixed in memory */
1895 Local[i++] = 7 + strlen (Name_pnt);
1896 Local[i++] = spnt->VMS_type;
1898 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
1900 VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
1902 Local[i++] = strlen (Name_pnt);
1903 while (*Name_pnt != '\0')
1904 Local[i++] = *Name_pnt++;
1905 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
1906 if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
1907 generate_suffix (spnt, 0);
1911 /* This routine parses the stabs entries in order to make the definition
1912 * for the debugger of local symbols and function parameters
1915 VMS_local_stab_Parse (sp)
1921 struct VMS_DBG_Symbol *spnt;
1922 struct VMS_Symbol *vsp;
1926 str = S_GET_NAME (sp);
1927 pnt = (char *) strchr (str, ':');
1928 if (pnt == (char *) NULL)
1929 return; /* no colon present */
1930 pnt1 = pnt++; /* save this for later, and skip colon */
1932 return 0; /* ignore static constants */
1933 /* there is one little catch that we must be aware of. Sometimes function
1934 * parameters are optimized into registers, and the compiler, in its infiite
1935 * wisdom outputs stabs records for *both*. In general we want to use the
1936 * register if it is present, so we must search the rest of the symbols for
1937 * this function to see if this parameter is assigned to a register.
1945 for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1))
1947 if (!S_IS_DEBUG (sp1))
1949 if (S_GET_RAW_TYPE (sp1) == N_FUN)
1951 char * pnt3=(char*) strchr (S_GET_NAME (sp1), ':') + 1;
1952 if (*pnt3 == 'F' || *pnt3 == 'f') break;
1954 if (S_GET_RAW_TYPE (sp1) != N_RSYM)
1956 str1 = S_GET_NAME (sp1); /* and get the name */
1958 while (*pnt2 != ':')
1965 if ((*str1 != ':') || (*pnt2 != ':'))
1967 return; /* they are the same! lets skip this one */
1969 /* first find the dbx symbol type from list, and then find VMS type */
1970 pnt++; /* skip p in case no register */
1973 pnt = cvt_integer (pnt, &dbx_type);
1974 spnt = find_symbol (dbx_type);
1975 if (spnt == (struct VMS_DBG_Symbol *) NULL)
1976 return 0; /*Dunno what this is*/
1978 VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
1979 *pnt1 = ':'; /* and restore the string */
1983 /* This routine parses a stabs entry to find the information required to define
1984 * a variable. It is used for global and static variables.
1985 * Basically we need to know the address of the symbol. With older versions
1986 * of the compiler, const symbols are
1987 * treated differently, in that if they are global they are written into the
1988 * text psect. The global symbol entry for such a const is actually written
1989 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
1990 * of psects, we must search the entry points as well. static consts are even
1991 * harder, since they are never assigned a memory address. The compiler passes
1992 * a stab to tell us the value, but I am not sure what to do with it.
1996 VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect)
1999 int type1, type2, Text_Psect;
2005 struct VMS_DBG_Symbol *spnt;
2006 struct VMS_Symbol *vsp;
2010 str = S_GET_NAME (sp);
2011 pnt = (char *) strchr (str, ':');
2012 if (pnt == (char *) NULL)
2013 return; /* no colon present */
2014 pnt1 = pnt; /* save this for later*/
2016 if (*pnt == expected_type)
2018 pnt = cvt_integer (pnt + 1, &dbx_type);
2019 spnt = find_symbol (dbx_type);
2020 if (spnt == (struct VMS_DBG_Symbol *) NULL)
2021 return 0; /*Dunno what this is*/
2022 /* now we need to search the symbol table to find the psect and offset for
2027 while (vsp != (struct VMS_Symbol *) NULL)
2029 pnt = S_GET_NAME (vsp->Symbol);
2030 if (pnt != (char *) NULL)
2032 /* make sure name is the same, and make sure correct symbol type */
2033 if ((strlen (pnt) == strlen (str)) && (strcmp (pnt, str) == 0)
2034 && ((S_GET_RAW_TYPE (vsp->Symbol) == type1) ||
2035 (S_GET_RAW_TYPE (vsp->Symbol) == type2)))
2039 if (vsp != (struct VMS_Symbol *) NULL)
2041 VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str);
2042 *pnt1 = ':'; /* and restore the string */
2045 /* the symbol was not in the symbol list, but it may be an "entry point"
2046 if it was a constant */
2047 for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
2050 * Dispatch on STAB type
2052 if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT))
2054 pnt = S_GET_NAME (sp1);
2057 if (strcmp (pnt, str) == 0)
2059 if (!gave_compiler_message && expected_type == 'G')
2061 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2062 printf ("global constant(s) in the text psect. These will not be available to\n");
2063 printf ("other modules, since this is not the correct way to handle this. You\n");
2064 printf ("have two options: 1) get a patched compiler that does not put global\n");
2065 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2066 printf ("definitions of global variables in your source module(s). Don't say\n");
2067 printf ("I didn't warn you!");
2068 gave_compiler_message = 1;
2070 VMS_DBG_record (spnt,
2075 *S_GET_NAME (sp1) = 'L';
2076 /* fool assembler to not output this
2077 * as a routine in the TBT */
2082 *pnt1 = ':'; /* and restore the string */
2087 VMS_GSYM_Parse (sp, Text_Psect)
2090 { /* Global variables */
2091 VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect);
2096 VMS_LCSYM_Parse (sp, Text_Psect)
2099 { /* Static symbols - uninitialized */
2100 VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
2104 VMS_STSYM_Parse (sp, Text_Psect)
2107 { /* Static symbols - initialized */
2108 VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect);
2112 /* for register symbols, we must figure out what range of addresses within the
2113 * psect are valid. We will use the brackets in the stab directives to give us
2114 * guidance as to the PC range that this variable is in scope. I am still not
2115 * completely comfortable with this but as I learn more, I seem to get a better
2116 * handle on what is going on.
2120 VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
2121 symbolS *sp, *Current_Routine;
2128 struct VMS_DBG_Symbol *spnt;
2133 int Min_Offset = -1; /* min PC of validity */
2134 int Max_Offset = 0; /* max PC of validity */
2136 for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
2139 * Dispatch on STAB type
2141 switch (S_GET_RAW_TYPE (symbolP))
2145 Min_Offset = S_GET_VALUE (symbolP);
2150 S_GET_VALUE (symbolP) - 1;
2153 if ((Min_Offset != -1) && (bcnt == 0))
2155 if (S_GET_RAW_TYPE (symbolP) == N_FUN)
2157 pnt=(char*) strchr (S_GET_NAME (symbolP), ':') + 1;
2158 if (*pnt == 'F' || *pnt == 'f') break;
2161 /* check to see that the addresses were defined. If not, then there were no
2162 * brackets in the function, and we must try to search for the next function
2163 * Since functions can be in any order, we should search all of the symbol list
2164 * to find the correct ending address. */
2165 if (Min_Offset == -1)
2167 int Max_Source_Offset;
2169 Min_Offset = S_GET_VALUE (sp);
2170 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2173 * Dispatch on STAB type
2175 This_Offset = S_GET_VALUE (symbolP);
2176 switch (S_GET_RAW_TYPE (symbolP))
2178 case N_TEXT | N_EXT:
2179 if ((This_Offset > Min_Offset) && (This_Offset < Max_Offset))
2180 Max_Offset = This_Offset;
2183 if (This_Offset > Max_Source_Offset)
2184 Max_Source_Offset = This_Offset;
2187 /* if this is the last routine, then we use the PC of the last source line
2188 * as a marker of the max PC for which this reg is valid */
2189 if (Max_Offset == 0x7fffffff)
2190 Max_Offset = Max_Source_Offset;
2193 str = S_GET_NAME (sp);
2194 pnt = (char *) strchr (str, ':');
2195 if (pnt == (char *) NULL)
2196 return; /* no colon present */
2197 pnt1 = pnt; /* save this for later*/
2201 pnt = cvt_integer (pnt + 1, &dbx_type);
2202 spnt = find_symbol (dbx_type);
2203 if (spnt == (struct VMS_DBG_Symbol *) NULL)
2204 return 0; /*Dunno what this is yet*/
2206 pnt = fix_name (S_GET_NAME (sp)); /* if there are bad characters in name, convert them */
2207 maxlen = 25 + strlen (pnt);
2208 Local[i++] = maxlen;
2209 Local[i++] = spnt->VMS_type;
2211 Local[i++] = strlen (pnt) + 1;
2215 Local[i++] = strlen (pnt);
2216 while (*pnt != '\0')
2217 Local[i++] = *pnt++;
2223 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2225 VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
2226 VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
2228 Local[i++] = S_GET_VALUE (sp);
2232 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2234 if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
2235 generate_suffix (spnt, 0);
2238 /* this function examines a structure definition, checking all of the elements
2239 * to make sure that all of them are fully defined. The only thing that we
2240 * kick out are arrays of undefined structs, since we do not know how big
2241 * they are. All others we can handle with a normal forward reference.
2244 forward_reference (pnt)
2248 struct VMS_DBG_Symbol *spnt;
2249 struct VMS_DBG_Symbol *spnt1;
2250 pnt = cvt_integer (pnt + 1, &i);
2252 return 0; /* no forward references */
2255 pnt = (char *) strchr (pnt, ':');
2256 pnt = cvt_integer (pnt + 1, &i);
2257 spnt = find_symbol (i);
2258 if(spnt != (struct VMS_DBG_Symbol*) NULL) {
2259 while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY))
2262 spnt1 = find_symbol (spnt->type2);
2263 if ((spnt->advanced == ARRAY) &&
2264 (spnt1 == (struct VMS_DBG_Symbol *) NULL))
2266 if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
2271 pnt = cvt_integer (pnt + 1, &i);
2272 pnt = cvt_integer (pnt + 1, &i);
2273 } while (*++pnt != ';');
2274 return 0; /* no forward refences found */
2277 /* Used to check a single element of a structure on the final pass*/
2280 final_forward_reference (spnt)
2281 struct VMS_DBG_Symbol * spnt;
2283 struct VMS_DBG_Symbol * spnt1;
2284 if(spnt != (struct VMS_DBG_Symbol*) NULL) {
2285 while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY)){
2286 spnt1 = find_symbol(spnt->type2);
2287 if((spnt->advanced == ARRAY) &&
2288 (spnt1 == (struct VMS_DBG_Symbol*) NULL))return 1;
2289 if(spnt1 == (struct VMS_DBG_Symbol*) NULL) break;
2293 return 0; /* no forward refences found */
2296 /* This routine parses the stabs directives to find any definitions of dbx type
2297 * numbers. It makes a note of all of them, creating a structure element
2298 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2299 * debugger that describes the struct/union/enum, so that further references
2300 * to these data types will be by number
2301 * We have to process pointers right away, since there can be references
2302 * to them later in the same stabs directive. We cannot have forward
2303 * references to pointers, (but we can have a forward reference to a pointer to
2304 * a structure/enum/union) and this is why we process them immediately.
2305 * After we process the pointer, then we search for defs that are nested even
2307 * 8/15/92: We have to process arrays right away too, because there can
2308 * be multiple references to identical array types in one structure
2309 * definition, and only the first one has the definition. (We tend to
2310 * parse from the back going forward.
2313 VMS_typedef_parse (str)
2321 struct forward_ref *fpnt;
2323 int convert_integer;
2324 struct VMS_DBG_Symbol *spnt;
2325 struct VMS_DBG_Symbol *spnt1;
2326 /* check for any nested def's */
2327 pnt = (char *) strchr (str + 1, '=');
2328 if ((pnt != (char *) NULL) && (*(str + 1) != '*')
2329 && (str[1] != 'a' || str[2] != 'r'))
2330 if (VMS_typedef_parse (pnt) == 1)
2332 /* now find dbx_type of entry */
2335 { /* check for static constants */
2336 *str = '\0'; /* for now we ignore them */
2339 while ((*pnt <= '9') && (*pnt >= '0'))
2341 pnt++; /* and get back to the number */
2342 cvt_integer (pnt, &i1);
2343 spnt = find_symbol (i1);
2344 /* first we see if this has been defined already, due to a forward reference*/
2345 if (spnt == (struct VMS_DBG_Symbol *) NULL)
2347 if (VMS_Symbol_type_list == (struct VMS_DBG_Symbol *) NULL)
2349 spnt = (struct VMS_DBG_Symbol *) malloc (sizeof (struct VMS_DBG_Symbol));
2350 spnt->next = (struct VMS_DBG_Symbol *) NULL;
2351 VMS_Symbol_type_list = spnt;
2355 spnt = (struct VMS_DBG_Symbol *) malloc (sizeof (struct VMS_DBG_Symbol));
2356 spnt->next = VMS_Symbol_type_list;
2357 VMS_Symbol_type_list = spnt;
2359 spnt->dbx_type = i1; /* and save the type */
2361 /* for structs and unions, do a partial parse, otherwise we sometimes get
2362 * circular definitions that are impossible to resolve. We read enough info
2363 * so that any reference to this type has enough info to be resolved
2365 pnt = str + 1; /* point to character past equal sign */
2366 if ((*pnt == 'u') || (*pnt == 's'))
2369 if ((*pnt <= '9') && (*pnt >= '0'))
2371 if (type_check ("void"))
2372 { /* this is the void symbol */
2374 spnt->advanced = VOID;
2377 if (type_check ("unknown type"))
2378 { /* this is the void symbol */
2380 spnt->advanced = UNKNOWN;
2383 pnt1 = cvt_integer(pnt,&i1);
2384 if(i1 != spnt->dbx_type)
2386 spnt->advanced = ALIAS;
2391 printf ("gcc-as warning(debugger output):");
2392 printf (" %d is an unknown untyped variable.\n", spnt->dbx_type);
2393 return 1; /* do not know what this is */
2395 /* now define this module*/
2396 pnt = str + 1; /* point to character past equal sign */
2400 spnt->advanced = BASIC;
2401 if (type_check ("int"))
2403 spnt->VMS_type = DBG_S_C_SLINT;
2404 spnt->data_size = 4;
2406 else if (type_check ("long int"))
2408 spnt->VMS_type = DBG_S_C_SLINT;
2409 spnt->data_size = 4;
2411 else if (type_check ("unsigned int"))
2413 spnt->VMS_type = DBG_S_C_ULINT;
2414 spnt->data_size = 4;
2416 else if (type_check ("long unsigned int"))
2418 spnt->VMS_type = DBG_S_C_ULINT;
2419 spnt->data_size = 4;
2421 else if (type_check ("short int"))
2423 spnt->VMS_type = DBG_S_C_SSINT;
2424 spnt->data_size = 2;
2426 else if (type_check ("short unsigned int"))
2428 spnt->VMS_type = DBG_S_C_USINT;
2429 spnt->data_size = 2;
2431 else if (type_check ("char"))
2433 spnt->VMS_type = DBG_S_C_SCHAR;
2434 spnt->data_size = 1;
2436 else if (type_check ("signed char"))
2438 spnt->VMS_type = DBG_S_C_SCHAR;
2439 spnt->data_size = 1;
2441 else if (type_check ("unsigned char"))
2443 spnt->VMS_type = DBG_S_C_UCHAR;
2444 spnt->data_size = 1;
2446 else if (type_check ("float"))
2448 spnt->VMS_type = DBG_S_C_REAL4;
2449 spnt->data_size = 4;
2451 else if (type_check ("double"))
2453 spnt->VMS_type = DBG_S_C_REAL8;
2454 spnt->data_size = 8;
2456 pnt1 = (char *) strchr (str, ';') + 1;
2461 spnt->advanced = STRUCT;
2463 spnt->advanced = UNION;
2464 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2465 pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
2466 if (!final_pass && forward_reference(pnt))
2468 spnt->struc_numb = -1;
2471 spnt->struc_numb = ++structure_count;
2473 pnt = get_struct_name (str);
2474 VMS_Def_Struct (spnt->struc_numb);
2476 while (fpnt != (struct forward_ref *) NULL)
2478 if (fpnt->dbx_type == spnt->dbx_type)
2480 fpnt->resolved = 'Y';
2481 VMS_Set_Struct (fpnt->struc_numb);
2482 VMS_Store_Struct (spnt->struc_numb);
2486 VMS_Set_Struct (spnt->struc_numb);
2488 Local[i++] = 11 + strlen (pnt);
2489 Local[i++] = DBG_S_C_STRUCT_START;
2491 for (i1 = 0; i1 < 4; i1++)
2493 Local[i++] = strlen (pnt);
2495 while (*pnt2 != '\0')
2496 Local[i++] = *pnt2++;
2497 i2 = spnt->data_size * 8; /* number of bits */
2498 COPY_LONG(&Local[i], i2);
2500 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2502 if (pnt != symbol_name)
2504 pnt += strlen (pnt);
2506 }; /* replace colon for later */
2507 while (*++pnt1 != ';')
2509 pnt = (char *) strchr (pnt1, ':');
2512 pnt1 = cvt_integer (pnt + 1, &dtype);
2513 pnt1 = cvt_integer (pnt1 + 1, &i2);
2514 pnt1 = cvt_integer (pnt1 + 1, &i3);
2515 if ((dtype == 1) && (i3 != 32))
2518 push (19 + strlen (pnt2), 1);
2520 push (1 + strlen (pnt2), 4);
2521 push (strlen (pnt2), 1);
2522 while (*pnt2 != '\0')
2524 push (i3, 2); /* size of bitfield */
2527 push (i2, 4); /* start position */
2528 VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
2533 Local[i++] = 7 + strlen (pnt2);
2534 spnt1 = find_symbol (dtype);
2535 /* check if this is a forward reference */
2536 if(final_pass && final_forward_reference(spnt1))
2538 printf("gcc-as warning(debugger output):");
2539 printf("structure element %s has undefined type\n",pnt2);
2543 if (spnt1 != (struct VMS_DBG_Symbol *) NULL)
2544 Local[i++] = spnt1->VMS_type;
2546 Local[i++] = DBG_S_C_ADVANCED_TYPE;
2547 Local[i++] = DBG_S_C_STRUCT_ITEM;
2548 COPY_LONG (&Local[i], i2);
2550 Local[i++] = strlen (pnt2);
2551 while (*pnt2 != '\0')
2552 Local[i++] = *pnt2++;
2553 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2555 if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
2556 generate_suffix (spnt1, dtype);
2557 else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
2558 generate_suffix (spnt1, 0);
2562 Local[i++] = 0x01; /* length byte */
2563 Local[i++] = DBG_S_C_STRUCT_END;
2564 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2568 spnt->advanced = ENUM;
2569 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2570 spnt->struc_numb = ++structure_count;
2571 spnt->data_size = 4;
2572 VMS_Def_Struct (spnt->struc_numb);
2574 while (fpnt != (struct forward_ref *) NULL)
2576 if (fpnt->dbx_type == spnt->dbx_type)
2578 fpnt->resolved = 'Y';
2579 VMS_Set_Struct (fpnt->struc_numb);
2580 VMS_Store_Struct (spnt->struc_numb);
2584 VMS_Set_Struct (spnt->struc_numb);
2586 Local[i++] = 3 + strlen (symbol_name);
2587 Local[i++] = DBG_S_C_ENUM_START;
2589 Local[i++] = strlen (symbol_name);
2591 while (*pnt2 != '\0')
2592 Local[i++] = *pnt2++;
2593 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2595 while (*++pnt != ';')
2597 pnt1 = (char *) strchr (pnt, ':');
2599 pnt1 = cvt_integer (pnt1, &i1);
2600 Local[i++] = 7 + strlen (pnt);
2601 Local[i++] = DBG_S_C_ENUM_ITEM;
2603 COPY_LONG (&Local[i], i1);
2605 Local[i++] = strlen (pnt);
2607 while (*pnt != '\0')
2608 Local[i++] = *pnt++;
2609 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2611 pnt = pnt1; /* Skip final semicolon */
2613 Local[i++] = 0x01; /* len byte */
2614 Local[i++] = DBG_S_C_ENUM_END;
2615 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2620 spnt->advanced = ARRAY;
2621 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2622 pnt = (char *) strchr (pnt, ';');
2623 if (pnt == (char *) NULL)
2625 pnt1 = cvt_integer (pnt + 1, &spnt->index_min);
2626 pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max);
2627 pnt1 = cvt_integer (pnt1 + 1, &spnt->type2);
2628 pnt=(char*)strchr(str+1,'=');
2629 if((pnt != (char*) NULL))
2630 if(VMS_typedef_parse(pnt) == 1 ) return 1;
2633 spnt->advanced = FUNCTION;
2634 spnt->VMS_type = DBG_S_C_FUNCTION_ADDR;
2635 /* this masquerades as a basic type*/
2636 spnt->data_size = 4;
2637 pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2640 spnt->advanced = POINTER;
2641 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2642 spnt->data_size = 4;
2643 pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2644 pnt = (char *) strchr (str + 1, '=');
2645 if ((pnt != (char *) NULL))
2646 if (VMS_typedef_parse (pnt) == 1)
2650 spnt->advanced = UNKNOWN;
2652 printf ("gcc-as warning(debugger output):");
2653 printf (" %d is an unknown type of variable.\n", spnt->dbx_type);
2654 return 1; /* unable to decipher */
2656 /* this removes the evidence of the definition so that the outer levels of
2657 parsing do not have to worry about it */
2659 while (*pnt1 != '\0')
2667 * This is the root routine that parses the stabs entries for definitions.
2668 * it calls VMS_typedef_parse, which can in turn call itself.
2669 * We need to be careful, since sometimes there are forward references to
2670 * other symbol types, and these cannot be resolved until we have completed
2673 * Also check and see if we are using continuation stabs, if we are, then
2674 * paste together the entire contents of the stab before we pass it to
2675 * VMS_typedef_parse.
2684 char *parse_buffer = 0;
2686 int incomplete, i, pass, incom1;
2687 struct VMS_DBG_Symbol *spnt;
2688 struct VMS_Symbol *vsp;
2689 struct forward_ref *fpnt;
2696 incom1 = incomplete;
2698 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
2701 * Deal with STAB symbols
2703 if (S_IS_DEBUG (sp))
2706 * Dispatch on STAB type
2708 switch (S_GET_RAW_TYPE (sp))
2716 case N_FUN: /*sometimes these contain typedefs*/
2717 str = S_GET_NAME (sp);
2719 pnt = str + strlen(str) -1;
2720 if (*pnt == '?') /* Continuation stab. */
2726 tlen += strlen(str) - 1;
2727 spnext = symbol_next (spnext);
2728 str = S_GET_NAME (spnext);
2729 pnt = str + strlen(str) - 1;
2730 } while (*pnt == '?');
2731 tlen += strlen(str);
2732 parse_buffer = (char *) malloc (tlen + 1);
2733 strcpy(parse_buffer, S_GET_NAME (sp));
2734 pnt2 = parse_buffer + strlen(S_GET_NAME (sp)) - 1;
2738 spnext = symbol_next (spnext);
2739 str = S_GET_NAME (spnext);
2740 strcat (pnt2, S_GET_NAME (spnext));
2741 pnt2 += strlen(str) - 1;
2742 *str = '\0'; /* Erase this string */
2743 if (*pnt2 != '?') break;
2749 pnt = (char *) strchr (str, ':');
2750 if (pnt != (char *) NULL)
2754 pnt2 = (char *) strchr (pnt1, '=');
2755 if (pnt2 != (char *) NULL)
2756 incomplete += VMS_typedef_parse (pnt2);
2758 /* At this point the parse buffer should just contain name:nn.
2759 If it does not, then we are in real trouble. Anyway,
2760 this is always shorter than the original line. */
2761 strcpy(S_GET_NAME (sp), parse_buffer);
2762 free (parse_buffer);
2765 *pnt = ':'; /* put back colon so variable def code finds dbx_type*/
2772 /* Make one last pass, if needed, and define whatever we can that is left */
2773 if(final_pass == 0 && incomplete == incom1)
2776 incom1 ++; /* Force one last pass through */
2778 } while ((incomplete != 0) && (incomplete != incom1));
2779 /* repeat until all refs resolved if possible */
2780 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2781 if (incomplete != 0)
2783 printf ("gcc-as warning(debugger output):");
2784 printf ("Unable to resolve %d circular references.\n", incomplete);
2788 while (fpnt != (struct forward_ref *) NULL)
2790 if (fpnt->resolved != 'Y')
2792 if (find_symbol (fpnt->dbx_type) !=
2793 (struct VMS_DBG_Symbol *) NULL)
2795 printf ("gcc-as warning(debugger output):");
2796 printf ("Forward reference error, dbx type %d\n",
2801 sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type);
2802 pnt2 = (char *) strchr (&fixit[1], '=');
2803 VMS_typedef_parse (pnt2);
2810 Define_Local_Symbols (s1, s2)
2814 for (symbolP1 = symbol_next (s1); symbolP1 != s2; symbolP1 = symbol_next (symbolP1))
2816 if (symbolP1 == (symbolS *) NULL)
2818 if (S_GET_RAW_TYPE (symbolP1) == N_FUN)
2820 char * pnt=(char*) strchr (S_GET_NAME (symbolP1), ':') + 1;
2821 if (*pnt == 'F' || *pnt == 'f') break;
2824 * Deal with STAB symbols
2826 if (S_IS_DEBUG (symbolP1))
2829 * Dispatch on STAB type
2831 switch (S_GET_RAW_TYPE (symbolP1))
2835 VMS_local_stab_Parse (symbolP1);
2838 VMS_RSYM_Parse (symbolP1, Current_Routine, Text_Psect);
2846 /* This function crawls the symbol chain searching for local symbols that need
2847 * to be described to the debugger. When we enter a new scope with a "{", it
2848 * creates a new "block", which helps the debugger keep track of which scope
2849 * we are currently in.
2853 Define_Routine (symbolP, Level)
2863 for (symbolP1 = symbol_next (symbolP); symbolP1; symbolP1 = symbol_next (symbolP1))
2865 if (S_GET_RAW_TYPE (symbolP1) == N_FUN)
2867 char * pnt=(char*) strchr (S_GET_NAME (symbolP1), ':') + 1;
2868 if (*pnt == 'F' || *pnt == 'f') break;
2871 * Deal with STAB symbols
2873 if (S_IS_DEBUG (symbolP1))
2876 * Dispatch on STAB type
2878 switch (S_GET_RAW_TYPE (symbolP1))
2883 sprintf (str, "$%d", rcount++);
2884 VMS_TBT_Block_Begin (symbolP1, Text_Psect, str);
2886 Offset = S_GET_VALUE (symbolP1);
2887 Define_Local_Symbols (sstart, symbolP1);
2889 Define_Routine (symbolP1, Level + 1);
2891 VMS_TBT_Block_End (S_GET_VALUE (symbolP1) -
2900 /* we end up here if there were no brackets in this function. Define
2902 Define_Local_Symbols (sstart, (symbolS *) 0);
2908 VMS_DBG_Define_Routine (symbolP, Curr_Routine, Txt_Psect)
2910 symbolS *Curr_Routine;
2913 Current_Routine = Curr_Routine;
2914 Text_Psect = Txt_Psect;
2915 Define_Routine (symbolP, 0);
2922 #include <sys/types.h>
2925 /* Manufacure a VMS like time on a unix based system. */
2926 get_VMS_time_on_unix (Now)
2932 pnt = ctime (&timeb);
2938 sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
2941 #endif /* not HO_VMS */
2943 * Write the MHD (Module Header) records
2946 Write_VMS_MHD_Records ()
2948 register char *cp, *cp1;
2955 char Module_Name[256];
2959 * We are writing a module header record
2961 Set_VMS_Object_File_Record (OBJ_S_C_HDR);
2963 * ***************************
2964 * *MAIN MODULE HEADER RECORD*
2965 * ***************************
2967 * Store record type and header type
2969 PUT_CHAR (OBJ_S_C_HDR);
2970 PUT_CHAR (MHD_S_C_MHD);
2972 * Structure level is 0
2974 PUT_CHAR (OBJ_S_C_STRLVL);
2976 * Maximum record size is size of the object record buffer
2978 PUT_SHORT (sizeof (Object_Record_Buffer));
2980 * Get module name (the FILENAME part of the object file)
2986 if ((*cp == ']') || (*cp == '>') ||
2987 (*cp == ':') || (*cp == '/'))
2993 *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
2997 * Limit it to 31 characters and store in the object record
2999 while (--cp1 >= Module_Name)
3002 if (strlen (Module_Name) > 31)
3005 printf ("%s: Module name truncated: %s\n", myname, Module_Name);
3006 Module_Name[31] = 0;
3008 PUT_COUNTED_STRING (Module_Name);
3010 * Module Version is "V1.0"
3012 PUT_COUNTED_STRING ("V1.0");
3014 * Creation time is "now" (17 chars of time string)
3017 get_VMS_time_on_unix (&Now[0]);
3019 Descriptor.Size = 17;
3020 Descriptor.Ptr = Now;
3021 sys$asctim (0, &Descriptor, 0, 0);
3023 for (i = 0; i < 17; i++)
3026 * Patch time is "never" (17 zeros)
3028 for (i = 0; i < 17; i++)
3033 Flush_VMS_Object_Record_Buffer ();
3035 * *************************
3036 * *LANGUAGE PROCESSOR NAME*
3037 * *************************
3039 * Store record type and header type
3041 PUT_CHAR (OBJ_S_C_HDR);
3042 PUT_CHAR (MHD_S_C_LNM);
3044 * Store language processor name and version
3045 * (not a counted string!)
3047 cp = compiler_version_string;
3053 cp = strchr (GAS_VERSION, '.');
3063 Flush_VMS_Object_Record_Buffer ();
3068 * Write the EOM (End Of Module) record
3071 Write_VMS_EOM_Record (Psect, Offset)
3076 * We are writing an end-of-module record
3078 Set_VMS_Object_File_Record (OBJ_S_C_EOM);
3082 PUT_CHAR (OBJ_S_C_EOM);
3084 * Store the error severity (0)
3088 * Store the entry point, if it exists
3093 * Store the entry point Psect
3097 * Store the entry point Psect offset
3104 Flush_VMS_Object_Record_Buffer ();
3108 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3114 register unsigned char *p = ptr;
3115 register unsigned char *end = p + strlen (ptr);
3116 register unsigned char c;
3117 register int hash = 0;
3122 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
3128 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3131 VMS_Case_Hack_Symbol (In, Out)
3141 int destructor = 0; /*hack to allow for case sens in a destructor*/
3143 int Case_Hack_Bits = 0;
3145 static char Hex_Table[16] =
3146 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3149 * Kill any leading "_"
3151 if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0')))
3154 new_name = Out; /* save this for later*/
3156 #if barfoo /* Dead code */
3157 if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_'))
3161 /* We may need to truncate the symbol, save the hash for later*/
3162 if (strlen (In) > 23)
3163 result = hash_string (In);
3165 * Is there a Psect Attribute to skip??
3167 if (HAS_PSECT_ATTRIBUTES (In))
3172 In += PSECT_ATTRIBUTES_STRING_LENGTH;
3175 if ((In[0] == '$') && (In[1] == '$'))
3185 /* if (strlen(In) > 31 && flagseen['+'])
3186 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3188 * Do the case conversion
3190 i = 23; /* Maximum of 23 chars */
3191 while (*In && (--i >= 0))
3193 Case_Hack_Bits <<= 1;
3196 if ((destructor == 1) && (i == 21))
3198 switch (vms_name_mapping)
3203 Case_Hack_Bits |= 1;
3205 *Out++ = islower(*In) ? toupper(*In++) : *In++;
3208 case 3: *Out++ = *In++;
3214 *Out++ = isupper(*In) ? tolower(*In++) : *In++;
3220 * If we saw a dollar sign, we don't do case hacking
3222 if (flagseen['h'] || Saw_Dollar)
3226 * If we have more than 23 characters and everything is lowercase
3227 * we can insert the full 31 characters
3232 * We have more than 23 characters
3233 * If we must add the case hack, then we have truncated the str
3237 if (Case_Hack_Bits == 0)
3240 * And so far they are all lower case:
3241 * Check up to 8 more characters
3242 * and ensure that they are lowercase
3244 for (i = 0; (In[i] != 0) && (i < 8); i++)
3245 if (isupper(In[i]) && !Saw_Dollar && !flagseen['h'])
3251 if ((i == 8) || (In[i] == 0))
3254 * They are: Copy up to 31 characters
3255 * to the output string
3258 while ((--i >= 0) && (*In))
3259 switch (vms_name_mapping){
3260 case 0: *Out++ = islower(*In) ?
3264 case 3: *Out++ = *In++;
3266 case 2: *Out++ = isupper(*In) ?
3275 * If there were any uppercase characters in the name we
3276 * take on the case hacking string
3279 /* Old behavior for regular GNU-C compiler */
3282 if ((Case_Hack_Bits != 0) || (truncate == 1))
3287 for (i = 0; i < 6; i++)
3289 *Out++ = Hex_Table[Case_Hack_Bits & 0xf];
3290 Case_Hack_Bits >>= 4;
3296 Out = pnt; /*Cut back to 23 characters maximum */
3298 for (i = 0; i < 7; i++)
3300 init = result & 0x01f;
3302 *Out++ = '0' + init;
3304 *Out++ = 'A' + init - 10;
3305 result = result >> 5;
3313 if (truncate == 1 && flagseen['+'] && flagseen['H'])
3314 printf ("%s: Symbol %s replaced by %s\n", myname, old_name, new_name);
3319 * Scan a symbol name for a psect attribute specification
3321 #define GLOBALSYMBOL_BIT 0x10000
3322 #define GLOBALVALUE_BIT 0x20000
3326 VMS_Modify_Psect_Attributes (Name, Attribute_Pointer)
3328 int *Attribute_Pointer;
3339 {"PIC", GPS_S_M_PIC},
3340 {"LIB", GPS_S_M_LIB},
3341 {"OVR", GPS_S_M_OVR},
3342 {"REL", GPS_S_M_REL},
3343 {"GBL", GPS_S_M_GBL},
3344 {"SHR", GPS_S_M_SHR},
3345 {"EXE", GPS_S_M_EXE},
3347 {"WRT", GPS_S_M_WRT},
3348 {"VEC", GPS_S_M_VEC},
3349 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT},
3350 {"GLOBALVALUE", GLOBALVALUE_BIT},
3360 * Check for a PSECT attribute list
3362 if (!HAS_PSECT_ATTRIBUTES (Name))
3363 return; /* If not, return */
3365 * Skip the attribute list indicator
3367 Name += PSECT_ATTRIBUTES_STRING_LENGTH;
3369 * Process the attributes ("_" separated, "$" terminated)
3371 while (*Name != '$')
3374 * Assume not negating
3380 if ((Name[0] == 'N') && (Name[1] == 'O'))
3383 * We are negating (and skip the NO)
3389 * Find the token delimiter
3392 while (*cp && (*cp != '_') && (*cp != '$'))
3395 * Look for the token in the attribute list
3397 for (i = 0; Attributes[i].Name; i++)
3400 * If the strings match, set/clear the attr.
3402 if (strncmp (Name, Attributes[i].Name, cp - Name) == 0)
3408 *Attribute_Pointer &=
3409 ~Attributes[i].Value;
3411 *Attribute_Pointer |=
3412 Attributes[i].Value;
3420 * Now skip the attribute
3434 * Define a global symbol
3437 VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Defined)
3445 * We are writing a GSD record
3447 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3449 * If the buffer is empty we must insert the GSD record type
3451 if (Object_Record_Offset == 0)
3452 PUT_CHAR (OBJ_S_C_GSD);
3454 * We are writing a Global symbol definition subrecord
3456 if (Psect_Number <= 255)
3458 PUT_CHAR (GSD_S_C_SYM);
3462 PUT_CHAR (GSD_S_C_SYMW);
3465 * Data type is undefined
3469 * Switch on Definition/Reference
3471 if ((Defined & 1) != 0)
3475 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3476 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3478 if ((Defined & 2) == 0)
3480 PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
3484 PUT_SHORT (GSY_S_M_DEF);
3489 if (Psect_Number <= 255)
3491 PUT_CHAR (Psect_Number);
3495 PUT_SHORT (Psect_Number);
3500 PUT_LONG (Psect_Offset);
3506 * Flags = "RELOCATABLE" for regular symbol,
3507 * = "" for globalvalue (Defined & 2 == 1)
3509 if ((Defined & 2) == 0)
3511 PUT_SHORT (GSY_S_M_REL);
3519 * Finally, the global symbol name
3521 VMS_Case_Hack_Symbol (Name, Local);
3522 PUT_COUNTED_STRING (Local);
3524 * Flush the buffer if it is more than 75% full
3526 if (Object_Record_Offset >
3527 (sizeof (Object_Record_Buffer) * 3 / 4))
3528 Flush_VMS_Object_Record_Buffer ();
3536 VMS_Psect_Spec (Name, Size, Type, vsp)
3540 struct VMS_Symbol *vsp;
3543 int Psect_Attributes;
3546 * Generate the appropriate PSECT flags given the PSECT type
3548 if (strcmp (Type, "COMMON") == 0)
3551 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3553 Psect_Attributes = (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL |
3554 GPS_S_M_SHR | GPS_S_M_RD | GPS_S_M_WRT);
3556 else if (strcmp (Type, "CONST") == 0)
3559 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3561 Psect_Attributes = (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL |
3562 GPS_S_M_SHR | GPS_S_M_RD);
3564 else if (strcmp (Type, "DATA") == 0)
3567 * The Data psects are PIC,REL,RD,WRT
3570 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT);
3572 else if (strcmp (Type, "TEXT") == 0)
3575 * The Text psects are PIC,REL,SHR,EXE,RD
3578 (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR |
3579 GPS_S_M_EXE | GPS_S_M_RD);
3584 * Error: Unknown psect type
3586 error ("Unknown VMS psect type");
3589 * Modify the psect attributes according to any attribute string
3591 if (HAS_PSECT_ATTRIBUTES (Name))
3592 VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
3594 * Check for globalref/def/val.
3596 if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3599 * globalvalue symbols were generated before. This code
3600 * prevents unsightly psect buildup, and makes sure that
3601 * fixup references are emitted correctly.
3603 vsp->Psect_Index = -1; /* to catch errors */
3604 S_GET_RAW_TYPE (vsp->Symbol) = N_UNDF; /* make refs work */
3605 return 1; /* decrement psect counter */
3608 if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0)
3610 switch (S_GET_RAW_TYPE (vsp->Symbol))
3612 case N_UNDF | N_EXT:
3613 VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3614 vsp->Psect_Offset, 0);
3615 vsp->Psect_Index = -1;
3616 S_GET_RAW_TYPE (vsp->Symbol) = N_UNDF;
3617 return 1; /* return and indicate no psect */
3618 case N_DATA | N_EXT:
3619 VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3620 vsp->Psect_Offset, 1);
3621 /* In this case we still generate the psect */
3625 char Error_Line[256];
3626 sprintf (Error_Line,
3627 "Globalsymbol attribute for symbol %s was unexpected.\n",
3635 Psect_Attributes &= 0xffff; /* clear out the globalref/def stuff */
3637 * We are writing a GSD record
3639 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3641 * If the buffer is empty we must insert the GSD record type
3643 if (Object_Record_Offset == 0)
3644 PUT_CHAR (OBJ_S_C_GSD);
3646 * We are writing a PSECT definition subrecord
3648 PUT_CHAR (GSD_S_C_PSC);
3650 * Psects are always LONGWORD aligned
3654 * Specify the psect attributes
3656 PUT_SHORT (Psect_Attributes);
3658 * Specify the allocation
3662 * Finally, the psect name
3664 VMS_Case_Hack_Symbol (Name, Local);
3665 PUT_COUNTED_STRING (Local);
3667 * Flush the buffer if it is more than 75% full
3669 if (Object_Record_Offset >
3670 (sizeof (Object_Record_Buffer) * 3 / 4))
3671 Flush_VMS_Object_Record_Buffer ();
3677 * Given the pointer to a symbol we calculate how big the data at the
3678 * symbol is. We do this by looking for the next symbol (local or
3679 * global) which will indicate the start of another datum.
3682 VMS_Initialized_Data_Size (sp, End_Of_Data)
3683 register struct symbol *sp;
3686 register struct symbol *sp1, *Next_Symbol;
3689 * Find the next symbol
3690 * it delimits this datum
3693 for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
3696 * The data type must match
3698 if (S_GET_TYPE (sp1) != N_DATA)
3701 * The symbol must be AFTER this symbol
3703 if (S_GET_VALUE (sp1) <= S_GET_VALUE (sp))
3706 * We ignore THIS symbol
3711 * If there is already a candidate selected for the
3712 * next symbol, see if we are a better candidate
3717 * We are a better candidate if we are "closer"
3720 if (S_GET_VALUE (sp1) >
3721 S_GET_VALUE (Next_Symbol))
3724 * Win: Make this the candidate
3731 * This is the 1st candidate
3737 * Calculate its size
3739 return (Next_Symbol ?
3740 (S_GET_VALUE (Next_Symbol) -
3742 (End_Of_Data - S_GET_VALUE (sp)));
3746 * Check symbol names for the Psect hack with a globalvalue, and then
3747 * generate globalvalues for those that have it.
3750 VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment)
3755 register symbolS *sp;
3756 char *stripped_name, *Name;
3758 int Psect_Attributes;
3762 * Scan the symbol table for globalvalues, and emit def/ref when
3763 * required. These will be caught again later and converted to
3766 for (sp = symbol_rootP; sp; sp = sp->sy_next)
3769 * See if this is something we want to look at.
3771 if ((S_GET_RAW_TYPE (sp) != (N_DATA | N_EXT)) &&
3772 (S_GET_RAW_TYPE (sp) != (N_UNDF | N_EXT)))
3775 * See if this has globalvalue specification.
3777 Name = S_GET_NAME (sp);
3779 if (!HAS_PSECT_ATTRIBUTES (Name))
3782 stripped_name = (char *) malloc (strlen (Name) + 1);
3783 strcpy (stripped_name, Name);
3784 Psect_Attributes = 0;
3785 VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
3787 if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3789 switch (S_GET_RAW_TYPE (sp))
3791 case N_UNDF | N_EXT:
3792 VMS_Global_Symbol_Spec (stripped_name, 0, 0, 2);
3794 case N_DATA | N_EXT:
3795 Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
3797 error ("Invalid data type for globalvalue");
3798 globalvalue = md_chars_to_number (Data_Segment +
3799 S_GET_VALUE (sp) - text_siz , Size);
3800 /* Three times for good luck. The linker seems to get confused
3801 if there are fewer than three */
3802 VMS_Global_Symbol_Spec (stripped_name, 0, 0, 2);
3803 VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue, 3);
3804 VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue, 3);
3807 printf (" Invalid globalvalue of %s\n", stripped_name);
3811 free (stripped_name); /* clean up */
3818 * Define a procedure entry pt/mask
3821 VMS_Procedure_Entry_Pt (Name, Psect_Number, Psect_Offset, Entry_Mask)
3830 * We are writing a GSD record
3832 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3834 * If the buffer is empty we must insert the GSD record type
3836 if (Object_Record_Offset == 0)
3837 PUT_CHAR (OBJ_S_C_GSD);
3839 * We are writing a Procedure Entry Pt/Mask subrecord
3841 if (Psect_Number <= 255)
3843 PUT_CHAR (GSD_S_C_EPM);
3847 PUT_CHAR (GSD_S_C_EPMW);
3850 * Data type is undefined
3854 * Flags = "RELOCATABLE" and "DEFINED"
3856 PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
3860 if (Psect_Number <= 255)
3862 PUT_CHAR (Psect_Number);
3866 PUT_SHORT (Psect_Number);
3871 PUT_LONG (Psect_Offset);
3875 PUT_SHORT (Entry_Mask);
3877 * Finally, the global symbol name
3879 VMS_Case_Hack_Symbol (Name, Local);
3880 PUT_COUNTED_STRING (Local);
3882 * Flush the buffer if it is more than 75% full
3884 if (Object_Record_Offset >
3885 (sizeof (Object_Record_Buffer) * 3 / 4))
3886 Flush_VMS_Object_Record_Buffer ();
3891 * Set the current location counter to a particular Psect and Offset
3894 VMS_Set_Psect (Psect_Index, Offset, Record_Type)
3900 * We are writing a "Record_Type" record
3902 Set_VMS_Object_File_Record (Record_Type);
3904 * If the buffer is empty we must insert the record type
3906 if (Object_Record_Offset == 0)
3907 PUT_CHAR (Record_Type);
3909 * Stack the Psect base + Longword Offset
3911 if (Psect_Index < 255)
3913 PUT_CHAR (TIR_S_C_STA_PL);
3914 PUT_CHAR (Psect_Index);
3918 PUT_CHAR (TIR_S_C_STA_WPL);
3919 PUT_SHORT (Psect_Index);
3923 * Set relocation base
3925 PUT_CHAR (TIR_S_C_CTL_SETRB);
3927 * Flush the buffer if it is more than 75% full
3929 if (Object_Record_Offset >
3930 (sizeof (Object_Record_Buffer) * 3 / 4))
3931 Flush_VMS_Object_Record_Buffer ();
3936 * Store repeated immediate data in current Psect
3939 VMS_Store_Repeated_Data (Repeat_Count, Pointer, Size, Record_Type)
3941 register char *Pointer;
3947 * Ignore zero bytes/words/longwords
3949 if ((Size == sizeof (char)) && (*Pointer == 0))
3951 if ((Size == sizeof (short)) && (*(short *) Pointer == 0))
3953 if ((Size == sizeof (long)) && (*(long *) Pointer == 0))
3956 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
3957 * then we do it manually
3961 while (--Repeat_Count >= 0)
3962 VMS_Store_Immediate_Data (Pointer, Size, Record_Type);
3966 * We are writing a "Record_Type" record
3968 Set_VMS_Object_File_Record (Record_Type);
3970 * If the buffer is empty we must insert record type
3972 if (Object_Record_Offset == 0)
3973 PUT_CHAR (Record_Type);
3975 * Stack the repeat count
3977 PUT_CHAR (TIR_S_C_STA_LW);
3978 PUT_LONG (Repeat_Count);
3980 * And now the command and its data
3982 PUT_CHAR (TIR_S_C_STO_RIVB);
3985 PUT_CHAR (*Pointer++);
3987 * Flush the buffer if it is more than 75% full
3989 if (Object_Record_Offset >
3990 (sizeof (Object_Record_Buffer) * 3 / 4))
3991 Flush_VMS_Object_Record_Buffer ();
3996 * Store a Position Independent Reference
3999 VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative,
4000 Psect, Psect_Offset, Record_Type)
4001 struct symbol *Symbol;
4008 register struct VMS_Symbol *vsp =
4009 (struct VMS_Symbol *) (Symbol->sy_number);
4013 * We are writing a "Record_Type" record
4015 Set_VMS_Object_File_Record (Record_Type);
4017 * If the buffer is empty we must insert record type
4019 if (Object_Record_Offset == 0)
4020 PUT_CHAR (Record_Type);
4022 * Set to the appropriate offset in the Psect
4027 * For a Code reference we need to fix the operand
4028 * specifier as well (so back up 1 byte)
4030 VMS_Set_Psect (Psect, Psect_Offset - 1, Record_Type);
4035 * For a Data reference we just store HERE
4037 VMS_Set_Psect (Psect, Psect_Offset, Record_Type);
4040 * Make sure we are still generating a "Record Type" record
4042 if (Object_Record_Offset == 0)
4043 PUT_CHAR (Record_Type);
4045 * Dispatch on symbol type (so we can stack its value)
4047 switch (S_GET_RAW_TYPE (Symbol))
4052 #ifdef NOT_VAX_11_C_COMPATIBLE
4053 case N_UNDF | N_EXT:
4054 case N_DATA | N_EXT:
4055 #endif /* NOT_VAX_11_C_COMPATIBLE */
4057 case N_TEXT | N_EXT:
4059 * Get the symbol name (case hacked)
4061 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local);
4063 * Stack the global symbol value
4065 PUT_CHAR (TIR_S_C_STA_GBL);
4066 PUT_COUNTED_STRING (Local);
4070 * Stack the longword offset
4072 PUT_CHAR (TIR_S_C_STA_LW);
4075 * Add the two, leaving the result on the stack
4077 PUT_CHAR (TIR_S_C_OPR_ADD);
4081 * Uninitialized local data
4085 * Stack the Psect (+offset)
4087 if (vsp->Psect_Index < 255)
4089 PUT_CHAR (TIR_S_C_STA_PL);
4090 PUT_CHAR (vsp->Psect_Index);
4094 PUT_CHAR (TIR_S_C_STA_WPL);
4095 PUT_SHORT (vsp->Psect_Index);
4097 PUT_LONG (vsp->Psect_Offset + Offset);
4104 * Stack the Psect (+offset)
4106 if (vsp->Psect_Index < 255)
4108 PUT_CHAR (TIR_S_C_STA_PL);
4109 PUT_CHAR (vsp->Psect_Index);
4113 PUT_CHAR (TIR_S_C_STA_WPL);
4114 PUT_SHORT (vsp->Psect_Index);
4116 PUT_LONG (S_GET_VALUE (Symbol) + Offset);
4119 * Initialized local or global data
4122 #ifndef NOT_VAX_11_C_COMPATIBLE
4123 case N_UNDF | N_EXT:
4124 case N_DATA | N_EXT:
4125 #endif /* NOT_VAX_11_C_COMPATIBLE */
4127 * Stack the Psect (+offset)
4129 if (vsp->Psect_Index < 255)
4131 PUT_CHAR (TIR_S_C_STA_PL);
4132 PUT_CHAR (vsp->Psect_Index);
4136 PUT_CHAR (TIR_S_C_STA_WPL);
4137 PUT_SHORT (vsp->Psect_Index);
4139 PUT_LONG (vsp->Psect_Offset + Offset);
4143 * Store either a code or data reference
4145 PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR);
4147 * Flush the buffer if it is more than 75% full
4149 if (Object_Record_Offset >
4150 (sizeof (Object_Record_Buffer) * 3 / 4))
4151 Flush_VMS_Object_Record_Buffer ();
4156 * Check in the text area for an indirect pc-relative reference
4157 * and fix it up with addressing mode 0xff [PC indirect]
4159 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4160 * PIC CODE GENERATING FIXUP ROUTINE.
4163 VMS_Fix_Indirect_Reference (Text_Psect, Offset, fragP, text_frag_root)
4166 register fragS *fragP;
4167 struct frag *text_frag_root;
4170 * The addressing mode byte is 1 byte before the address
4174 * Is it in THIS frag??
4176 if ((Offset < fragP->fr_address) ||
4177 (Offset >= (fragP->fr_address + fragP->fr_fix)))
4180 * We need to search for the fragment containing this
4183 for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
4185 if ((Offset >= fragP->fr_address) &&
4186 (Offset < (fragP->fr_address + fragP->fr_fix)))
4190 * If we couldn't find the frag, things are BAD!!
4193 error ("Couldn't find fixup fragment when checking for indirect reference");
4196 * Check for indirect PC relative addressing mode
4198 if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff)
4200 static char Address_Mode = 0xff;
4203 * Yes: Store the indirect mode back into the image
4204 * to fix up the damage done by STO_PICR
4206 VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR);
4207 VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR);
4212 * If the procedure "main()" exists we have to add the instruction
4213 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4215 VMS_Check_For_Main ()
4217 register symbolS *symbolP;
4218 #ifdef HACK_DEC_C_STARTUP /* JF */
4219 register struct frchain *frchainP;
4220 register fragS *fragP;
4221 register fragS **prev_fragPP;
4222 register struct fix *fixP;
4223 register fragS *New_Frag;
4225 #endif /* HACK_DEC_C_STARTUP */
4227 symbolP = (struct symbol *) symbol_find ("_main");
4228 if (symbolP && !S_IS_DEBUG (symbolP) &&
4229 S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
4231 #ifdef HACK_DEC_C_STARTUP
4236 * Remember the entry point symbol
4238 Entry_Point_Symbol = symbolP;
4239 #ifdef HACK_DEC_C_STARTUP
4244 * Scan all the fragment chains for the one with "_main"
4245 * (Actually we know the fragment from the symbol, but we need
4246 * the previous fragment so we can change its pointer)
4248 frchainP = frchain_root;
4252 * Scan all the fragments in this chain, remembering
4253 * the "previous fragment"
4255 prev_fragPP = &frchainP->frch_root;
4256 fragP = frchainP->frch_root;
4257 while (fragP && (fragP != frchainP->frch_last))
4260 * Is this the fragment?
4262 if (fragP == symbolP->sy_frag)
4265 * Yes: Modify the fragment by replacing
4266 * it with a new fragment.
4268 New_Frag = (fragS *)
4269 xmalloc (sizeof (*New_Frag) +
4274 * The fragments are the same except
4275 * that the "fixed" area is larger
4278 New_Frag->fr_fix += 6;
4280 * Copy the literal data opening a hole
4281 * 2 bytes after "_main" (i.e. just after
4282 * the entry mask). Into which we place
4283 * the JSB instruction.
4285 New_Frag->fr_literal[0] = fragP->fr_literal[0];
4286 New_Frag->fr_literal[1] = fragP->fr_literal[1];
4287 New_Frag->fr_literal[2] = 0x16; /* Jsb */
4288 New_Frag->fr_literal[3] = 0xef;
4289 New_Frag->fr_literal[4] = 0;
4290 New_Frag->fr_literal[5] = 0;
4291 New_Frag->fr_literal[6] = 0;
4292 New_Frag->fr_literal[7] = 0;
4293 for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++)
4294 New_Frag->fr_literal[i + 6] =
4295 fragP->fr_literal[i];
4297 * Now replace the old fragment with the
4298 * newly generated one.
4300 *prev_fragPP = New_Frag;
4302 * Remember the entry point symbol
4304 Entry_Point_Symbol = symbolP;
4306 * Scan the text area fixup structures
4307 * as offsets in the fragment may have
4310 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
4313 * Look for references to this
4316 if (fixP->fx_frag == fragP)
4319 * Change the fragment
4322 fixP->fx_frag = New_Frag;
4324 * If the offset is after
4325 * the entry mask we need
4326 * to account for the JSB
4327 * instruction we just
4330 if (fixP->fx_where >= 2)
4331 fixP->fx_where += 6;
4335 * Scan the symbols as offsets in the
4336 * fragment may have changed
4338 for (symbolP = symbol_rootP;
4340 symbolP = symbol_next (symbolP))
4343 * Look for references to this
4346 if (symbolP->sy_frag == fragP)
4349 * Change the fragment
4352 symbolP->sy_frag = New_Frag;
4354 * If the offset is after
4355 * the entry mask we need
4356 * to account for the JSB
4357 * instruction we just
4360 if (S_GET_VALUE (symbolP) >= 2)
4361 S_SET_VALUE (symbolP,
4362 S_GET_VALUE (symbolP) + 6);
4366 * Make a symbol reference to
4367 * "_c$main_args" so we can get
4368 * its address inserted into the
4371 symbolP = (symbolS *) xmalloc (sizeof (*symbolP));
4372 S_GET_NAME (symbolP) = "_c$main_args";
4373 S_SET_TYPE (symbolP, N_UNDF);
4374 S_GET_OTHER (symbolP) = 0;
4375 S_GET_DESC (symbolP) = 0;
4376 S_SET_VALUE (symbolP, 0);
4377 symbolP->sy_name_offset = 0;
4378 symbolP->sy_number = 0;
4379 symbolP->sy_frag = New_Frag;
4380 symbolP->sy_resolved = 0;
4381 symbolP->sy_resolving = 0;
4382 /* this actually inserts at the beginning of the list */
4383 symbol_append (symbol_rootP, symbolP, &symbol_rootP, &symbol_lastP);
4385 symbol_rootP = symbolP;
4387 * Generate a text fixup structure
4388 * to get "_c$main_args" stored into the
4391 fixP = (struct fix *) xmalloc (sizeof (*fixP));
4392 fixP->fx_frag = New_Frag;
4394 fixP->fx_addsy = symbolP;
4396 fixP->fx_offset = 0;
4397 fixP->fx_size = sizeof (long);
4399 fixP->fx_next = text_fix_root;
4400 text_fix_root = fixP;
4402 * Now make sure we exit from the loop
4408 * Try the next fragment
4410 prev_fragPP = &fragP->fr_next;
4411 fragP = fragP->fr_next;
4414 * Try the next fragment chain
4417 frchainP = frchainP->frch_next;
4420 #endif /* HACK_DEC_C_STARTUP */
4425 * Write a VAX/VMS object file (everything else has been done!)
4427 VMS_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
4432 struct frag *text_frag_root;
4433 struct frag *data_frag_root;
4435 register fragS *fragP;
4436 register symbolS *symbolP;
4437 register symbolS *sp;
4438 register struct fix *fixP;
4439 register struct VMS_Symbol *vsp;
4441 int Local_Initialized_Data_Size = 0;
4443 int Psect_Number = 0; /* Psect Index Number */
4444 int Text_Psect = -1; /* Text Psect Index */
4445 int Data_Psect = -2; /* Data Psect Index JF: Was -1 */
4446 int Bss_Psect = -3; /* Bss Psect Index JF: Was -1 */
4449 * Create the VMS object file
4451 Create_VMS_Object_File ();
4453 * Write the module header records
4455 Write_VMS_MHD_Records ();
4458 * Store the Data segment:
4460 * Since this is REALLY hard to do any other way,
4461 * we actually manufacture the data segment and
4462 * the store the appropriate values out of it.
4463 * We need to generate this early, so that globalvalues
4464 * can be properly emitted.
4469 * Allocate the data segment
4471 Data_Segment = (char *) xmalloc (data_siz);
4473 * Run through the data fragments, filling in the segment
4475 for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
4477 register long int count;
4478 register char *fill_literal;
4479 register long int fill_size;
4482 i = fragP->fr_address - text_siz;
4484 memcpy (Data_Segment + i,
4489 fill_literal = fragP->fr_literal + fragP->fr_fix;
4490 fill_size = fragP->fr_var;
4491 for (count = fragP->fr_offset; count; count--)
4494 memcpy (Data_Segment + i, fill_literal, fill_size);
4502 * Generate the VMS object file records
4503 * 1st GSD then TIR records
4506 /******* Global Symbol Dictionary *******/
4508 * Emit globalvalues now. We must do this before the text psect
4509 * is defined, or we will get linker warnings about multiply defined
4510 * symbols. All of the globalvalues "reference" psect 0, although
4511 * it really does not have anything to do with it.
4513 VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment);
4515 * Define the Text Psect
4517 Text_Psect = Psect_Number++;
4518 VMS_Psect_Spec ("$code", text_siz, "TEXT", 0);
4520 * Define the BSS Psect
4524 Bss_Psect = Psect_Number++;
4525 VMS_Psect_Spec ("$uninitialized_data", bss_siz, "DATA", 0);
4527 #ifndef gxx_bug_fixed
4529 * The g++ compiler does not write out external references to vtables
4530 * correctly. Check for this and holler if we see it happening.
4531 * If that compiler bug is ever fixed we can remove this.
4533 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4536 * Dispatch on symbol type
4538 switch (S_GET_RAW_TYPE (sp)) {
4544 * Make a GSD global symbol reference
4547 if (strncmp (S_GET_NAME (sp),"__vt.",5) == 0)
4549 S_GET_RAW_TYPE (sp) = N_UNDF | N_EXT;
4550 as_warn("g++ wrote an extern reference to %s as a routine.",
4552 as_warn("I will fix it, but I hope that it was not really a routine");
4559 #endif /* gxx_bug_fixed */
4561 * Now scan the symbols and emit the appropriate GSD records
4563 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4566 * Dispatch on symbol type
4568 switch (S_GET_RAW_TYPE (sp))
4571 * Global uninitialized data
4573 case N_UNDF | N_EXT:
4575 * Make a VMS data symbol entry
4577 vsp = (struct VMS_Symbol *)
4578 xmalloc (sizeof (*vsp));
4580 vsp->Size = S_GET_VALUE (sp);
4581 vsp->Psect_Index = Psect_Number++;
4582 vsp->Psect_Offset = 0;
4583 vsp->Next = VMS_Symbols;
4585 sp->sy_number = (int) vsp;
4587 * Make the psect for this data
4589 if (S_GET_OTHER (sp))
4590 Globalref = VMS_Psect_Spec (
4596 Globalref = VMS_Psect_Spec (
4604 /* See if this is an external vtable. We want to help the linker find
4605 these things in libraries, so we make a symbol reference. This
4606 is not compatible with VAX-C usage for variables, but since vtables are
4607 only used internally by g++, we can get away with this hack. */
4609 if(strncmp (S_GET_NAME (sp), "__vt.", 5) == 0)
4610 VMS_Global_Symbol_Spec (S_GET_NAME(sp),
4615 #ifdef NOT_VAX_11_C_COMPATIBLE
4617 * Place a global symbol at the
4618 * beginning of the Psect
4620 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4624 #endif /* NOT_VAX_11_C_COMPATIBLE */
4627 * Local uninitialized data
4631 * Make a VMS data symbol entry
4633 vsp = (struct VMS_Symbol *)
4634 xmalloc (sizeof (*vsp));
4637 vsp->Psect_Index = Bss_Psect;
4640 bss_address_frag.fr_address;
4641 vsp->Next = VMS_Symbols;
4643 sp->sy_number = (int) vsp;
4646 * Global initialized data
4648 case N_DATA | N_EXT:
4650 * Make a VMS data symbol entry
4652 vsp = (struct VMS_Symbol *)
4653 xmalloc (sizeof (*vsp));
4655 vsp->Size = VMS_Initialized_Data_Size (sp,
4656 text_siz + data_siz);
4657 vsp->Psect_Index = Psect_Number++;
4658 vsp->Psect_Offset = 0;
4659 vsp->Next = VMS_Symbols;
4661 sp->sy_number = (int) vsp;
4665 if (S_GET_OTHER (sp))
4666 Globalref = VMS_Psect_Spec (
4672 Globalref = VMS_Psect_Spec (
4680 /* See if this is an external vtable. We want to help the linker find
4681 these things in libraries, so we make a symbol definition. This
4682 is not compatible with VAX-C usage for variables, but since vtables are
4683 only used internally by g++, we can get away with this hack. */
4685 if(strncmp (S_GET_NAME (sp), "__vt.", 5) == 0)
4686 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4691 #ifdef NOT_VAX_11_C_COMPATIBLE
4693 * Place a global symbol at the
4694 * beginning of the Psect
4696 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4700 #endif /* NOT_VAX_11_C_COMPATIBLE */
4703 * Local initialized data
4707 * Make a VMS data symbol entry
4709 vsp = (struct VMS_Symbol *)
4710 xmalloc (sizeof (*vsp));
4713 VMS_Initialized_Data_Size (sp,
4714 text_siz + data_siz);
4715 vsp->Psect_Index = Data_Psect;
4717 Local_Initialized_Data_Size;
4718 Local_Initialized_Data_Size += vsp->Size;
4719 vsp->Next = VMS_Symbols;
4721 sp->sy_number = (int) vsp;
4724 * Global Text definition
4726 case N_TEXT | N_EXT:
4728 unsigned short Entry_Mask;
4731 * Get the entry mask
4733 fragP = sp->sy_frag;
4734 Entry_Mask = (fragP->fr_literal[0] & 0xff) +
4735 ((fragP->fr_literal[1] & 0xff)
4738 * Define the Procedure entry pt.
4740 VMS_Procedure_Entry_Pt (S_GET_NAME (sp),
4747 * Local Text definition
4751 * Make a VMS data symbol entry
4753 if (Text_Psect != -1)
4755 vsp = (struct VMS_Symbol *)
4756 xmalloc (sizeof (*vsp));
4759 vsp->Psect_Index = Text_Psect;
4760 vsp->Psect_Offset = S_GET_VALUE (sp);
4761 vsp->Next = VMS_Symbols;
4763 sp->sy_number = (int) vsp;
4771 * Make a GSD global symbol reference
4774 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
4784 * Ignore STAB symbols
4785 * Including .stabs emitted by g++
4787 if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22))
4792 if (S_GET_TYPE (sp) != 22)
4793 printf (" ERROR, unknown type (%d)\n",
4799 * Define the Data Psect
4801 if ((data_siz > 0) && (Local_Initialized_Data_Size > 0))
4806 Data_Psect = Psect_Number++;
4807 VMS_Psect_Spec ("$data",
4808 Local_Initialized_Data_Size,
4811 * Scan the VMS symbols and fill in the data psect
4813 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4816 * Only look for undefined psects
4818 if (vsp->Psect_Index < 0)
4821 * And only initialized data
4823 if ((S_GET_TYPE (vsp->Symbol) == N_DATA) && !S_IS_EXTERNAL (vsp->Symbol))
4824 vsp->Psect_Index = Data_Psect;
4829 /******* Text Information and Relocation Records *******/
4831 * Write the text segment data
4836 * Scan the text fragments
4838 for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
4841 * Stop if we get to the data fragments
4843 if (fragP == data_frag_root)
4846 * Ignore fragments with no data
4848 if ((fragP->fr_fix == 0) && (fragP->fr_var == 0))
4851 * Go the the appropriate offset in the
4854 VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR);
4856 * Store the "fixed" part
4859 VMS_Store_Immediate_Data (fragP->fr_literal,
4863 * Store the "variable" part
4865 if (fragP->fr_var && fragP->fr_offset)
4866 VMS_Store_Repeated_Data (fragP->fr_offset,
4873 * Now we go through the text segment fixups and
4874 * generate TIR records to fix up addresses within
4877 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
4880 * We DO handle the case of "Symbol - Symbol" as
4881 * long as it is in the same segment.
4883 if (fixP->fx_subsy && fixP->fx_addsy)
4888 * They need to be in the same segment
4890 if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
4891 S_GET_RAW_TYPE (fixP->fx_addsy))
4892 error ("Fixup data addsy and subsy didn't have the same type");
4894 * And they need to be in one that we
4895 * can check the psect on
4897 if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
4898 (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
4899 error ("Fixup data addsy and subsy didn't have an appropriate type");
4901 * This had better not be PC relative!
4904 error ("Fixup data was erroneously \"pcrel\"");
4906 * Subtract their values to get the
4909 i = S_GET_VALUE (fixP->fx_addsy) -
4910 S_GET_VALUE (fixP->fx_subsy);
4912 * Now generate the fixup object records
4913 * Set the psect and store the data
4915 VMS_Set_Psect (Text_Psect,
4917 fixP->fx_frag->fr_address,
4919 VMS_Store_Immediate_Data (&i,
4928 * Size will HAVE to be "long"
4930 if (fixP->fx_size != sizeof (long))
4931 error ("Fixup datum was not a longword");
4933 * Symbol must be "added" (if it is ever
4935 * fix this assumption)
4937 if (fixP->fx_addsy == 0)
4938 error ("Fixup datum was not \"fixP->fx_addsy\"");
4940 * Store the symbol value in a PIC fashion
4942 VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
4947 fixP->fx_frag->fr_address,
4950 * Check for indirect address reference,
4951 * which has to be fixed up (as the linker
4952 * will screw it up with TIR_S_C_STO_PICR).
4955 VMS_Fix_Indirect_Reference (Text_Psect,
4957 fixP->fx_frag->fr_address,
4963 * Store the Data segment:
4965 * Since this is REALLY hard to do any other way,
4966 * we actually manufacture the data segment and
4967 * the store the appropriate values out of it.
4968 * The segment was manufactured before, now we just
4969 * dump it into the appropriate psects.
4975 * Now we can run through all the data symbols
4976 * and store the data
4978 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4981 * Ignore anything other than data symbols
4983 if (S_GET_TYPE (vsp->Symbol) != N_DATA)
4986 * Set the Psect + Offset
4988 VMS_Set_Psect (vsp->Psect_Index,
4994 VMS_Store_Immediate_Data (Data_Segment +
4995 S_GET_VALUE (vsp->Symbol) -
5001 * Now we go through the data segment fixups and
5002 * generate TIR records to fix up addresses within
5005 for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
5008 * Find the symbol for the containing datum
5010 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
5013 * Only bother with Data symbols
5016 if (S_GET_TYPE (sp) != N_DATA)
5019 * Ignore symbol if After fixup
5021 if (S_GET_VALUE (sp) >
5023 fixP->fx_frag->fr_address))
5026 * See if the datum is here
5028 if ((S_GET_VALUE (sp) + vsp->Size) <=
5030 fixP->fx_frag->fr_address))
5033 * We DO handle the case of "Symbol - Symbol" as
5034 * long as it is in the same segment.
5036 if (fixP->fx_subsy && fixP->fx_addsy)
5041 * They need to be in the same segment
5043 if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
5044 S_GET_RAW_TYPE (fixP->fx_addsy))
5045 error ("Fixup data addsy and subsy didn't have the same type");
5047 * And they need to be in one that we
5048 * can check the psect on
5050 if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
5051 (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
5052 error ("Fixup data addsy and subsy didn't have an appropriate type");
5054 * This had better not be PC relative!
5057 error ("Fixup data was erroneously \"pcrel\"");
5059 * Subtract their values to get the
5062 i = S_GET_VALUE (fixP->fx_addsy) -
5063 S_GET_VALUE (fixP->fx_subsy);
5065 * Now generate the fixup object records
5066 * Set the psect and store the data
5068 VMS_Set_Psect (vsp->Psect_Index,
5069 fixP->fx_frag->fr_address +
5071 S_GET_VALUE (vsp->Symbol) +
5074 VMS_Store_Immediate_Data (&i,
5083 * Size will HAVE to be "long"
5085 if (fixP->fx_size != sizeof (long))
5086 error ("Fixup datum was not a longword");
5088 * Symbol must be "added" (if it is ever
5090 * fix this assumption)
5092 if (fixP->fx_addsy == 0)
5093 error ("Fixup datum was not \"fixP->fx_addsy\"");
5095 * Store the symbol value in a PIC fashion
5097 VMS_Store_PIC_Symbol_Reference (
5102 fixP->fx_frag->fr_address +
5104 S_GET_VALUE (vsp->Symbol) +
5117 * Write the Traceback Begin Module record
5119 VMS_TBT_Module_Begin ();
5121 * Scan the symbols and write out the routines
5122 * (this makes the assumption that symbols are in
5123 * order of ascending text segment offset)
5126 struct symbol *Current_Routine = 0;
5127 int Current_Line_Number = 0;
5128 int Current_Offset = -1;
5129 struct input_file *Current_File;
5131 /* Output debugging info for global variables and static variables that are not
5132 * specific to one routine. We also need to examine all stabs directives, to
5133 * find the definitions to all of the advanced data types, and this is done by
5134 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5135 * the object file, since there can be forward references in the stabs
5136 * directives. When through with parsing, the text of the stabs directive
5137 * is altered, with the definitions removed, so that later passes will see
5138 * directives as they would be written if the type were already defined.
5140 * We also look for files and include files, and make a list of them. We
5141 * examine the source file numbers to establish the actual lines that code was
5142 * generated from, and then generate offsets.
5145 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
5148 * Deal with STAB symbols
5150 if (S_IS_DEBUG (symbolP))
5153 * Dispatch on STAB type
5155 switch ((unsigned char) S_GET_RAW_TYPE (symbolP))
5158 if (S_GET_DESC (symbolP) > Current_File->max_line)
5159 Current_File->max_line = S_GET_DESC (symbolP);
5160 if (S_GET_DESC (symbolP) < Current_File->min_line)
5161 Current_File->min_line = S_GET_DESC (symbolP);
5164 Current_File = find_file (symbolP);
5165 Current_File->flag = 1;
5166 Current_File->min_line = 1;
5169 Current_File = find_file (symbolP);
5172 VMS_GSYM_Parse (symbolP, Text_Psect);
5175 VMS_LCSYM_Parse (symbolP, Text_Psect);
5177 case N_FUN: /* For static constant symbols */
5179 VMS_STSYM_Parse (symbolP, Text_Psect);
5185 /* now we take a quick sweep through the files and assign offsets
5186 to each one. This will essentially be the starting line number to the
5187 debugger for each file. Output the info for the debugger to specify the
5188 files, and then tell it how many lines to use */
5190 int File_Number = 0;
5191 int Debugger_Offset = 0;
5193 Current_File = file_root;
5194 for (Current_File = file_root; Current_File; Current_File = Current_File->next)
5196 if (Current_File == (struct input_file *) NULL)
5198 if (Current_File->max_line == 0)
5200 if ((strncmp (Current_File->name, "GNU_GXX_INCLUDE:", 16) == 0) &&
5203 if ((strncmp (Current_File->name, "GNU_CC_INCLUDE:", 15) == 0) &&
5206 /* show a few extra lines at the start of the region selected */
5207 if (Current_File->min_line > 2)
5208 Current_File->min_line -= 2;
5209 Current_File->offset = Debugger_Offset - Current_File->min_line + 1;
5210 Debugger_Offset += Current_File->max_line - Current_File->min_line + 1;
5211 if (Current_File->same_file_fpnt != (struct input_file *) NULL)
5212 Current_File->file_number = Current_File->same_file_fpnt->file_number;
5215 Current_File->file_number = ++File_Number;
5216 file_available = VMS_TBT_Source_File (Current_File->name,
5217 Current_File->file_number);
5218 if (!file_available)
5220 Current_File->file_number = 0;
5225 VMS_TBT_Source_Lines (Current_File->file_number,
5226 Current_File->min_line,
5227 Current_File->max_line - Current_File->min_line + 1);
5230 Current_File = (struct input_file *) NULL;
5232 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
5235 * Deal with text symbols
5237 if (!S_IS_DEBUG (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
5240 * Ignore symbols starting with "L",
5241 * as they are local symbols
5243 if (*S_GET_NAME (symbolP) == 'L')
5246 * If there is a routine start defined,
5249 if (Current_Routine)
5254 VMS_TBT_Routine_End (text_siz, Current_Routine);
5257 * Store the routine begin traceback info
5259 if (Text_Psect != -1)
5261 VMS_TBT_Routine_Begin (symbolP, Text_Psect);
5262 Current_Routine = symbolP;
5264 /* Output local symbols, i.e. all symbols that are associated with a specific
5265 * routine. We output them now so the debugger recognizes them as local to
5272 for (symbolP1 = Current_Routine; symbolP1; symbolP1 = symbol_next (symbolP1))
5274 if (!S_IS_DEBUG (symbolP1))
5276 if (S_GET_RAW_TYPE (symbolP1) != N_FUN)
5278 pnt = S_GET_NAME (symbolP);
5279 pnt1 = S_GET_NAME (symbolP1);
5282 while (*pnt++ == *pnt1++)
5285 if (*pnt1 != 'F' && *pnt1 != 'f') continue;
5286 if ((*(--pnt) == '\0') && (*(--pnt1) == ':'))
5289 if (symbolP1 != (symbolS *) NULL)
5290 VMS_DBG_Define_Routine (symbolP1, Current_Routine, Text_Psect);
5291 } /* local symbol block */
5298 * Deal with STAB symbols
5300 if (S_IS_DEBUG (symbolP))
5303 * Dispatch on STAB type
5305 switch ((unsigned char) S_GET_RAW_TYPE (symbolP))
5311 /* Offset the line into the correct portion
5313 if (Current_File->file_number == 0)
5315 /* Sometimes the same offset gets several source
5316 * lines assigned to it.
5317 * We should be selective about which lines
5318 * we allow, we should prefer lines that are
5319 * in the main source file when debugging
5320 * inline functions. */
5321 if ((Current_File->file_number != 1) &&
5322 S_GET_VALUE (symbolP) ==
5325 /* calculate actual debugger source line */
5326 S_GET_DESC (symbolP)
5327 += Current_File->offset;
5329 * If this is the 1st N_SLINE, setup
5330 * PC/Line correlation. Otherwise
5331 * do the delta PC/Line. If the offset
5332 * for the line number is not +ve we need
5333 * to do another PC/Line correlation
5336 if (Current_Offset == -1)
5338 VMS_TBT_Line_PC_Correlation (
5339 S_GET_DESC (symbolP),
5340 S_GET_VALUE (symbolP),
5346 if ((S_GET_DESC (symbolP) -
5347 Current_Line_Number) <= 0)
5350 * Line delta is not +ve, we
5351 * need to close the line and
5352 * start a new PC/Line
5355 VMS_TBT_Line_PC_Correlation (0,
5356 S_GET_VALUE (symbolP) -
5360 VMS_TBT_Line_PC_Correlation (
5361 S_GET_DESC (symbolP),
5362 S_GET_VALUE (symbolP),
5369 * Line delta is +ve, all is well
5371 VMS_TBT_Line_PC_Correlation (
5372 S_GET_DESC (symbolP) -
5373 Current_Line_Number,
5374 S_GET_VALUE (symbolP) -
5381 * Update the current line/PC
5383 Current_Line_Number = S_GET_DESC (symbolP);
5384 Current_Offset = S_GET_VALUE (symbolP);
5394 * Remember that we had a source file
5395 * and emit the source file debugger
5399 find_file (symbolP);
5401 /* We need to make sure that we are really in the actual source file when
5402 * we compute the maximum line number. Otherwise the debugger gets really
5406 find_file (symbolP);
5412 * If there is a routine start defined,
5413 * terminate it (and the line numbers)
5415 if (Current_Routine)
5418 * Terminate the line numbers
5420 VMS_TBT_Line_PC_Correlation (0,
5421 text_siz - S_GET_VALUE (Current_Routine),
5425 * Terminate the routine
5427 VMS_TBT_Routine_End (text_siz, Current_Routine);
5431 * Write the Traceback End Module TBT record
5433 VMS_TBT_Module_End ();
5436 * Write the End Of Module record
5438 if (Entry_Point_Symbol == 0)
5439 Write_VMS_EOM_Record (-1, 0);
5441 Write_VMS_EOM_Record (Text_Psect,
5442 S_GET_VALUE (Entry_Point_Symbol));
5445 * All done, close the object file
5447 Close_VMS_Object_File ();
5450 /* end of obj-vms.c */