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 ()
383 obj_crawl_symbol_chain (headers
)
384 object_headers
*headers
;
388 int symbol_number
= 0;
390 { /* crawl symbol table */
391 register int symbol_number
= 0;
394 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
395 while ((symbolP
= *symbolPP
) != NULL
)
397 resolve_symbol_value (symbolP
);
399 /* OK, here is how we decide which symbols go out into the
400 brave new symtab. Symbols that do are:
402 * symbols with no name (stabd's?)
403 * symbols with debug info in their N_TYPE
405 Symbols that don't are:
406 * symbols that are registers
407 * symbols with \1 as their 3rd character (numeric labels)
408 * "local labels" as defined by S_LOCAL_NAME(name)
409 if the -L switch was passed to gas.
411 All other symbols are output. We complain if a deleted
412 symbol was marked external. */
415 if (!S_IS_REGISTER (symbolP
))
417 symbolP
->sy_name_offset
= 0;
418 symbolPP
= &(symbol_next (symbolP
));
422 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
424 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
427 } /* if this symbol should be in the output */
428 } /* for each symbol */
430 H_SET_STRING_SIZE (headers
, string_byte_count
);
431 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
432 } /* crawl symbol table */
434 } /* obj_crawl_symbol_chain() */
437 /****** VMS OBJECT FILE HACKING ROUTINES *******/
441 * Create the VMS object file
444 Create_VMS_Object_File ()
446 #if defined(eunice) || !defined(HO_VMS)
447 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
449 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
450 "mbc=16", "deq=64", "fop=tef", "shr=nil");
455 if (VMS_Object_File_FD
< 0)
457 char Error_Line
[256];
459 sprintf (Error_Line
, "Couldn't create VMS object file \"%s\"",
464 * Initialize object file hacking variables
466 Object_Record_Offset
= 0;
467 Current_Object_Record_Type
= -1;
472 * Flush the object record buffer to the object file
475 Flush_VMS_Object_Record_Buffer ()
481 * If the buffer is empty, we are done
483 if (Object_Record_Offset
== 0)
486 * Write the data to the file
488 #ifndef HO_VMS /* For cross-assembly purposes. */
489 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
490 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
491 #endif /* not HO_VMS */
492 i
= write (VMS_Object_File_FD
,
493 Object_Record_Buffer
,
494 Object_Record_Offset
);
495 if (i
!= Object_Record_Offset
)
496 error ("I/O error writing VMS object file");
497 #ifndef HO_VMS /* When cross-assembling, we need to pad the record to an even
499 /* pad it if needed */
501 if (Object_Record_Offset
& 1 != 0)
502 write (VMS_Object_File_FD
, &zero
, 1);
503 #endif /* not HO_VMS */
505 * The buffer is now empty
507 Object_Record_Offset
= 0;
512 * Declare a particular type of object file record
515 Set_VMS_Object_File_Record (Type
)
519 * If the type matches, we are done
521 if (Type
== Current_Object_Record_Type
)
524 * Otherwise: flush the buffer
526 Flush_VMS_Object_Record_Buffer ();
530 Current_Object_Record_Type
= Type
;
536 * Close the VMS Object file
539 Close_VMS_Object_File ()
541 short int m_one
= -1;
542 #ifndef HO_VMS /* For cross-assembly purposes. */
543 /* Write a 0xffff into the file, which means "End of File" */
544 write (VMS_Object_File_FD
, &m_one
, 2);
545 #endif /* not HO_VMS */
546 close (VMS_Object_File_FD
);
551 * Store immediate data in current Psect
554 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
562 * We are writing a "Record_Type" record
564 Set_VMS_Object_File_Record (Record_Type
);
566 * We can only store 128 bytes at a time
571 * Store a maximum of 128 bytes
573 i
= (Size
> 128) ? 128 : Size
;
576 * If we cannot accommodate this record, flush the
579 if ((Object_Record_Offset
+ i
+ 1) >=
580 sizeof (Object_Record_Buffer
))
581 Flush_VMS_Object_Record_Buffer ();
583 * If the buffer is empty we must insert record type
585 if (Object_Record_Offset
== 0)
586 PUT_CHAR (Record_Type
);
590 PUT_CHAR (-i
& 0xff);
595 PUT_CHAR (*Pointer
++);
597 * Flush the buffer if it is more than 75% full
599 if (Object_Record_Offset
>
600 (sizeof (Object_Record_Buffer
) * 3 / 4))
601 Flush_VMS_Object_Record_Buffer ();
606 * Make a data reference
609 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
616 * We are writing a "Record_Type" record
618 Set_VMS_Object_File_Record (Record_Type
);
620 * If the buffer is empty we must insert the record type
622 if (Object_Record_Offset
== 0)
623 PUT_CHAR (Record_Type
);
625 * Stack the Psect base + Longword Offset
629 if (Psect_Index
> 127)
631 PUT_CHAR (TIR_S_C_STA_WPL
);
632 PUT_SHORT (Psect_Index
);
637 PUT_CHAR (TIR_S_C_STA_PL
);
638 PUT_CHAR (Psect_Index
);
646 PUT_CHAR (TIR_S_C_STA_WPL
);
647 PUT_SHORT (Psect_Index
);
650 else if (Offset
> 127)
652 PUT_CHAR (TIR_S_C_STA_WPW
);
653 PUT_SHORT (Psect_Index
);
658 PUT_CHAR (TIR_S_C_STA_WPB
);
659 PUT_SHORT (Psect_Index
);
664 * Set relocation base
666 PUT_CHAR (TIR_S_C_STO_PIDR
);
668 * Flush the buffer if it is more than 75% full
670 if (Object_Record_Offset
>
671 (sizeof (Object_Record_Buffer
) * 3 / 4))
672 Flush_VMS_Object_Record_Buffer ();
676 * Make a debugger reference to a struct, union or enum.
679 VMS_Store_Struct (Struct_Index
)
683 * We are writing a "OBJ_S_C_DBG" record
685 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
687 * If the buffer is empty we must insert the record type
689 if (Object_Record_Offset
== 0)
690 PUT_CHAR (OBJ_S_C_DBG
);
691 PUT_CHAR (TIR_S_C_STA_UW
);
692 PUT_SHORT (Struct_Index
);
693 PUT_CHAR (TIR_S_C_CTL_STKDL
);
694 PUT_CHAR (TIR_S_C_STO_L
);
696 * Flush the buffer if it is more than 75% full
698 if (Object_Record_Offset
>
699 (sizeof (Object_Record_Buffer
) * 3 / 4))
700 Flush_VMS_Object_Record_Buffer ();
704 * Make a debugger reference to partially define a struct, union or enum.
707 VMS_Def_Struct (Struct_Index
)
711 * We are writing a "OBJ_S_C_DBG" record
713 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
715 * If the buffer is empty we must insert the record type
717 if (Object_Record_Offset
== 0)
718 PUT_CHAR (OBJ_S_C_DBG
);
719 PUT_CHAR (TIR_S_C_STA_UW
);
720 PUT_SHORT (Struct_Index
);
721 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
723 * Flush the buffer if it is more than 75% full
725 if (Object_Record_Offset
>
726 (sizeof (Object_Record_Buffer
) * 3 / 4))
727 Flush_VMS_Object_Record_Buffer ();
731 VMS_Set_Struct (Struct_Index
)
733 { /* see previous functions for comments */
734 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
735 if (Object_Record_Offset
== 0)
736 PUT_CHAR (OBJ_S_C_DBG
);
737 PUT_CHAR (TIR_S_C_STA_UW
);
738 PUT_SHORT (Struct_Index
);
739 PUT_CHAR (TIR_S_C_CTL_STLOC
);
740 if (Object_Record_Offset
>
741 (sizeof (Object_Record_Buffer
) * 3 / 4))
742 Flush_VMS_Object_Record_Buffer ();
746 * Write the Traceback Module Begin record
749 VMS_TBT_Module_Begin ()
751 register char *cp
, *cp1
;
753 char Module_Name
[256];
757 * Get module name (the FILENAME part of the object file)
763 if ((*cp
== ']') || (*cp
== '>') ||
764 (*cp
== ':') || (*cp
== '/'))
770 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
774 * Limit it to 31 characters
776 while (--cp1
>= Module_Name
)
779 if (strlen (Module_Name
) > 31)
782 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
786 * Arrange to store the data locally (leave room for size byte)
792 *cp
++ = DST_S_C_MODBEG
;
798 * Language type == "C"
800 COPY_LONG (cp
, DST_S_C_C
);
803 * Store the module name
805 *cp
++ = strlen (Module_Name
);
810 * Now we can store the record size
815 * Put it into the object record
817 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
822 * Write the Traceback Module End record
825 VMS_TBT_Module_End ()
833 Local
[1] = DST_S_C_MODEND
;
835 * Put it into the object record
837 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
842 * Write the Traceback Routine Begin record
845 VMS_TBT_Routine_Begin (symbolP
, Psect
)
846 struct symbol
*symbolP
;
849 register char *cp
, *cp1
;
856 * Strip the leading "_" from the name
858 Name
= S_GET_NAME (symbolP
);
862 * Get the text psect offset
864 Offset
= S_GET_VALUE (symbolP
);
866 * Calculate the record size
868 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
876 Local
[1] = DST_S_C_RTNBEG
;
882 * Store the data so far
884 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
886 * Make sure we are still generating a OBJ_S_C_TBT record
888 if (Object_Record_Offset
== 0)
889 PUT_CHAR (OBJ_S_C_TBT
);
891 * Now get the symbol address
893 PUT_CHAR (TIR_S_C_STA_WPL
);
897 * Store the data reference
899 PUT_CHAR (TIR_S_C_STO_PIDR
);
901 * Store the counted string as data
905 Size
= strlen (cp1
) + 1;
909 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
914 * Write the Traceback Routine End record
915 * We *must* search the symbol table to find the next routine, since
916 * the assember has a way of reassembling the symbol table OUT OF ORDER
917 * Thus the next routine in the symbol list is not necessarily the
918 * next one in memory. For debugging to work correctly we must know the
919 * size of the routine.
922 VMS_TBT_Routine_End (Max_Size
, sp
)
927 int Size
= 0x7fffffff;
931 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
933 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
935 if (*S_GET_NAME (symbolP
) == 'L')
937 if ((S_GET_VALUE (symbolP
) > S_GET_VALUE (sp
)) &&
938 (S_GET_VALUE (symbolP
) < Size
))
939 Size
= S_GET_VALUE (symbolP
);
940 /* check if gcc_compiled. has size of zero */
941 if ((S_GET_VALUE (symbolP
) == S_GET_VALUE (sp
)) &&
943 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
944 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
945 Size
= S_GET_VALUE (symbolP
);
949 if (Size
== 0x7fffffff)
951 Size
-= S_GET_VALUE (sp
); /* and get the size of the routine */
959 Local
[1] = DST_S_C_RTNEND
;
967 COPY_LONG (&Local
[3], Size
);
971 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
975 * Write the Traceback Block End record
978 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
979 struct symbol
*symbolP
;
983 register char *cp
, *cp1
;
990 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
996 * Begin Block - We simulate with a phony routine
998 Local
[1] = DST_S_C_BLKBEG
;
1004 * Store the data so far
1006 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1008 * Make sure we are still generating a OBJ_S_C_DBG record
1010 if (Object_Record_Offset
== 0)
1011 PUT_CHAR (OBJ_S_C_DBG
);
1013 * Now get the symbol address
1015 PUT_CHAR (TIR_S_C_STA_WPL
);
1018 * Get the text psect offset
1020 Offset
= S_GET_VALUE (symbolP
);
1023 * Store the data reference
1025 PUT_CHAR (TIR_S_C_STO_PIDR
);
1027 * Store the counted string as data
1031 Size
= strlen (cp1
) + 1;
1035 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1040 * Write the Traceback Block End record
1043 VMS_TBT_Block_End (Size
)
1049 * End block - simulate with a phony end routine
1052 Local
[1] = DST_S_C_BLKEND
;
1053 COPY_LONG (&Local
[3], Size
);
1058 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1064 * Write a Line number / PC correlation record
1067 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1077 * If not delta, set our PC/Line number correlation
1084 Local
[0] = 1 + 1 + 2 + 1 + 4;
1086 * Line Number/PC correlation
1088 Local
[1] = DST_S_C_LINE_NUM
;
1092 Local
[2] = DST_S_C_SET_LINE_NUM
;
1093 COPY_SHORT (&Local
[3], Line_Number
- 1);
1097 Local
[5] = DST_S_C_SET_ABS_PC
;
1098 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1100 * Make sure we are still generating a OBJ_S_C_TBT record
1102 if (Object_Record_Offset
== 0)
1103 PUT_CHAR (OBJ_S_C_TBT
);
1106 PUT_CHAR (TIR_S_C_STA_PL
);
1111 PUT_CHAR (TIR_S_C_STA_WPL
);
1115 PUT_CHAR (TIR_S_C_STO_PIDR
);
1117 * Do a PC offset of 0 to register the line number
1120 Local
[1] = DST_S_C_LINE_NUM
;
1121 Local
[2] = 0; /* Increment PC by 0 and register line # */
1122 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1127 * If Delta is negative, terminate the line numbers
1131 Local
[0] = 1 + 1 + 4;
1132 Local
[1] = DST_S_C_LINE_NUM
;
1133 Local
[2] = DST_S_C_TERM_L
;
1134 COPY_LONG (&Local
[3], Offset
);
1135 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1142 * Do a PC/Line delta
1145 *cp
++ = DST_S_C_LINE_NUM
;
1146 if (Line_Number
> 1)
1149 * We need to increment the line number
1151 if (Line_Number
- 1 <= 255)
1153 *cp
++ = DST_S_C_INCR_LINUM
;
1154 *cp
++ = Line_Number
- 1;
1158 *cp
++ = DST_S_C_INCR_LINUM_W
;
1159 COPY_SHORT (cp
, Line_Number
- 1);
1160 cp
+= sizeof (short);
1172 if (Offset
< 0x10000)
1174 *cp
++ = DST_S_C_DELTA_PC_W
;
1175 COPY_SHORT (cp
, Offset
);
1176 cp
+= sizeof (short);
1180 *cp
++ = DST_S_C_DELTA_PC_L
;
1181 COPY_LONG (cp
, Offset
);
1182 cp
+= sizeof (long);
1185 Local
[0] = cp
- (Local
+ 1);
1186 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1192 * Describe a source file to the debugger
1195 VMS_TBT_Source_File (Filename
, ID_Number
)
1199 register char *cp
, *cp1
;
1202 #ifndef HO_VMS /* Used for cross-assembly */
1203 i
= strlen (Filename
);
1205 static struct FAB Fab
;
1206 static struct NAM Nam
;
1207 static struct XABDAT Date_Xab
;
1208 static struct XABFHC File_Header_Xab
;
1209 char Es_String
[255], Rs_String
[255];
1214 Fab
.fab$b_bid
= FAB$C_BID
;
1215 Fab
.fab$b_bln
= sizeof (Fab
);
1216 Fab
.fab$l_nam
= (&Nam
);
1217 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1219 * Setup the Nam block so we can find out the FULL name
1220 * of the source file.
1222 Nam
.nam$b_bid
= NAM$C_BID
;
1223 Nam
.nam$b_bln
= sizeof (Nam
);
1224 Nam
.nam$l_rsa
= Rs_String
;
1225 Nam
.nam$b_rss
= sizeof (Rs_String
);
1226 Nam
.nam$l_esa
= Es_String
;
1227 Nam
.nam$b_ess
= sizeof (Es_String
);
1229 * Setup the Date and File Header Xabs
1231 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1232 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1233 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1234 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1235 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1237 * Get the file information
1239 Fab
.fab$l_fna
= Filename
;
1240 Fab
.fab$b_fns
= strlen (Filename
);
1241 Status
= sys$
open (&Fab
);
1244 printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
1250 * Calculate the size of the resultant string
1257 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1259 * Source declaration
1261 Local
[1] = DST_S_C_SOURCE
;
1263 * Make formfeeds count as source records
1265 Local
[2] = DST_S_C_SRC_FORMFEED
;
1267 * Declare source file
1269 Local
[3] = DST_S_C_SRC_DECLFILE
;
1270 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1279 COPY_SHORT (cp
, ID_Number
);
1280 cp
+= sizeof (short);
1283 * Creation Date. Unknown, so we fill with zeroes.
1286 cp
+= sizeof (long);
1288 cp
+= sizeof (long);
1293 cp
+= sizeof (long);
1298 cp
+= sizeof (short);
1308 #else /* Use this code when assembling for VMS on a VMS system */
1312 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[0];
1313 cp
+= sizeof (long);
1314 *(long *) cp
= ((long *) &Date_Xab
.xab$q_cdt
)[1];
1315 cp
+= sizeof (long);
1319 *(long *) cp
= File_Header_Xab
.xab$l_ebk
;
1320 cp
+= sizeof (long);
1324 *(short *) cp
= File_Header_Xab
.xab$w_ffb
;
1325 cp
+= sizeof (short);
1329 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1339 * Library module name (none)
1345 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1351 * Give the number of source lines to the debugger
1354 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1356 int Starting_Line_Number
;
1357 int Number_Of_Lines
;
1365 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1367 * Source declaration
1369 Local
[1] = DST_S_C_SOURCE
;
1374 *cp
++ = DST_S_C_SRC_SETFILE
;
1378 COPY_SHORT (cp
, ID_Number
);
1379 cp
+= sizeof (short);
1383 *cp
++ = DST_S_C_SRC_SETREC_L
;
1384 COPY_LONG (cp
, Starting_Line_Number
);
1385 cp
+= sizeof (long);
1389 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1390 COPY_SHORT (cp
, Number_Of_Lines
);
1391 cp
+= sizeof (short);
1395 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1401 /* This routine locates a file in the list of files. If an entry does not
1402 * exist, one is created. For include files, a new entry is always created
1403 * such that inline functions can be properly debugged. */
1404 static struct input_file
*
1408 struct input_file
*same_file
;
1409 struct input_file
*fpnt
;
1410 same_file
= (struct input_file
*) NULL
;
1411 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1413 if (fpnt
== (struct input_file
*) NULL
)
1415 if (fpnt
->spnt
== sp
)
1418 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1420 if (fpnt
== (struct input_file
*) NULL
)
1422 if (strcmp (S_GET_NAME (sp
), fpnt
->name
) == 0)
1424 if (fpnt
->flag
== 1)
1430 fpnt
= (struct input_file
*) malloc (sizeof (struct input_file
));
1431 if (file_root
== (struct input_file
*) NULL
)
1435 struct input_file
*fpnt1
;
1436 for (fpnt1
= file_root
; fpnt1
->next
; fpnt1
= fpnt1
->next
) ;
1439 fpnt
->next
= (struct input_file
*) NULL
;
1440 fpnt
->name
= S_GET_NAME (sp
);
1441 fpnt
->min_line
= 0x7fffffff;
1445 fpnt
->file_number
= 0;
1447 fpnt
->same_file_fpnt
= same_file
;
1452 * The following functions and definitions are used to generate object records
1453 * that will describe program variables to the VMS debugger.
1455 * This file contains many of the routines needed to output debugging info into
1456 * the object file that the VMS debugger needs to understand symbols. These
1457 * routines are called very late in the assembly process, and thus we can be
1458 * fairly lax about changing things, since the GSD and the TIR sections have
1459 * already been output.
1463 /* This routine converts a number string into an integer, and stops when it
1464 * sees an invalid character the return value is the address of the character
1465 * just past the last character read. No error is generated.
1468 cvt_integer (str
, rtn
)
1473 neg
= *str
== '-' ? ++str
, -1 : 1;
1474 ival
= 0; /* first get the number of the type for dbx */
1475 while ((*str
<= '9') && (*str
>= '0'))
1476 ival
= 10 * ival
+ *str
++ - '0';
1481 /* this routine fixes the names that are generated by C++, ".this" is a good
1482 * example. The period does not work for the debugger, since it looks like
1483 * the syntax for a structure element, and thus it gets mightily confused
1485 * We also use this to strip the PsectAttribute hack from the name before we
1486 * write a debugger record */
1494 * Kill any leading "_"
1499 * Is there a Psect Attribute to skip??
1501 if (HAS_PSECT_ATTRIBUTES (pnt
))
1506 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1509 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1517 /* Here we fix the .this -> $this conversion */
1518 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1526 /* When defining a structure, this routine is called to find the name of
1527 * the actual structure. It is assumed that str points to the equal sign
1528 * in the definition, and it moves backward until it finds the start of the
1529 * name. If it finds a 0, then it knows that this structure def is in the
1530 * outermost level, and thus symbol_name points to the symbol name.
1533 get_struct_name (str
)
1538 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1543 while ((*pnt
!= ';') && (*pnt
!= '='))
1547 while ((*pnt
< '0') || (*pnt
> '9'))
1549 while ((*pnt
>= '0') && (*pnt
<= '9'))
1554 /* search symbol list for type number dbx_type. Return a pointer to struct */
1555 static struct VMS_DBG_Symbol
*
1556 find_symbol (dbx_type
)
1559 struct VMS_DBG_Symbol
*spnt
;
1560 spnt
= VMS_Symbol_type_list
;
1561 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1563 if (spnt
->dbx_type
== dbx_type
)
1567 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1568 return 0; /*Dunno what this is*/
1569 if(spnt
->advanced
== ALIAS
)
1570 return find_symbol(spnt
->type2
);
1575 /* this routine puts info into either Local or Asuffix, depending on the sign
1576 * of size. The reason is that it is easier to build the variable descriptor
1577 * backwards, while the array descriptor is best built forwards. In the end
1578 * they get put together, if there is not a struct/union/enum along the way
1597 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1601 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1604 Apoint
= MAX_DEBUG_RECORD
- 1;
1607 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1612 /* this routine generates the array descriptor for a given array */
1614 array_suffix (spnt2
)
1615 struct VMS_DBG_Symbol
*spnt2
;
1617 struct VMS_DBG_Symbol
*spnt
;
1618 struct VMS_DBG_Symbol
*spnt1
;
1624 while (spnt
->advanced
!= ARRAY
)
1626 spnt
= find_symbol (spnt
->type2
);
1627 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1633 while (spnt1
->advanced
== ARRAY
)
1636 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1637 spnt1
= find_symbol (spnt1
->type2
);
1639 total_size
= total_size
* spnt1
->data_size
;
1640 push (spnt1
->data_size
, 2);
1641 if (spnt1
->VMS_type
== 0xa3)
1644 push (spnt1
->VMS_type
, 1);
1646 for (i
= 0; i
< 6; i
++)
1650 push (total_size
, 4);
1653 while (spnt1
->advanced
== ARRAY
)
1655 push (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1656 spnt1
= find_symbol (spnt1
->type2
);
1659 while (spnt1
->advanced
== ARRAY
)
1661 push (spnt1
->index_min
, 4);
1662 push (spnt1
->index_max
, 4);
1663 spnt1
= find_symbol (spnt1
->type2
);
1667 /* this routine generates the start of a variable descriptor based upon
1668 * a struct/union/enum that has yet to be defined. We define this spot as
1669 * a new location, and save four bytes for the address. When the struct is
1670 * finally defined, then we can go back and plug in the correct address
1673 new_forward_ref (dbx_type
)
1676 struct forward_ref
*fpnt
;
1677 fpnt
= (struct forward_ref
*) malloc (sizeof (struct forward_ref
));
1678 fpnt
->next
= f_ref_root
;
1680 fpnt
->dbx_type
= dbx_type
;
1681 fpnt
->struc_numb
= ++structure_count
;
1682 fpnt
->resolved
= 'N';
1685 push (total_len
, -2);
1686 struct_number
= -fpnt
->struc_numb
;
1689 /* this routine generates the variable descriptor used to describe non-basic
1690 * variables. It calls itself recursively until it gets to the bottom of it
1691 * all, and then builds the descriptor backwards. It is easiest to do it this
1692 *way since we must periodically write length bytes, and it is easiest if we know
1693 *the value when it is time to write it.
1696 gen1 (spnt
, array_suffix_len
)
1697 struct VMS_DBG_Symbol
*spnt
;
1698 int array_suffix_len
;
1700 struct VMS_DBG_Symbol
*spnt1
;
1702 switch (spnt
->advanced
)
1705 push (DBG_S_C_VOID
, -1);
1707 push (total_len
, -2);
1711 if (array_suffix_len
== 0)
1713 push (spnt
->VMS_type
, -1);
1714 push (DBG_S_C_BASIC
, -1);
1716 push (total_len
, -2);
1726 struct_number
= spnt
->struc_numb
;
1727 if (struct_number
< 0)
1729 new_forward_ref (spnt
->dbx_type
);
1732 push (DBG_S_C_STRUCT
, -1);
1734 push (total_len
, -2);
1737 spnt1
= find_symbol (spnt
->type2
);
1739 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1740 new_forward_ref (spnt
->type2
);
1742 i
= gen1 (spnt1
, 0);
1744 { /* (*void) is a special case, do not put pointer suffix*/
1745 push (DBG_S_C_POINTER
, -1);
1747 push (total_len
, -2);
1752 while (spnt1
->advanced
== ARRAY
)
1754 spnt1
= find_symbol (spnt1
->type2
);
1755 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
1757 printf ("gcc-as warning(debugger output):");
1758 printf ("Forward reference error, dbx type %d\n",
1763 /* It is too late to generate forward references, so the user gets a message.
1764 * This should only happen on a compiler error */
1765 i
= gen1 (spnt1
, 1);
1767 array_suffix (spnt
);
1768 array_suffix_len
= Apoint
- i
;
1769 switch (spnt1
->advanced
)
1777 push (total_len
, -2);
1780 push (DBG_S_C_COMPLEX_ARRAY
, -1);
1782 total_len
+= array_suffix_len
+ 8;
1783 push (total_len
, -2);
1787 /* This generates a suffix for a variable. If it is not a defined type yet,
1788 * then dbx_type contains the type we are expecting so we can generate a
1789 * forward reference. This calls gen1 to build most of the descriptor, and
1790 * then it puts the icing on at the end. It then dumps whatever is needed
1791 * to get a complete descriptor (i.e. struct reference, array suffix ).
1794 generate_suffix (spnt
, dbx_type
)
1795 struct VMS_DBG_Symbol
*spnt
;
1800 static CONST
char pvoid
[6] = {5, 0xaf, 0, 1, 0, 5};
1801 struct VMS_DBG_Symbol
*spnt1
;
1803 Lpnt
= MAX_DEBUG_RECORD
- 1;
1807 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1808 new_forward_ref (dbx_type
);
1811 if (spnt
->VMS_type
!= 0xa3)
1812 return 0; /* no suffix needed */
1817 push (total_len
, -1);
1818 /* if the variable descriptor overflows the record, output a descriptor for
1819 * a pointer to void.
1821 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1823 printf (" Variable descriptor %d too complicated. Defined as *void ", spnt
->dbx_type
);
1824 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1828 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1829 Local
[i
++] = Local
[++Lpnt
];
1831 /* we use this for a reference to a structure that has already been defined */
1832 if (struct_number
> 0)
1834 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1836 VMS_Store_Struct (struct_number
);
1838 /* we use this for a forward reference to a structure that has yet to be
1839 *defined. We store four bytes of zero to make room for the actual address once
1842 if (struct_number
< 0)
1844 struct_number
= -struct_number
;
1845 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1847 VMS_Def_Struct (struct_number
);
1848 for (i
= 0; i
< 4; i
++)
1850 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1855 Local
[Lpnt
++] = Asuffix
[i
++];
1857 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1861 /* This routine generates a symbol definition for a C sybmol for the debugger.
1862 * It takes a psect and offset for global symbols - if psect < 0, then this is
1863 * a local variable and the offset is relative to FP. In this case it can
1864 * be either a variable (Offset < 0) or a parameter (Offset > 0).
1867 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1868 struct VMS_DBG_Symbol
*spnt
;
1878 Name_pnt
= fix_name (Name
); /* if there are bad characters in name, convert them */
1880 { /* this is a local variable, referenced to SP */
1881 maxlen
= 7 + strlen (Name_pnt
);
1882 Local
[i
++] = maxlen
;
1883 Local
[i
++] = spnt
->VMS_type
;
1885 Local
[i
++] = DBG_S_C_FUNCTION_PARAMETER
;
1887 Local
[i
++] = DBG_S_C_LOCAL_SYM
;
1888 COPY_LONG (&Local
[i
], Offset
);
1893 maxlen
= 7 + strlen (Name_pnt
); /* symbols fixed in memory */
1894 Local
[i
++] = 7 + strlen (Name_pnt
);
1895 Local
[i
++] = spnt
->VMS_type
;
1897 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1899 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
1901 Local
[i
++] = strlen (Name_pnt
);
1902 while (*Name_pnt
!= '\0')
1903 Local
[i
++] = *Name_pnt
++;
1904 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1905 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1906 generate_suffix (spnt
, 0);
1910 /* This routine parses the stabs entries in order to make the definition
1911 * for the debugger of local symbols and function parameters
1914 VMS_local_stab_Parse (sp
)
1920 struct VMS_DBG_Symbol
*spnt
;
1921 struct VMS_Symbol
*vsp
;
1925 str
= S_GET_NAME (sp
);
1926 pnt
= (char *) strchr (str
, ':');
1927 if (pnt
== (char *) NULL
)
1928 return; /* no colon present */
1929 pnt1
= pnt
++; /* save this for later, and skip colon */
1931 return 0; /* ignore static constants */
1932 /* there is one little catch that we must be aware of. Sometimes function
1933 * parameters are optimized into registers, and the compiler, in its infiite
1934 * wisdom outputs stabs records for *both*. In general we want to use the
1935 * register if it is present, so we must search the rest of the symbols for
1936 * this function to see if this parameter is assigned to a register.
1944 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
1946 if (!S_IS_DEBUG (sp1
))
1948 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
1950 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
1951 if (*pnt3
== 'F' || *pnt3
== 'f') break;
1953 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
1955 str1
= S_GET_NAME (sp1
); /* and get the name */
1957 while (*pnt2
!= ':')
1964 if ((*str1
!= ':') || (*pnt2
!= ':'))
1966 return; /* they are the same! lets skip this one */
1968 /* first find the dbx symbol type from list, and then find VMS type */
1969 pnt
++; /* skip p in case no register */
1972 pnt
= cvt_integer (pnt
, &dbx_type
);
1973 spnt
= find_symbol (dbx_type
);
1974 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1975 return 0; /*Dunno what this is*/
1977 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
1978 *pnt1
= ':'; /* and restore the string */
1982 /* This routine parses a stabs entry to find the information required to define
1983 * a variable. It is used for global and static variables.
1984 * Basically we need to know the address of the symbol. With older versions
1985 * of the compiler, const symbols are
1986 * treated differently, in that if they are global they are written into the
1987 * text psect. The global symbol entry for such a const is actually written
1988 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
1989 * of psects, we must search the entry points as well. static consts are even
1990 * harder, since they are never assigned a memory address. The compiler passes
1991 * a stab to tell us the value, but I am not sure what to do with it.
1995 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
1998 int type1
, type2
, Text_Psect
;
2004 struct VMS_DBG_Symbol
*spnt
;
2005 struct VMS_Symbol
*vsp
;
2009 str
= S_GET_NAME (sp
);
2010 pnt
= (char *) strchr (str
, ':');
2011 if (pnt
== (char *) NULL
)
2012 return; /* no colon present */
2013 pnt1
= pnt
; /* save this for later*/
2015 if (*pnt
== expected_type
)
2017 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2018 spnt
= find_symbol (dbx_type
);
2019 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2020 return 0; /*Dunno what this is*/
2021 /* now we need to search the symbol table to find the psect and offset for
2026 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2028 pnt
= S_GET_NAME (vsp
->Symbol
);
2029 if (pnt
!= (char *) NULL
)
2031 /* make sure name is the same, and make sure correct symbol type */
2032 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2033 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2034 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2038 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2040 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2041 *pnt1
= ':'; /* and restore the string */
2044 /* the symbol was not in the symbol list, but it may be an "entry point"
2045 if it was a constant */
2046 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2049 * Dispatch on STAB type
2051 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2053 pnt
= S_GET_NAME (sp1
);
2056 if (strcmp (pnt
, str
) == 0)
2058 if (!gave_compiler_message
&& expected_type
== 'G')
2060 printf ("***Warning - the assembly code generated by the compiler has placed\n");
2061 printf ("global constant(s) in the text psect. These will not be available to\n");
2062 printf ("other modules, since this is not the correct way to handle this. You\n");
2063 printf ("have two options: 1) get a patched compiler that does not put global\n");
2064 printf ("constants in the text psect, or 2) remove the 'const' keyword from\n");
2065 printf ("definitions of global variables in your source module(s). Don't say\n");
2066 printf ("I didn't warn you!");
2067 gave_compiler_message
= 1;
2069 VMS_DBG_record (spnt
,
2074 *S_GET_NAME (sp1
) = 'L';
2075 /* fool assembler to not output this
2076 * as a routine in the TBT */
2081 *pnt1
= ':'; /* and restore the string */
2086 VMS_GSYM_Parse (sp
, Text_Psect
)
2089 { /* Global variables */
2090 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2095 VMS_LCSYM_Parse (sp
, Text_Psect
)
2098 { /* Static symbols - uninitialized */
2099 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2103 VMS_STSYM_Parse (sp
, Text_Psect
)
2106 { /* Static symbols - initialized */
2107 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2111 /* for register symbols, we must figure out what range of addresses within the
2112 * psect are valid. We will use the brackets in the stab directives to give us
2113 * guidance as to the PC range that this variable is in scope. I am still not
2114 * completely comfortable with this but as I learn more, I seem to get a better
2115 * handle on what is going on.
2119 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2120 symbolS
*sp
, *Current_Routine
;
2127 struct VMS_DBG_Symbol
*spnt
;
2132 int Min_Offset
= -1; /* min PC of validity */
2133 int Max_Offset
= 0; /* max PC of validity */
2135 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2138 * Dispatch on STAB type
2140 switch (S_GET_RAW_TYPE (symbolP
))
2144 Min_Offset
= S_GET_VALUE (symbolP
);
2149 S_GET_VALUE (symbolP
) - 1;
2152 if ((Min_Offset
!= -1) && (bcnt
== 0))
2154 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2156 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2157 if (*pnt
== 'F' || *pnt
== 'f') break;
2160 /* check to see that the addresses were defined. If not, then there were no
2161 * brackets in the function, and we must try to search for the next function
2162 * Since functions can be in any order, we should search all of the symbol list
2163 * to find the correct ending address. */
2164 if (Min_Offset
== -1)
2166 int Max_Source_Offset
;
2168 Min_Offset
= S_GET_VALUE (sp
);
2169 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2172 * Dispatch on STAB type
2174 This_Offset
= S_GET_VALUE (symbolP
);
2175 switch (S_GET_RAW_TYPE (symbolP
))
2177 case N_TEXT
| N_EXT
:
2178 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2179 Max_Offset
= This_Offset
;
2182 if (This_Offset
> Max_Source_Offset
)
2183 Max_Source_Offset
= This_Offset
;
2186 /* if this is the last routine, then we use the PC of the last source line
2187 * as a marker of the max PC for which this reg is valid */
2188 if (Max_Offset
== 0x7fffffff)
2189 Max_Offset
= Max_Source_Offset
;
2192 str
= S_GET_NAME (sp
);
2193 pnt
= (char *) strchr (str
, ':');
2194 if (pnt
== (char *) NULL
)
2195 return; /* no colon present */
2196 pnt1
= pnt
; /* save this for later*/
2200 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2201 spnt
= find_symbol (dbx_type
);
2202 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2203 return 0; /*Dunno what this is yet*/
2205 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2206 maxlen
= 25 + strlen (pnt
);
2207 Local
[i
++] = maxlen
;
2208 Local
[i
++] = spnt
->VMS_type
;
2210 Local
[i
++] = strlen (pnt
) + 1;
2214 Local
[i
++] = strlen (pnt
);
2215 while (*pnt
!= '\0')
2216 Local
[i
++] = *pnt
++;
2222 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2224 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2225 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2227 Local
[i
++] = S_GET_VALUE (sp
);
2231 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2233 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2234 generate_suffix (spnt
, 0);
2237 /* this function examines a structure definition, checking all of the elements
2238 * to make sure that all of them are fully defined. The only thing that we
2239 * kick out are arrays of undefined structs, since we do not know how big
2240 * they are. All others we can handle with a normal forward reference.
2243 forward_reference (pnt
)
2247 struct VMS_DBG_Symbol
*spnt
;
2248 struct VMS_DBG_Symbol
*spnt1
;
2249 pnt
= cvt_integer (pnt
+ 1, &i
);
2251 return 0; /* no forward references */
2254 pnt
= (char *) strchr (pnt
, ':');
2255 pnt
= cvt_integer (pnt
+ 1, &i
);
2256 spnt
= find_symbol (i
);
2257 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2258 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2261 spnt1
= find_symbol (spnt
->type2
);
2262 if ((spnt
->advanced
== ARRAY
) &&
2263 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2265 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2270 pnt
= cvt_integer (pnt
+ 1, &i
);
2271 pnt
= cvt_integer (pnt
+ 1, &i
);
2272 } while (*++pnt
!= ';');
2273 return 0; /* no forward refences found */
2276 /* Used to check a single element of a structure on the final pass*/
2279 final_forward_reference (spnt
)
2280 struct VMS_DBG_Symbol
* spnt
;
2282 struct VMS_DBG_Symbol
* spnt1
;
2283 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2284 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
2285 spnt1
= find_symbol(spnt
->type2
);
2286 if((spnt
->advanced
== ARRAY
) &&
2287 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
2288 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
2292 return 0; /* no forward refences found */
2295 /* This routine parses the stabs directives to find any definitions of dbx type
2296 * numbers. It makes a note of all of them, creating a structure element
2297 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2298 * debugger that describes the struct/union/enum, so that further references
2299 * to these data types will be by number
2300 * We have to process pointers right away, since there can be references
2301 * to them later in the same stabs directive. We cannot have forward
2302 * references to pointers, (but we can have a forward reference to a pointer to
2303 * a structure/enum/union) and this is why we process them immediately.
2304 * After we process the pointer, then we search for defs that are nested even
2306 * 8/15/92: We have to process arrays right away too, because there can
2307 * be multiple references to identical array types in one structure
2308 * definition, and only the first one has the definition. (We tend to
2309 * parse from the back going forward.
2312 VMS_typedef_parse (str
)
2320 struct forward_ref
*fpnt
;
2322 int convert_integer
;
2323 struct VMS_DBG_Symbol
*spnt
;
2324 struct VMS_DBG_Symbol
*spnt1
;
2325 /* check for any nested def's */
2326 pnt
= (char *) strchr (str
+ 1, '=');
2327 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2328 && (str
[1] != 'a' || str
[2] != 'r'))
2329 if (VMS_typedef_parse (pnt
) == 1)
2331 /* now find dbx_type of entry */
2334 { /* check for static constants */
2335 *str
= '\0'; /* for now we ignore them */
2338 while ((*pnt
<= '9') && (*pnt
>= '0'))
2340 pnt
++; /* and get back to the number */
2341 cvt_integer (pnt
, &i1
);
2342 spnt
= find_symbol (i1
);
2343 /* first we see if this has been defined already, due to a forward reference*/
2344 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2346 if (VMS_Symbol_type_list
== (struct VMS_DBG_Symbol
*) NULL
)
2348 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2349 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
2350 VMS_Symbol_type_list
= spnt
;
2354 spnt
= (struct VMS_DBG_Symbol
*) malloc (sizeof (struct VMS_DBG_Symbol
));
2355 spnt
->next
= VMS_Symbol_type_list
;
2356 VMS_Symbol_type_list
= spnt
;
2358 spnt
->dbx_type
= i1
; /* and save the type */
2360 /* for structs and unions, do a partial parse, otherwise we sometimes get
2361 * circular definitions that are impossible to resolve. We read enough info
2362 * so that any reference to this type has enough info to be resolved
2364 pnt
= str
+ 1; /* point to character past equal sign */
2365 if ((*pnt
== 'u') || (*pnt
== 's'))
2368 if ((*pnt
<= '9') && (*pnt
>= '0'))
2370 if (type_check ("void"))
2371 { /* this is the void symbol */
2373 spnt
->advanced
= VOID
;
2376 if (type_check ("unknown type"))
2377 { /* this is the void symbol */
2379 spnt
->advanced
= UNKNOWN
;
2382 pnt1
= cvt_integer(pnt
,&i1
);
2383 if(i1
!= spnt
->dbx_type
)
2385 spnt
->advanced
= ALIAS
;
2390 printf ("gcc-as warning(debugger output):");
2391 printf (" %d is an unknown untyped variable.\n", spnt
->dbx_type
);
2392 return 1; /* do not know what this is */
2394 /* now define this module*/
2395 pnt
= str
+ 1; /* point to character past equal sign */
2399 spnt
->advanced
= BASIC
;
2400 if (type_check ("int"))
2402 spnt
->VMS_type
= DBG_S_C_SLINT
;
2403 spnt
->data_size
= 4;
2405 else if (type_check ("long int"))
2407 spnt
->VMS_type
= DBG_S_C_SLINT
;
2408 spnt
->data_size
= 4;
2410 else if (type_check ("unsigned int"))
2412 spnt
->VMS_type
= DBG_S_C_ULINT
;
2413 spnt
->data_size
= 4;
2415 else if (type_check ("long unsigned int"))
2417 spnt
->VMS_type
= DBG_S_C_ULINT
;
2418 spnt
->data_size
= 4;
2420 else if (type_check ("short int"))
2422 spnt
->VMS_type
= DBG_S_C_SSINT
;
2423 spnt
->data_size
= 2;
2425 else if (type_check ("short unsigned int"))
2427 spnt
->VMS_type
= DBG_S_C_USINT
;
2428 spnt
->data_size
= 2;
2430 else if (type_check ("char"))
2432 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2433 spnt
->data_size
= 1;
2435 else if (type_check ("signed char"))
2437 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2438 spnt
->data_size
= 1;
2440 else if (type_check ("unsigned char"))
2442 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2443 spnt
->data_size
= 1;
2445 else if (type_check ("float"))
2447 spnt
->VMS_type
= DBG_S_C_REAL4
;
2448 spnt
->data_size
= 4;
2450 else if (type_check ("double"))
2452 spnt
->VMS_type
= DBG_S_C_REAL8
;
2453 spnt
->data_size
= 8;
2455 pnt1
= (char *) strchr (str
, ';') + 1;
2460 spnt
->advanced
= STRUCT
;
2462 spnt
->advanced
= UNION
;
2463 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2464 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2465 if (!final_pass
&& forward_reference(pnt
))
2467 spnt
->struc_numb
= -1;
2470 spnt
->struc_numb
= ++structure_count
;
2472 pnt
= get_struct_name (str
);
2473 VMS_Def_Struct (spnt
->struc_numb
);
2475 while (fpnt
!= (struct forward_ref
*) NULL
)
2477 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2479 fpnt
->resolved
= 'Y';
2480 VMS_Set_Struct (fpnt
->struc_numb
);
2481 VMS_Store_Struct (spnt
->struc_numb
);
2485 VMS_Set_Struct (spnt
->struc_numb
);
2487 Local
[i
++] = 11 + strlen (pnt
);
2488 Local
[i
++] = DBG_S_C_STRUCT_START
;
2490 for (i1
= 0; i1
< 4; i1
++)
2492 Local
[i
++] = strlen (pnt
);
2494 while (*pnt2
!= '\0')
2495 Local
[i
++] = *pnt2
++;
2496 i2
= spnt
->data_size
* 8; /* number of bits */
2497 COPY_LONG(&Local
[i
], i2
);
2499 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2501 if (pnt
!= symbol_name
)
2503 pnt
+= strlen (pnt
);
2505 }; /* replace colon for later */
2506 while (*++pnt1
!= ';')
2508 pnt
= (char *) strchr (pnt1
, ':');
2511 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2512 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2513 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2514 if ((dtype
== 1) && (i3
!= 32))
2517 push (19 + strlen (pnt2
), 1);
2519 push (1 + strlen (pnt2
), 4);
2520 push (strlen (pnt2
), 1);
2521 while (*pnt2
!= '\0')
2523 push (i3
, 2); /* size of bitfield */
2526 push (i2
, 4); /* start position */
2527 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2532 Local
[i
++] = 7 + strlen (pnt2
);
2533 spnt1
= find_symbol (dtype
);
2534 /* check if this is a forward reference */
2535 if(final_pass
&& final_forward_reference(spnt1
))
2537 printf("gcc-as warning(debugger output):");
2538 printf("structure element %s has undefined type\n",pnt2
);
2542 if (spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
2543 Local
[i
++] = spnt1
->VMS_type
;
2545 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
;
2546 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2547 COPY_LONG (&Local
[i
], i2
);
2549 Local
[i
++] = strlen (pnt2
);
2550 while (*pnt2
!= '\0')
2551 Local
[i
++] = *pnt2
++;
2552 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2554 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2555 generate_suffix (spnt1
, dtype
);
2556 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2557 generate_suffix (spnt1
, 0);
2561 Local
[i
++] = 0x01; /* length byte */
2562 Local
[i
++] = DBG_S_C_STRUCT_END
;
2563 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2567 spnt
->advanced
= ENUM
;
2568 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2569 spnt
->struc_numb
= ++structure_count
;
2570 spnt
->data_size
= 4;
2571 VMS_Def_Struct (spnt
->struc_numb
);
2573 while (fpnt
!= (struct forward_ref
*) NULL
)
2575 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2577 fpnt
->resolved
= 'Y';
2578 VMS_Set_Struct (fpnt
->struc_numb
);
2579 VMS_Store_Struct (spnt
->struc_numb
);
2583 VMS_Set_Struct (spnt
->struc_numb
);
2585 Local
[i
++] = 3 + strlen (symbol_name
);
2586 Local
[i
++] = DBG_S_C_ENUM_START
;
2588 Local
[i
++] = strlen (symbol_name
);
2590 while (*pnt2
!= '\0')
2591 Local
[i
++] = *pnt2
++;
2592 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2594 while (*++pnt
!= ';')
2596 pnt1
= (char *) strchr (pnt
, ':');
2598 pnt1
= cvt_integer (pnt1
, &i1
);
2599 Local
[i
++] = 7 + strlen (pnt
);
2600 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2602 COPY_LONG (&Local
[i
], i1
);
2604 Local
[i
++] = strlen (pnt
);
2606 while (*pnt
!= '\0')
2607 Local
[i
++] = *pnt
++;
2608 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2610 pnt
= pnt1
; /* Skip final semicolon */
2612 Local
[i
++] = 0x01; /* len byte */
2613 Local
[i
++] = DBG_S_C_ENUM_END
;
2614 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2619 spnt
->advanced
= ARRAY
;
2620 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2621 pnt
= (char *) strchr (pnt
, ';');
2622 if (pnt
== (char *) NULL
)
2624 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2625 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2626 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2627 pnt
=(char*)strchr(str
+1,'=');
2628 if((pnt
!= (char*) NULL
))
2629 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
2632 spnt
->advanced
= FUNCTION
;
2633 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2634 /* this masquerades as a basic type*/
2635 spnt
->data_size
= 4;
2636 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2639 spnt
->advanced
= POINTER
;
2640 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2641 spnt
->data_size
= 4;
2642 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2643 pnt
= (char *) strchr (str
+ 1, '=');
2644 if ((pnt
!= (char *) NULL
))
2645 if (VMS_typedef_parse (pnt
) == 1)
2649 spnt
->advanced
= UNKNOWN
;
2651 printf ("gcc-as warning(debugger output):");
2652 printf (" %d is an unknown type of variable.\n", spnt
->dbx_type
);
2653 return 1; /* unable to decipher */
2655 /* this removes the evidence of the definition so that the outer levels of
2656 parsing do not have to worry about it */
2658 while (*pnt1
!= '\0')
2666 * This is the root routine that parses the stabs entries for definitions.
2667 * it calls VMS_typedef_parse, which can in turn call itself.
2668 * We need to be careful, since sometimes there are forward references to
2669 * other symbol types, and these cannot be resolved until we have completed
2672 * Also check and see if we are using continuation stabs, if we are, then
2673 * paste together the entire contents of the stab before we pass it to
2674 * VMS_typedef_parse.
2683 char *parse_buffer
= 0;
2685 int incomplete
, i
, pass
, incom1
;
2686 struct VMS_DBG_Symbol
*spnt
;
2687 struct VMS_Symbol
*vsp
;
2688 struct forward_ref
*fpnt
;
2695 incom1
= incomplete
;
2697 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2700 * Deal with STAB symbols
2702 if (S_IS_DEBUG (sp
))
2705 * Dispatch on STAB type
2707 switch (S_GET_RAW_TYPE (sp
))
2715 case N_FUN
: /*sometimes these contain typedefs*/
2716 str
= S_GET_NAME (sp
);
2718 pnt
= str
+ strlen(str
) -1;
2719 if (*pnt
== '?') /* Continuation stab. */
2725 tlen
+= strlen(str
) - 1;
2726 spnext
= symbol_next (spnext
);
2727 str
= S_GET_NAME (spnext
);
2728 pnt
= str
+ strlen(str
) - 1;
2729 } while (*pnt
== '?');
2730 tlen
+= strlen(str
);
2731 parse_buffer
= (char *) malloc (tlen
+ 1);
2732 strcpy(parse_buffer
, S_GET_NAME (sp
));
2733 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
2737 spnext
= symbol_next (spnext
);
2738 str
= S_GET_NAME (spnext
);
2739 strcat (pnt2
, S_GET_NAME (spnext
));
2740 pnt2
+= strlen(str
) - 1;
2741 *str
= '\0'; /* Erase this string */
2742 if (*pnt2
!= '?') break;
2748 pnt
= (char *) strchr (str
, ':');
2749 if (pnt
!= (char *) NULL
)
2753 pnt2
= (char *) strchr (pnt1
, '=');
2754 if (pnt2
!= (char *) NULL
)
2755 incomplete
+= VMS_typedef_parse (pnt2
);
2757 /* At this point the parse buffer should just contain name:nn.
2758 If it does not, then we are in real trouble. Anyway,
2759 this is always shorter than the original line. */
2760 strcpy(S_GET_NAME (sp
), parse_buffer
);
2761 free (parse_buffer
);
2764 *pnt
= ':'; /* put back colon so variable def code finds dbx_type*/
2771 /* Make one last pass, if needed, and define whatever we can that is left */
2772 if(final_pass
== 0 && incomplete
== incom1
)
2775 incom1
++; /* Force one last pass through */
2777 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
2778 /* repeat until all refs resolved if possible */
2779 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
2780 if (incomplete
!= 0)
2782 printf ("gcc-as warning(debugger output):");
2783 printf ("Unable to resolve %d circular references.\n", incomplete
);
2787 while (fpnt
!= (struct forward_ref
*) NULL
)
2789 if (fpnt
->resolved
!= 'Y')
2791 if (find_symbol (fpnt
->dbx_type
) !=
2792 (struct VMS_DBG_Symbol
*) NULL
)
2794 printf ("gcc-as warning(debugger output):");
2795 printf ("Forward reference error, dbx type %d\n",
2800 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2801 pnt2
= (char *) strchr (&fixit
[1], '=');
2802 VMS_typedef_parse (pnt2
);
2809 Define_Local_Symbols (s1
, s2
)
2813 for (symbolP1
= symbol_next (s1
); symbolP1
!= s2
; symbolP1
= symbol_next (symbolP1
))
2815 if (symbolP1
== (symbolS
*) NULL
)
2817 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2819 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2820 if (*pnt
== 'F' || *pnt
== 'f') break;
2823 * Deal with STAB symbols
2825 if (S_IS_DEBUG (symbolP1
))
2828 * Dispatch on STAB type
2830 switch (S_GET_RAW_TYPE (symbolP1
))
2834 VMS_local_stab_Parse (symbolP1
);
2837 VMS_RSYM_Parse (symbolP1
, Current_Routine
, Text_Psect
);
2845 /* This function crawls the symbol chain searching for local symbols that need
2846 * to be described to the debugger. When we enter a new scope with a "{", it
2847 * creates a new "block", which helps the debugger keep track of which scope
2848 * we are currently in.
2852 Define_Routine (symbolP
, Level
)
2862 for (symbolP1
= symbol_next (symbolP
); symbolP1
; symbolP1
= symbol_next (symbolP1
))
2864 if (S_GET_RAW_TYPE (symbolP1
) == N_FUN
)
2866 char * pnt
=(char*) strchr (S_GET_NAME (symbolP1
), ':') + 1;
2867 if (*pnt
== 'F' || *pnt
== 'f') break;
2870 * Deal with STAB symbols
2872 if (S_IS_DEBUG (symbolP1
))
2875 * Dispatch on STAB type
2877 switch (S_GET_RAW_TYPE (symbolP1
))
2882 sprintf (str
, "$%d", rcount
++);
2883 VMS_TBT_Block_Begin (symbolP1
, Text_Psect
, str
);
2885 Offset
= S_GET_VALUE (symbolP1
);
2886 Define_Local_Symbols (sstart
, symbolP1
);
2888 Define_Routine (symbolP1
, Level
+ 1);
2890 VMS_TBT_Block_End (S_GET_VALUE (symbolP1
) -
2899 /* we end up here if there were no brackets in this function. Define
2901 Define_Local_Symbols (sstart
, (symbolS
*) 0);
2907 VMS_DBG_Define_Routine (symbolP
, Curr_Routine
, Txt_Psect
)
2909 symbolS
*Curr_Routine
;
2912 Current_Routine
= Curr_Routine
;
2913 Text_Psect
= Txt_Psect
;
2914 Define_Routine (symbolP
, 0);
2921 #include <sys/types.h>
2924 /* Manufacure a VMS like time on a unix based system. */
2925 get_VMS_time_on_unix (Now
)
2931 pnt
= ctime (&timeb
);
2937 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
2940 #endif /* not HO_VMS */
2942 * Write the MHD (Module Header) records
2945 Write_VMS_MHD_Records ()
2947 register char *cp
, *cp1
;
2954 char Module_Name
[256];
2958 * We are writing a module header record
2960 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
2962 * ***************************
2963 * *MAIN MODULE HEADER RECORD*
2964 * ***************************
2966 * Store record type and header type
2968 PUT_CHAR (OBJ_S_C_HDR
);
2969 PUT_CHAR (MHD_S_C_MHD
);
2971 * Structure level is 0
2973 PUT_CHAR (OBJ_S_C_STRLVL
);
2975 * Maximum record size is size of the object record buffer
2977 PUT_SHORT (sizeof (Object_Record_Buffer
));
2979 * Get module name (the FILENAME part of the object file)
2985 if ((*cp
== ']') || (*cp
== '>') ||
2986 (*cp
== ':') || (*cp
== '/'))
2992 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
2996 * Limit it to 31 characters and store in the object record
2998 while (--cp1
>= Module_Name
)
3001 if (strlen (Module_Name
) > 31)
3004 printf ("%s: Module name truncated: %s\n", myname
, Module_Name
);
3005 Module_Name
[31] = 0;
3007 PUT_COUNTED_STRING (Module_Name
);
3009 * Module Version is "V1.0"
3011 PUT_COUNTED_STRING ("V1.0");
3013 * Creation time is "now" (17 chars of time string)
3016 get_VMS_time_on_unix (&Now
[0]);
3018 Descriptor
.Size
= 17;
3019 Descriptor
.Ptr
= Now
;
3020 sys$
asctim (0, &Descriptor
, 0, 0);
3022 for (i
= 0; i
< 17; i
++)
3025 * Patch time is "never" (17 zeros)
3027 for (i
= 0; i
< 17; i
++)
3032 Flush_VMS_Object_Record_Buffer ();
3034 * *************************
3035 * *LANGUAGE PROCESSOR NAME*
3036 * *************************
3038 * Store record type and header type
3040 PUT_CHAR (OBJ_S_C_HDR
);
3041 PUT_CHAR (MHD_S_C_LNM
);
3043 * Store language processor name and version
3044 * (not a counted string!)
3046 cp
= compiler_version_string
;
3052 cp
= strchr (GAS_VERSION
, '.');
3062 Flush_VMS_Object_Record_Buffer ();
3067 * Write the EOM (End Of Module) record
3070 Write_VMS_EOM_Record (Psect
, Offset
)
3075 * We are writing an end-of-module record
3077 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3081 PUT_CHAR (OBJ_S_C_EOM
);
3083 * Store the error severity (0)
3087 * Store the entry point, if it exists
3092 * Store the entry point Psect
3096 * Store the entry point Psect offset
3103 Flush_VMS_Object_Record_Buffer ();
3107 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3113 register unsigned char *p
= ptr
;
3114 register unsigned char *end
= p
+ strlen (ptr
);
3115 register unsigned char c
;
3116 register int hash
= 0;
3121 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3127 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3130 VMS_Case_Hack_Symbol (In
, Out
)
3140 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3142 int Case_Hack_Bits
= 0;
3144 static char Hex_Table
[16] =
3145 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3148 * Kill any leading "_"
3150 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3153 new_name
= Out
; /* save this for later*/
3155 #if barfoo /* Dead code */
3156 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3160 /* We may need to truncate the symbol, save the hash for later*/
3161 if (strlen (In
) > 23)
3162 result
= hash_string (In
);
3164 * Is there a Psect Attribute to skip??
3166 if (HAS_PSECT_ATTRIBUTES (In
))
3171 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3174 if ((In
[0] == '$') && (In
[1] == '$'))
3184 /* if (strlen(In) > 31 && flagseen['+'])
3185 printf("%s: Symbol name truncated: %s\n",myname,In);*/
3187 * Do the case conversion
3189 i
= 23; /* Maximum of 23 chars */
3190 while (*In
&& (--i
>= 0))
3192 Case_Hack_Bits
<<= 1;
3195 if ((destructor
== 1) && (i
== 21))
3197 switch (vms_name_mapping
)
3202 Case_Hack_Bits
|= 1;
3204 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3207 case 3: *Out
++ = *In
++;
3213 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3219 * If we saw a dollar sign, we don't do case hacking
3221 if (flagseen
['h'] || Saw_Dollar
)
3225 * If we have more than 23 characters and everything is lowercase
3226 * we can insert the full 31 characters
3231 * We have more than 23 characters
3232 * If we must add the case hack, then we have truncated the str
3236 if (Case_Hack_Bits
== 0)
3239 * And so far they are all lower case:
3240 * Check up to 8 more characters
3241 * and ensure that they are lowercase
3243 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3244 if (isupper(In
[i
]) && !Saw_Dollar
&& !flagseen
['h'])
3250 if ((i
== 8) || (In
[i
] == 0))
3253 * They are: Copy up to 31 characters
3254 * to the output string
3257 while ((--i
>= 0) && (*In
))
3258 switch (vms_name_mapping
){
3259 case 0: *Out
++ = islower(*In
) ?
3263 case 3: *Out
++ = *In
++;
3265 case 2: *Out
++ = isupper(*In
) ?
3274 * If there were any uppercase characters in the name we
3275 * take on the case hacking string
3278 /* Old behavior for regular GNU-C compiler */
3281 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3286 for (i
= 0; i
< 6; i
++)
3288 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3289 Case_Hack_Bits
>>= 4;
3295 Out
= pnt
; /*Cut back to 23 characters maximum */
3297 for (i
= 0; i
< 7; i
++)
3299 init
= result
& 0x01f;
3301 *Out
++ = '0' + init
;
3303 *Out
++ = 'A' + init
- 10;
3304 result
= result
>> 5;
3312 if (truncate
== 1 && flagseen
['+'] && flagseen
['H'])
3313 printf ("%s: Symbol %s replaced by %s\n", myname
, old_name
, new_name
);
3318 * Scan a symbol name for a psect attribute specification
3320 #define GLOBALSYMBOL_BIT 0x10000
3321 #define GLOBALVALUE_BIT 0x20000
3325 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3327 int *Attribute_Pointer
;
3338 {"PIC", GPS_S_M_PIC
},
3339 {"LIB", GPS_S_M_LIB
},
3340 {"OVR", GPS_S_M_OVR
},
3341 {"REL", GPS_S_M_REL
},
3342 {"GBL", GPS_S_M_GBL
},
3343 {"SHR", GPS_S_M_SHR
},
3344 {"EXE", GPS_S_M_EXE
},
3346 {"WRT", GPS_S_M_WRT
},
3347 {"VEC", GPS_S_M_VEC
},
3348 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3349 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3359 * Check for a PSECT attribute list
3361 if (!HAS_PSECT_ATTRIBUTES (Name
))
3362 return; /* If not, return */
3364 * Skip the attribute list indicator
3366 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3368 * Process the attributes ("_" separated, "$" terminated)
3370 while (*Name
!= '$')
3373 * Assume not negating
3379 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3382 * We are negating (and skip the NO)
3388 * Find the token delimiter
3391 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3394 * Look for the token in the attribute list
3396 for (i
= 0; Attributes
[i
].Name
; i
++)
3399 * If the strings match, set/clear the attr.
3401 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3407 *Attribute_Pointer
&=
3408 ~Attributes
[i
].Value
;
3410 *Attribute_Pointer
|=
3411 Attributes
[i
].Value
;
3419 * Now skip the attribute
3429 * Define a global symbol
3432 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Defined
)
3440 * We are writing a GSD record
3442 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3444 * If the buffer is empty we must insert the GSD record type
3446 if (Object_Record_Offset
== 0)
3447 PUT_CHAR (OBJ_S_C_GSD
);
3449 * We are writing a Global symbol definition subrecord
3451 if (Psect_Number
<= 255)
3453 PUT_CHAR (GSD_S_C_SYM
);
3457 PUT_CHAR (GSD_S_C_SYMW
);
3460 * Data type is undefined
3464 * Switch on Definition/Reference
3466 if ((Defined
& 1) != 0)
3470 * Flags = "RELOCATABLE" and "DEFINED" for regular symbol
3471 * = "DEFINED" for globalvalue (Defined & 2 == 1)
3473 if ((Defined
& 2) == 0)
3475 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3479 PUT_SHORT (GSY_S_M_DEF
);
3484 if (Psect_Number
<= 255)
3486 PUT_CHAR (Psect_Number
);
3490 PUT_SHORT (Psect_Number
);
3495 PUT_LONG (Psect_Offset
);
3501 * Flags = "RELOCATABLE" for regular symbol,
3502 * = "" for globalvalue (Defined & 2 == 1)
3504 if ((Defined
& 2) == 0)
3506 PUT_SHORT (GSY_S_M_REL
);
3514 * Finally, the global symbol name
3516 VMS_Case_Hack_Symbol (Name
, Local
);
3517 PUT_COUNTED_STRING (Local
);
3519 * Flush the buffer if it is more than 75% full
3521 if (Object_Record_Offset
>
3522 (sizeof (Object_Record_Buffer
) * 3 / 4))
3523 Flush_VMS_Object_Record_Buffer ();
3531 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3535 struct VMS_Symbol
*vsp
;
3538 int Psect_Attributes
;
3541 * Generate the appropriate PSECT flags given the PSECT type
3543 if (strcmp (Type
, "COMMON") == 0)
3546 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3548 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3549 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3551 else if (strcmp (Type
, "CONST") == 0)
3554 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3556 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3557 GPS_S_M_SHR
| GPS_S_M_RD
);
3559 else if (strcmp (Type
, "DATA") == 0)
3562 * The Data psects are PIC,REL,RD,WRT
3565 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3567 else if (strcmp (Type
, "TEXT") == 0)
3570 * The Text psects are PIC,REL,SHR,EXE,RD
3573 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3574 GPS_S_M_EXE
| GPS_S_M_RD
);
3579 * Error: Unknown psect type
3581 error ("Unknown VMS psect type");
3584 * Modify the psect attributes according to any attribute string
3586 if (HAS_PSECT_ATTRIBUTES (Name
))
3587 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3589 * Check for globalref/def/val.
3591 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3594 * globalvalue symbols were generated before. This code
3595 * prevents unsightly psect buildup, and makes sure that
3596 * fixup references are emitted correctly.
3598 vsp
->Psect_Index
= -1; /* to catch errors */
3599 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
; /* make refs work */
3600 return 1; /* decrement psect counter */
3603 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3605 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3607 case N_UNDF
| N_EXT
:
3608 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3609 vsp
->Psect_Offset
, 0);
3610 vsp
->Psect_Index
= -1;
3611 S_GET_RAW_TYPE (vsp
->Symbol
) = N_UNDF
;
3612 return 1; /* return and indicate no psect */
3613 case N_DATA
| N_EXT
:
3614 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3615 vsp
->Psect_Offset
, 1);
3616 /* In this case we still generate the psect */
3620 char Error_Line
[256];
3621 sprintf (Error_Line
,
3622 "Globalsymbol attribute for symbol %s was unexpected.\n",
3630 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3632 * We are writing a GSD record
3634 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3636 * If the buffer is empty we must insert the GSD record type
3638 if (Object_Record_Offset
== 0)
3639 PUT_CHAR (OBJ_S_C_GSD
);
3641 * We are writing a PSECT definition subrecord
3643 PUT_CHAR (GSD_S_C_PSC
);
3645 * Psects are always LONGWORD aligned
3649 * Specify the psect attributes
3651 PUT_SHORT (Psect_Attributes
);
3653 * Specify the allocation
3657 * Finally, the psect name
3659 VMS_Case_Hack_Symbol (Name
, Local
);
3660 PUT_COUNTED_STRING (Local
);
3662 * Flush the buffer if it is more than 75% full
3664 if (Object_Record_Offset
>
3665 (sizeof (Object_Record_Buffer
) * 3 / 4))
3666 Flush_VMS_Object_Record_Buffer ();
3672 * Given the pointer to a symbol we calculate how big the data at the
3673 * symbol is. We do this by looking for the next symbol (local or
3674 * global) which will indicate the start of another datum.
3677 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3678 register struct symbol
*sp
;
3681 register struct symbol
*sp1
, *Next_Symbol
;
3684 * Find the next symbol
3685 * it delimits this datum
3688 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3691 * The data type must match
3693 if (S_GET_TYPE (sp1
) != N_DATA
)
3696 * The symbol must be AFTER this symbol
3698 if (S_GET_VALUE (sp1
) <= S_GET_VALUE (sp
))
3701 * We ignore THIS symbol
3706 * If there is already a candidate selected for the
3707 * next symbol, see if we are a better candidate
3712 * We are a better candidate if we are "closer"
3715 if (S_GET_VALUE (sp1
) >
3716 S_GET_VALUE (Next_Symbol
))
3719 * Win: Make this the candidate
3726 * This is the 1st candidate
3732 * Calculate its size
3734 return (Next_Symbol
?
3735 (S_GET_VALUE (Next_Symbol
) -
3737 (End_Of_Data
- S_GET_VALUE (sp
)));
3741 * Check symbol names for the Psect hack with a globalvalue, and then
3742 * generate globalvalues for those that have it.
3745 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3750 register symbolS
*sp
;
3751 char *stripped_name
, *Name
;
3753 int Psect_Attributes
;
3757 * Scan the symbol table for globalvalues, and emit def/ref when
3758 * required. These will be caught again later and converted to
3761 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3764 * See if this is something we want to look at.
3766 if ((S_GET_RAW_TYPE (sp
) != (N_DATA
| N_EXT
)) &&
3767 (S_GET_RAW_TYPE (sp
) != (N_UNDF
| N_EXT
)))
3770 * See if this has globalvalue specification.
3772 Name
= S_GET_NAME (sp
);
3774 if (!HAS_PSECT_ATTRIBUTES (Name
))
3777 stripped_name
= (char *) malloc (strlen (Name
) + 1);
3778 strcpy (stripped_name
, Name
);
3779 Psect_Attributes
= 0;
3780 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3782 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3784 switch (S_GET_RAW_TYPE (sp
))
3786 case N_UNDF
| N_EXT
:
3787 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3789 case N_DATA
| N_EXT
:
3790 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3792 error ("Invalid data type for globalvalue");
3793 globalvalue
= md_chars_to_number (Data_Segment
+
3794 S_GET_VALUE (sp
) - text_siz
, Size
);
3795 /* Three times for good luck. The linker seems to get confused
3796 if there are fewer than three */
3797 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, 2);
3798 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3799 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
, 3);
3802 printf (" Invalid globalvalue of %s\n", stripped_name
);
3806 free (stripped_name
); /* clean up */
3813 * Define a procedure entry pt/mask
3816 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3825 * We are writing a GSD record
3827 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3829 * If the buffer is empty we must insert the GSD record type
3831 if (Object_Record_Offset
== 0)
3832 PUT_CHAR (OBJ_S_C_GSD
);
3834 * We are writing a Procedure Entry Pt/Mask subrecord
3836 if (Psect_Number
<= 255)
3838 PUT_CHAR (GSD_S_C_EPM
);
3842 PUT_CHAR (GSD_S_C_EPMW
);
3845 * Data type is undefined
3849 * Flags = "RELOCATABLE" and "DEFINED"
3851 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3855 if (Psect_Number
<= 255)
3857 PUT_CHAR (Psect_Number
);
3861 PUT_SHORT (Psect_Number
);
3866 PUT_LONG (Psect_Offset
);
3870 PUT_SHORT (Entry_Mask
);
3872 * Finally, the global symbol name
3874 VMS_Case_Hack_Symbol (Name
, Local
);
3875 PUT_COUNTED_STRING (Local
);
3877 * Flush the buffer if it is more than 75% full
3879 if (Object_Record_Offset
>
3880 (sizeof (Object_Record_Buffer
) * 3 / 4))
3881 Flush_VMS_Object_Record_Buffer ();
3886 * Set the current location counter to a particular Psect and Offset
3889 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
3895 * We are writing a "Record_Type" record
3897 Set_VMS_Object_File_Record (Record_Type
);
3899 * If the buffer is empty we must insert the record type
3901 if (Object_Record_Offset
== 0)
3902 PUT_CHAR (Record_Type
);
3904 * Stack the Psect base + Longword Offset
3906 if (Psect_Index
< 255)
3908 PUT_CHAR (TIR_S_C_STA_PL
);
3909 PUT_CHAR (Psect_Index
);
3913 PUT_CHAR (TIR_S_C_STA_WPL
);
3914 PUT_SHORT (Psect_Index
);
3918 * Set relocation base
3920 PUT_CHAR (TIR_S_C_CTL_SETRB
);
3922 * Flush the buffer if it is more than 75% full
3924 if (Object_Record_Offset
>
3925 (sizeof (Object_Record_Buffer
) * 3 / 4))
3926 Flush_VMS_Object_Record_Buffer ();
3931 * Store repeated immediate data in current Psect
3934 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
3936 register char *Pointer
;
3942 * Ignore zero bytes/words/longwords
3944 if ((Size
== sizeof (char)) && (*Pointer
== 0))
3946 if ((Size
== sizeof (short)) && (*(short *) Pointer
== 0))
3948 if ((Size
== sizeof (long)) && (*(long *) Pointer
== 0))
3951 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
3952 * then we do it manually
3956 while (--Repeat_Count
>= 0)
3957 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
3961 * We are writing a "Record_Type" record
3963 Set_VMS_Object_File_Record (Record_Type
);
3965 * If the buffer is empty we must insert record type
3967 if (Object_Record_Offset
== 0)
3968 PUT_CHAR (Record_Type
);
3970 * Stack the repeat count
3972 PUT_CHAR (TIR_S_C_STA_LW
);
3973 PUT_LONG (Repeat_Count
);
3975 * And now the command and its data
3977 PUT_CHAR (TIR_S_C_STO_RIVB
);
3980 PUT_CHAR (*Pointer
++);
3982 * Flush the buffer if it is more than 75% full
3984 if (Object_Record_Offset
>
3985 (sizeof (Object_Record_Buffer
) * 3 / 4))
3986 Flush_VMS_Object_Record_Buffer ();
3991 * Store a Position Independent Reference
3994 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
3995 Psect
, Psect_Offset
, Record_Type
)
3996 struct symbol
*Symbol
;
4003 register struct VMS_Symbol
*vsp
=
4004 (struct VMS_Symbol
*) (Symbol
->sy_number
);
4008 * We are writing a "Record_Type" record
4010 Set_VMS_Object_File_Record (Record_Type
);
4012 * If the buffer is empty we must insert record type
4014 if (Object_Record_Offset
== 0)
4015 PUT_CHAR (Record_Type
);
4017 * Set to the appropriate offset in the Psect
4022 * For a Code reference we need to fix the operand
4023 * specifier as well (so back up 1 byte)
4025 VMS_Set_Psect (Psect
, Psect_Offset
- 1, Record_Type
);
4030 * For a Data reference we just store HERE
4032 VMS_Set_Psect (Psect
, Psect_Offset
, Record_Type
);
4035 * Make sure we are still generating a "Record Type" record
4037 if (Object_Record_Offset
== 0)
4038 PUT_CHAR (Record_Type
);
4040 * Dispatch on symbol type (so we can stack its value)
4042 switch (S_GET_RAW_TYPE (Symbol
))
4047 #ifdef NOT_VAX_11_C_COMPATIBLE
4048 case N_UNDF
| N_EXT
:
4049 case N_DATA
| N_EXT
:
4050 #endif /* NOT_VAX_11_C_COMPATIBLE */
4052 case N_TEXT
| N_EXT
:
4054 * Get the symbol name (case hacked)
4056 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4058 * Stack the global symbol value
4060 PUT_CHAR (TIR_S_C_STA_GBL
);
4061 PUT_COUNTED_STRING (Local
);
4065 * Stack the longword offset
4067 PUT_CHAR (TIR_S_C_STA_LW
);
4070 * Add the two, leaving the result on the stack
4072 PUT_CHAR (TIR_S_C_OPR_ADD
);
4076 * Uninitialized local data
4080 * Stack the Psect (+offset)
4082 if (vsp
->Psect_Index
< 255)
4084 PUT_CHAR (TIR_S_C_STA_PL
);
4085 PUT_CHAR (vsp
->Psect_Index
);
4089 PUT_CHAR (TIR_S_C_STA_WPL
);
4090 PUT_SHORT (vsp
->Psect_Index
);
4092 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4099 * Stack the Psect (+offset)
4101 if (vsp
->Psect_Index
< 255)
4103 PUT_CHAR (TIR_S_C_STA_PL
);
4104 PUT_CHAR (vsp
->Psect_Index
);
4108 PUT_CHAR (TIR_S_C_STA_WPL
);
4109 PUT_SHORT (vsp
->Psect_Index
);
4111 PUT_LONG (S_GET_VALUE (Symbol
) + Offset
);
4114 * Initialized local or global data
4117 #ifndef NOT_VAX_11_C_COMPATIBLE
4118 case N_UNDF
| N_EXT
:
4119 case N_DATA
| N_EXT
:
4120 #endif /* NOT_VAX_11_C_COMPATIBLE */
4122 * Stack the Psect (+offset)
4124 if (vsp
->Psect_Index
< 255)
4126 PUT_CHAR (TIR_S_C_STA_PL
);
4127 PUT_CHAR (vsp
->Psect_Index
);
4131 PUT_CHAR (TIR_S_C_STA_WPL
);
4132 PUT_SHORT (vsp
->Psect_Index
);
4134 PUT_LONG (vsp
->Psect_Offset
+ Offset
);
4138 * Store either a code or data reference
4140 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4142 * Flush the buffer if it is more than 75% full
4144 if (Object_Record_Offset
>
4145 (sizeof (Object_Record_Buffer
) * 3 / 4))
4146 Flush_VMS_Object_Record_Buffer ();
4151 * Check in the text area for an indirect pc-relative reference
4152 * and fix it up with addressing mode 0xff [PC indirect]
4154 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4155 * PIC CODE GENERATING FIXUP ROUTINE.
4158 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4161 register fragS
*fragP
;
4162 struct frag
*text_frag_root
;
4165 * The addressing mode byte is 1 byte before the address
4169 * Is it in THIS frag??
4171 if ((Offset
< fragP
->fr_address
) ||
4172 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4175 * We need to search for the fragment containing this
4178 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4180 if ((Offset
>= fragP
->fr_address
) &&
4181 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4185 * If we couldn't find the frag, things are BAD!!
4188 error ("Couldn't find fixup fragment when checking for indirect reference");
4191 * Check for indirect PC relative addressing mode
4193 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4195 static char Address_Mode
= 0xff;
4198 * Yes: Store the indirect mode back into the image
4199 * to fix up the damage done by STO_PICR
4201 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4202 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4207 * If the procedure "main()" exists we have to add the instruction
4208 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4210 VMS_Check_For_Main ()
4212 register symbolS
*symbolP
;
4213 #ifdef HACK_DEC_C_STARTUP /* JF */
4214 register struct frchain
*frchainP
;
4215 register fragS
*fragP
;
4216 register fragS
**prev_fragPP
;
4217 register struct fix
*fixP
;
4218 register fragS
*New_Frag
;
4220 #endif /* HACK_DEC_C_STARTUP */
4222 symbolP
= (struct symbol
*) symbol_find ("_main");
4223 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4224 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4226 #ifdef HACK_DEC_C_STARTUP
4231 * Remember the entry point symbol
4233 Entry_Point_Symbol
= symbolP
;
4234 #ifdef HACK_DEC_C_STARTUP
4239 * Scan all the fragment chains for the one with "_main"
4240 * (Actually we know the fragment from the symbol, but we need
4241 * the previous fragment so we can change its pointer)
4243 frchainP
= frchain_root
;
4247 * Scan all the fragments in this chain, remembering
4248 * the "previous fragment"
4250 prev_fragPP
= &frchainP
->frch_root
;
4251 fragP
= frchainP
->frch_root
;
4252 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4255 * Is this the fragment?
4257 if (fragP
== symbolP
->sy_frag
)
4260 * Yes: Modify the fragment by replacing
4261 * it with a new fragment.
4263 New_Frag
= (fragS
*)
4264 xmalloc (sizeof (*New_Frag
) +
4269 * The fragments are the same except
4270 * that the "fixed" area is larger
4273 New_Frag
->fr_fix
+= 6;
4275 * Copy the literal data opening a hole
4276 * 2 bytes after "_main" (i.e. just after
4277 * the entry mask). Into which we place
4278 * the JSB instruction.
4280 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4281 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4282 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4283 New_Frag
->fr_literal
[3] = 0xef;
4284 New_Frag
->fr_literal
[4] = 0;
4285 New_Frag
->fr_literal
[5] = 0;
4286 New_Frag
->fr_literal
[6] = 0;
4287 New_Frag
->fr_literal
[7] = 0;
4288 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4289 New_Frag
->fr_literal
[i
+ 6] =
4290 fragP
->fr_literal
[i
];
4292 * Now replace the old fragment with the
4293 * newly generated one.
4295 *prev_fragPP
= New_Frag
;
4297 * Remember the entry point symbol
4299 Entry_Point_Symbol
= symbolP
;
4301 * Scan the text area fixup structures
4302 * as offsets in the fragment may have
4305 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4308 * Look for references to this
4311 if (fixP
->fx_frag
== fragP
)
4314 * Change the fragment
4317 fixP
->fx_frag
= New_Frag
;
4319 * If the offset is after
4320 * the entry mask we need
4321 * to account for the JSB
4322 * instruction we just
4325 if (fixP
->fx_where
>= 2)
4326 fixP
->fx_where
+= 6;
4330 * Scan the symbols as offsets in the
4331 * fragment may have changed
4333 for (symbolP
= symbol_rootP
;
4335 symbolP
= symbol_next (symbolP
))
4338 * Look for references to this
4341 if (symbolP
->sy_frag
== fragP
)
4344 * Change the fragment
4347 symbolP
->sy_frag
= New_Frag
;
4349 * If the offset is after
4350 * the entry mask we need
4351 * to account for the JSB
4352 * instruction we just
4355 if (S_GET_VALUE (symbolP
) >= 2)
4356 S_SET_VALUE (symbolP
,
4357 S_GET_VALUE (symbolP
) + 6);
4361 * Make a symbol reference to
4362 * "_c$main_args" so we can get
4363 * its address inserted into the
4366 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4367 S_GET_NAME (symbolP
) = "_c$main_args";
4368 S_SET_TYPE (symbolP
, N_UNDF
);
4369 S_GET_OTHER (symbolP
) = 0;
4370 S_GET_DESC (symbolP
) = 0;
4371 S_SET_VALUE (symbolP
, 0);
4372 symbolP
->sy_name_offset
= 0;
4373 symbolP
->sy_number
= 0;
4374 symbolP
->sy_frag
= New_Frag
;
4375 symbolP
->sy_resolved
= 0;
4376 symbolP
->sy_resolving
= 0;
4377 /* this actually inserts at the beginning of the list */
4378 symbol_append (symbol_rootP
, symbolP
, &symbol_rootP
, &symbol_lastP
);
4380 symbol_rootP
= symbolP
;
4382 * Generate a text fixup structure
4383 * to get "_c$main_args" stored into the
4386 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4387 fixP
->fx_frag
= New_Frag
;
4389 fixP
->fx_addsy
= symbolP
;
4391 fixP
->fx_offset
= 0;
4392 fixP
->fx_size
= sizeof (long);
4394 fixP
->fx_next
= text_fix_root
;
4395 text_fix_root
= fixP
;
4397 * Now make sure we exit from the loop
4403 * Try the next fragment
4405 prev_fragPP
= &fragP
->fr_next
;
4406 fragP
= fragP
->fr_next
;
4409 * Try the next fragment chain
4412 frchainP
= frchainP
->frch_next
;
4415 #endif /* HACK_DEC_C_STARTUP */
4420 * Write a VAX/VMS object file (everything else has been done!)
4422 VMS_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
4427 struct frag
*text_frag_root
;
4428 struct frag
*data_frag_root
;
4430 register fragS
*fragP
;
4431 register symbolS
*symbolP
;
4432 register symbolS
*sp
;
4433 register struct fix
*fixP
;
4434 register struct VMS_Symbol
*vsp
;
4436 int Local_Initialized_Data_Size
= 0;
4438 int Psect_Number
= 0; /* Psect Index Number */
4439 int Text_Psect
= -1; /* Text Psect Index */
4440 int Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
4441 int Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
4444 * Create the VMS object file
4446 Create_VMS_Object_File ();
4448 * Write the module header records
4450 Write_VMS_MHD_Records ();
4453 * Store the Data segment:
4455 * Since this is REALLY hard to do any other way,
4456 * we actually manufacture the data segment and
4457 * the store the appropriate values out of it.
4458 * We need to generate this early, so that globalvalues
4459 * can be properly emitted.
4464 * Allocate the data segment
4466 Data_Segment
= (char *) xmalloc (data_siz
);
4468 * Run through the data fragments, filling in the segment
4470 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4472 register long int count
;
4473 register char *fill_literal
;
4474 register long int fill_size
;
4477 i
= fragP
->fr_address
- text_siz
;
4479 memcpy (Data_Segment
+ i
,
4484 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4485 fill_size
= fragP
->fr_var
;
4486 for (count
= fragP
->fr_offset
; count
; count
--)
4489 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4497 * Generate the VMS object file records
4498 * 1st GSD then TIR records
4501 /******* Global Symbol Dictionary *******/
4503 * Emit globalvalues now. We must do this before the text psect
4504 * is defined, or we will get linker warnings about multiply defined
4505 * symbols. All of the globalvalues "reference" psect 0, although
4506 * it really does not have anything to do with it.
4508 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
4510 * Define the Text Psect
4512 Text_Psect
= Psect_Number
++;
4513 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
4515 * Define the BSS Psect
4519 Bss_Psect
= Psect_Number
++;
4520 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
4522 #ifndef gxx_bug_fixed
4524 * The g++ compiler does not write out external references to vtables
4525 * correctly. Check for this and holler if we see it happening.
4526 * If that compiler bug is ever fixed we can remove this.
4528 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4531 * Dispatch on symbol type
4533 switch (S_GET_RAW_TYPE (sp
)) {
4539 * Make a GSD global symbol reference
4542 if (strncmp (S_GET_NAME (sp
),"__vt.",5) == 0)
4544 S_GET_RAW_TYPE (sp
) = N_UNDF
| N_EXT
;
4545 as_warn("g++ wrote an extern reference to %s as a routine.",
4547 as_warn("I will fix it, but I hope that it was not really a routine");
4554 #endif /* gxx_bug_fixed */
4556 * Now scan the symbols and emit the appropriate GSD records
4558 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4561 * Dispatch on symbol type
4563 switch (S_GET_RAW_TYPE (sp
))
4566 * Global uninitialized data
4568 case N_UNDF
| N_EXT
:
4570 * Make a VMS data symbol entry
4572 vsp
= (struct VMS_Symbol
*)
4573 xmalloc (sizeof (*vsp
));
4575 vsp
->Size
= S_GET_VALUE (sp
);
4576 vsp
->Psect_Index
= Psect_Number
++;
4577 vsp
->Psect_Offset
= 0;
4578 vsp
->Next
= VMS_Symbols
;
4580 sp
->sy_number
= (int) vsp
;
4582 * Make the psect for this data
4584 if (S_GET_OTHER (sp
))
4585 Globalref
= VMS_Psect_Spec (
4591 Globalref
= VMS_Psect_Spec (
4599 /* See if this is an external vtable. We want to help the linker find
4600 these things in libraries, so we make a symbol reference. This
4601 is not compatible with VAX-C usage for variables, but since vtables are
4602 only used internally by g++, we can get away with this hack. */
4604 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4605 VMS_Global_Symbol_Spec (S_GET_NAME(sp
),
4610 #ifdef NOT_VAX_11_C_COMPATIBLE
4612 * Place a global symbol at the
4613 * beginning of the Psect
4615 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4619 #endif /* NOT_VAX_11_C_COMPATIBLE */
4622 * Local uninitialized data
4626 * Make a VMS data symbol entry
4628 vsp
= (struct VMS_Symbol
*)
4629 xmalloc (sizeof (*vsp
));
4632 vsp
->Psect_Index
= Bss_Psect
;
4635 bss_address_frag
.fr_address
;
4636 vsp
->Next
= VMS_Symbols
;
4638 sp
->sy_number
= (int) vsp
;
4641 * Global initialized data
4643 case N_DATA
| N_EXT
:
4645 * Make a VMS data symbol entry
4647 vsp
= (struct VMS_Symbol
*)
4648 xmalloc (sizeof (*vsp
));
4650 vsp
->Size
= VMS_Initialized_Data_Size (sp
,
4651 text_siz
+ data_siz
);
4652 vsp
->Psect_Index
= Psect_Number
++;
4653 vsp
->Psect_Offset
= 0;
4654 vsp
->Next
= VMS_Symbols
;
4656 sp
->sy_number
= (int) vsp
;
4660 if (S_GET_OTHER (sp
))
4661 Globalref
= VMS_Psect_Spec (
4667 Globalref
= VMS_Psect_Spec (
4675 /* See if this is an external vtable. We want to help the linker find
4676 these things in libraries, so we make a symbol definition. This
4677 is not compatible with VAX-C usage for variables, but since vtables are
4678 only used internally by g++, we can get away with this hack. */
4680 if(strncmp (S_GET_NAME (sp
), "__vt.", 5) == 0)
4681 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4686 #ifdef NOT_VAX_11_C_COMPATIBLE
4688 * Place a global symbol at the
4689 * beginning of the Psect
4691 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4695 #endif /* NOT_VAX_11_C_COMPATIBLE */
4698 * Local initialized data
4702 * Make a VMS data symbol entry
4704 vsp
= (struct VMS_Symbol
*)
4705 xmalloc (sizeof (*vsp
));
4708 VMS_Initialized_Data_Size (sp
,
4709 text_siz
+ data_siz
);
4710 vsp
->Psect_Index
= Data_Psect
;
4712 Local_Initialized_Data_Size
;
4713 Local_Initialized_Data_Size
+= vsp
->Size
;
4714 vsp
->Next
= VMS_Symbols
;
4716 sp
->sy_number
= (int) vsp
;
4719 * Global Text definition
4721 case N_TEXT
| N_EXT
:
4723 unsigned short Entry_Mask
;
4726 * Get the entry mask
4728 fragP
= sp
->sy_frag
;
4729 Entry_Mask
= (fragP
->fr_literal
[0] & 0xff) +
4730 ((fragP
->fr_literal
[1] & 0xff)
4733 * Define the Procedure entry pt.
4735 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4742 * Local Text definition
4746 * Make a VMS data symbol entry
4748 if (Text_Psect
!= -1)
4750 vsp
= (struct VMS_Symbol
*)
4751 xmalloc (sizeof (*vsp
));
4754 vsp
->Psect_Index
= Text_Psect
;
4755 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4756 vsp
->Next
= VMS_Symbols
;
4758 sp
->sy_number
= (int) vsp
;
4766 * Make a GSD global symbol reference
4769 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4779 * Ignore STAB symbols
4780 * Including .stabs emitted by g++
4782 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4787 if (S_GET_TYPE (sp
) != 22)
4788 printf (" ERROR, unknown type (%d)\n",
4794 * Define the Data Psect
4796 if ((data_siz
> 0) && (Local_Initialized_Data_Size
> 0))
4801 Data_Psect
= Psect_Number
++;
4802 VMS_Psect_Spec ("$data",
4803 Local_Initialized_Data_Size
,
4806 * Scan the VMS symbols and fill in the data psect
4808 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4811 * Only look for undefined psects
4813 if (vsp
->Psect_Index
< 0)
4816 * And only initialized data
4818 if ((S_GET_TYPE (vsp
->Symbol
) == N_DATA
) && !S_IS_EXTERNAL (vsp
->Symbol
))
4819 vsp
->Psect_Index
= Data_Psect
;
4824 /******* Text Information and Relocation Records *******/
4826 * Write the text segment data
4831 * Scan the text fragments
4833 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4836 * Stop if we get to the data fragments
4838 if (fragP
== data_frag_root
)
4841 * Ignore fragments with no data
4843 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4846 * Go the the appropriate offset in the
4849 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4851 * Store the "fixed" part
4854 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4858 * Store the "variable" part
4860 if (fragP
->fr_var
&& fragP
->fr_offset
)
4861 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4868 * Now we go through the text segment fixups and
4869 * generate TIR records to fix up addresses within
4872 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4875 * We DO handle the case of "Symbol - Symbol" as
4876 * long as it is in the same segment.
4878 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4883 * They need to be in the same segment
4885 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4886 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4887 error ("Fixup data addsy and subsy didn't have the same type");
4889 * And they need to be in one that we
4890 * can check the psect on
4892 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4893 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4894 error ("Fixup data addsy and subsy didn't have an appropriate type");
4896 * This had better not be PC relative!
4899 error ("Fixup data was erroneously \"pcrel\"");
4901 * Subtract their values to get the
4904 i
= S_GET_VALUE (fixP
->fx_addsy
) -
4905 S_GET_VALUE (fixP
->fx_subsy
);
4907 * Now generate the fixup object records
4908 * Set the psect and store the data
4910 VMS_Set_Psect (Text_Psect
,
4912 fixP
->fx_frag
->fr_address
,
4914 VMS_Store_Immediate_Data (&i
,
4923 * Size will HAVE to be "long"
4925 if (fixP
->fx_size
!= sizeof (long))
4926 error ("Fixup datum was not a longword");
4928 * Symbol must be "added" (if it is ever
4930 * fix this assumption)
4932 if (fixP
->fx_addsy
== 0)
4933 error ("Fixup datum was not \"fixP->fx_addsy\"");
4935 * Store the symbol value in a PIC fashion
4937 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4942 fixP
->fx_frag
->fr_address
,
4945 * Check for indirect address reference,
4946 * which has to be fixed up (as the linker
4947 * will screw it up with TIR_S_C_STO_PICR).
4950 VMS_Fix_Indirect_Reference (Text_Psect
,
4952 fixP
->fx_frag
->fr_address
,
4958 * Store the Data segment:
4960 * Since this is REALLY hard to do any other way,
4961 * we actually manufacture the data segment and
4962 * the store the appropriate values out of it.
4963 * The segment was manufactured before, now we just
4964 * dump it into the appropriate psects.
4970 * Now we can run through all the data symbols
4971 * and store the data
4973 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4976 * Ignore anything other than data symbols
4978 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
4981 * Set the Psect + Offset
4983 VMS_Set_Psect (vsp
->Psect_Index
,
4989 VMS_Store_Immediate_Data (Data_Segment
+
4990 S_GET_VALUE (vsp
->Symbol
) -
4996 * Now we go through the data segment fixups and
4997 * generate TIR records to fix up addresses within
5000 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
5003 * Find the symbol for the containing datum
5005 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5008 * Only bother with Data symbols
5011 if (S_GET_TYPE (sp
) != N_DATA
)
5014 * Ignore symbol if After fixup
5016 if (S_GET_VALUE (sp
) >
5018 fixP
->fx_frag
->fr_address
))
5021 * See if the datum is here
5023 if ((S_GET_VALUE (sp
) + vsp
->Size
) <=
5025 fixP
->fx_frag
->fr_address
))
5028 * We DO handle the case of "Symbol - Symbol" as
5029 * long as it is in the same segment.
5031 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
5036 * They need to be in the same segment
5038 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
5039 S_GET_RAW_TYPE (fixP
->fx_addsy
))
5040 error ("Fixup data addsy and subsy didn't have the same type");
5042 * And they need to be in one that we
5043 * can check the psect on
5045 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
5046 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
5047 error ("Fixup data addsy and subsy didn't have an appropriate type");
5049 * This had better not be PC relative!
5052 error ("Fixup data was erroneously \"pcrel\"");
5054 * Subtract their values to get the
5057 i
= S_GET_VALUE (fixP
->fx_addsy
) -
5058 S_GET_VALUE (fixP
->fx_subsy
);
5060 * Now generate the fixup object records
5061 * Set the psect and store the data
5063 VMS_Set_Psect (vsp
->Psect_Index
,
5064 fixP
->fx_frag
->fr_address
+
5066 S_GET_VALUE (vsp
->Symbol
) +
5069 VMS_Store_Immediate_Data (&i
,
5078 * Size will HAVE to be "long"
5080 if (fixP
->fx_size
!= sizeof (long))
5081 error ("Fixup datum was not a longword");
5083 * Symbol must be "added" (if it is ever
5085 * fix this assumption)
5087 if (fixP
->fx_addsy
== 0)
5088 error ("Fixup datum was not \"fixP->fx_addsy\"");
5090 * Store the symbol value in a PIC fashion
5092 VMS_Store_PIC_Symbol_Reference (
5097 fixP
->fx_frag
->fr_address
+
5099 S_GET_VALUE (vsp
->Symbol
) +
5112 * Write the Traceback Begin Module record
5114 VMS_TBT_Module_Begin ();
5116 * Scan the symbols and write out the routines
5117 * (this makes the assumption that symbols are in
5118 * order of ascending text segment offset)
5121 struct symbol
*Current_Routine
= 0;
5122 int Current_Line_Number
= 0;
5123 int Current_Offset
= -1;
5124 struct input_file
*Current_File
;
5126 /* Output debugging info for global variables and static variables that are not
5127 * specific to one routine. We also need to examine all stabs directives, to
5128 * find the definitions to all of the advanced data types, and this is done by
5129 * VMS_LSYM_Parse. This needs to be done before any definitions are output to
5130 * the object file, since there can be forward references in the stabs
5131 * directives. When through with parsing, the text of the stabs directive
5132 * is altered, with the definitions removed, so that later passes will see
5133 * directives as they would be written if the type were already defined.
5135 * We also look for files and include files, and make a list of them. We
5136 * examine the source file numbers to establish the actual lines that code was
5137 * generated from, and then generate offsets.
5140 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5143 * Deal with STAB symbols
5145 if (S_IS_DEBUG (symbolP
))
5148 * Dispatch on STAB type
5150 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5153 if (S_GET_DESC (symbolP
) > Current_File
->max_line
)
5154 Current_File
->max_line
= S_GET_DESC (symbolP
);
5155 if (S_GET_DESC (symbolP
) < Current_File
->min_line
)
5156 Current_File
->min_line
= S_GET_DESC (symbolP
);
5159 Current_File
= find_file (symbolP
);
5160 Current_File
->flag
= 1;
5161 Current_File
->min_line
= 1;
5164 Current_File
= find_file (symbolP
);
5167 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5170 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5172 case N_FUN
: /* For static constant symbols */
5174 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5180 /* now we take a quick sweep through the files and assign offsets
5181 to each one. This will essentially be the starting line number to the
5182 debugger for each file. Output the info for the debugger to specify the
5183 files, and then tell it how many lines to use */
5185 int File_Number
= 0;
5186 int Debugger_Offset
= 0;
5188 Current_File
= file_root
;
5189 for (Current_File
= file_root
; Current_File
; Current_File
= Current_File
->next
)
5191 if (Current_File
== (struct input_file
*) NULL
)
5193 if (Current_File
->max_line
== 0)
5195 if ((strncmp (Current_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5198 if ((strncmp (Current_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5201 /* show a few extra lines at the start of the region selected */
5202 if (Current_File
->min_line
> 2)
5203 Current_File
->min_line
-= 2;
5204 Current_File
->offset
= Debugger_Offset
- Current_File
->min_line
+ 1;
5205 Debugger_Offset
+= Current_File
->max_line
- Current_File
->min_line
+ 1;
5206 if (Current_File
->same_file_fpnt
!= (struct input_file
*) NULL
)
5207 Current_File
->file_number
= Current_File
->same_file_fpnt
->file_number
;
5210 Current_File
->file_number
= ++File_Number
;
5211 file_available
= VMS_TBT_Source_File (Current_File
->name
,
5212 Current_File
->file_number
);
5213 if (!file_available
)
5215 Current_File
->file_number
= 0;
5220 VMS_TBT_Source_Lines (Current_File
->file_number
,
5221 Current_File
->min_line
,
5222 Current_File
->max_line
- Current_File
->min_line
+ 1);
5225 Current_File
= (struct input_file
*) NULL
;
5227 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5230 * Deal with text symbols
5232 if (!S_IS_DEBUG (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
5235 * Ignore symbols starting with "L",
5236 * as they are local symbols
5238 if (*S_GET_NAME (symbolP
) == 'L')
5241 * If there is a routine start defined,
5244 if (Current_Routine
)
5249 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5252 * Store the routine begin traceback info
5254 if (Text_Psect
!= -1)
5256 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5257 Current_Routine
= symbolP
;
5259 /* Output local symbols, i.e. all symbols that are associated with a specific
5260 * routine. We output them now so the debugger recognizes them as local to
5267 for (symbolP1
= Current_Routine
; symbolP1
; symbolP1
= symbol_next (symbolP1
))
5269 if (!S_IS_DEBUG (symbolP1
))
5271 if (S_GET_RAW_TYPE (symbolP1
) != N_FUN
)
5273 pnt
= S_GET_NAME (symbolP
);
5274 pnt1
= S_GET_NAME (symbolP1
);
5277 while (*pnt
++ == *pnt1
++)
5280 if (*pnt1
!= 'F' && *pnt1
!= 'f') continue;
5281 if ((*(--pnt
) == '\0') && (*(--pnt1
) == ':'))
5284 if (symbolP1
!= (symbolS
*) NULL
)
5285 VMS_DBG_Define_Routine (symbolP1
, Current_Routine
, Text_Psect
);
5286 } /* local symbol block */
5293 * Deal with STAB symbols
5295 if (S_IS_DEBUG (symbolP
))
5298 * Dispatch on STAB type
5300 switch ((unsigned char) S_GET_RAW_TYPE (symbolP
))
5306 /* Offset the line into the correct portion
5308 if (Current_File
->file_number
== 0)
5310 /* Sometimes the same offset gets several source
5311 * lines assigned to it.
5312 * We should be selective about which lines
5313 * we allow, we should prefer lines that are
5314 * in the main source file when debugging
5315 * inline functions. */
5316 if ((Current_File
->file_number
!= 1) &&
5317 S_GET_VALUE (symbolP
) ==
5320 /* calculate actual debugger source line */
5321 S_GET_DESC (symbolP
)
5322 += Current_File
->offset
;
5324 * If this is the 1st N_SLINE, setup
5325 * PC/Line correlation. Otherwise
5326 * do the delta PC/Line. If the offset
5327 * for the line number is not +ve we need
5328 * to do another PC/Line correlation
5331 if (Current_Offset
== -1)
5333 VMS_TBT_Line_PC_Correlation (
5334 S_GET_DESC (symbolP
),
5335 S_GET_VALUE (symbolP
),
5341 if ((S_GET_DESC (symbolP
) -
5342 Current_Line_Number
) <= 0)
5345 * Line delta is not +ve, we
5346 * need to close the line and
5347 * start a new PC/Line
5350 VMS_TBT_Line_PC_Correlation (0,
5351 S_GET_VALUE (symbolP
) -
5355 VMS_TBT_Line_PC_Correlation (
5356 S_GET_DESC (symbolP
),
5357 S_GET_VALUE (symbolP
),
5364 * Line delta is +ve, all is well
5366 VMS_TBT_Line_PC_Correlation (
5367 S_GET_DESC (symbolP
) -
5368 Current_Line_Number
,
5369 S_GET_VALUE (symbolP
) -
5376 * Update the current line/PC
5378 Current_Line_Number
= S_GET_DESC (symbolP
);
5379 Current_Offset
= S_GET_VALUE (symbolP
);
5389 * Remember that we had a source file
5390 * and emit the source file debugger
5394 find_file (symbolP
);
5396 /* We need to make sure that we are really in the actual source file when
5397 * we compute the maximum line number. Otherwise the debugger gets really
5401 find_file (symbolP
);
5407 * If there is a routine start defined,
5408 * terminate it (and the line numbers)
5410 if (Current_Routine
)
5413 * Terminate the line numbers
5415 VMS_TBT_Line_PC_Correlation (0,
5416 text_siz
- S_GET_VALUE (Current_Routine
),
5420 * Terminate the routine
5422 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5426 * Write the Traceback End Module TBT record
5428 VMS_TBT_Module_End ();
5431 * Write the End Of Module record
5433 if (Entry_Point_Symbol
== 0)
5434 Write_VMS_EOM_Record (-1, 0);
5436 Write_VMS_EOM_Record (Text_Psect
,
5437 S_GET_VALUE (Entry_Point_Symbol
));
5440 * All done, close the object file
5442 Close_VMS_Object_File ();
5445 /* end of obj-vms.c */