1 /* vms.c -- Write out a VAX/VMS object file
2 Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 /* Written by David L. Kashtan */
21 /* Modified by Eric Youngdale to write VMS debug records for program
24 /* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h). */
25 #define WANT_VMS_OBJ_DEFS
32 /* What we do if there is a goof. */
33 #define error as_fatal
35 #ifdef VMS /* These are of no use if we are cross assembling. */
36 #include <fab.h> /* Define File Access Block */
37 #include <nam.h> /* Define NAM Block */
38 #include <xab.h> /* Define XAB - all different types*/
39 extern int sys$
open(), sys$
close(), sys$
asctim();
43 * Version string of the compiler that produced the code we are
44 * assembling. (And this assembler, if we do not have compiler info.)
46 char *compiler_version_string
;
48 extern int flag_hash_long_names
; /* -+ */
49 extern int flag_one
; /* -1; compatibility with gcc 1.x */
50 extern int flag_show_after_trunc
; /* -H */
51 extern int flag_no_hash_mixed_case
; /* -h NUM */
53 /* Flag that determines how we map names. This takes several values, and
54 * is set with the -h switch. A value of zero implies names should be
55 * upper case, and the presence of the -h switch inhibits the case hack.
56 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
57 * A value of 2 (set with -h2) implies names should be
58 * all lower case, with no case hack. A value of 3 (set with -h3) implies
59 * that case should be preserved. */
61 /* If the -+ switch is given, then the hash is appended to any name that is
62 * longer than 31 characters, regardless of the setting of the -h switch.
65 char vms_name_mapping
= 0;
67 static symbolS
*Entry_Point_Symbol
= 0; /* Pointer to "_main" */
70 * We augment the "gas" symbol structure with this
74 struct VMS_Symbol
*Next
;
81 struct VMS_Symbol
*VMS_Symbols
= 0;
83 /* We need this to keep track of the various input files, so that we can
84 * give the debugger the correct source line.
89 struct input_file
*next
;
90 struct input_file
*same_file_fpnt
;
100 static struct input_file
*file_root
= (struct input_file
*) NULL
;
104 * Styles of PSECTS (program sections) that we generate; just shorthand
105 * to avoid lists of section attributes. Used by VMS_Psect_Spec().
109 ps_TEXT
, ps_DATA
, ps_COMMON
, ps_CONST
113 * This enum is used to keep track of the various types of variables that
119 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
123 * This structure contains the information from the stabs directives, and the
124 * information is filled in by VMS_typedef_parse. Everything that is needed
125 * to generate the debugging record for a given symbol is present here.
126 * This could be done more efficiently, using nested struct/unions, but for now
127 * I am happy that it works.
129 struct VMS_DBG_Symbol
131 struct VMS_DBG_Symbol
*next
;
132 /* description of what this is */
133 enum advanced_type advanced
;
134 /* this record is for this type */
136 /* For advanced types this is the type referred to. I.e., the type
137 a pointer points to, or the type of object that makes up an
140 /* Use this type when generating a variable def */
142 /* used for arrays - this will be present for all */
144 /* entries, but will be meaningless for non-arrays */
146 /* Size in bytes of the data type. For an array, this is the size
147 of one element in the array */
149 /* Number of the structure/union/enum - used for ref */
153 #define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */
154 #define SYMTYP_HASH(x) ((unsigned)(x) & (SYMTYPLST_SIZE-1))
155 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
[SYMTYPLST_SIZE
];
158 * We need this structure to keep track of forward references to
159 * struct/union/enum that have not been defined yet. When they are ultimately
160 * defined, then we can go back and generate the TIR commands to make a back
166 struct forward_ref
*next
;
172 struct forward_ref
*f_ref_root
= (struct forward_ref
*) NULL
;
175 * This routine is used to compare the names of certain types to various
176 * fixed types that are known by the debugger.
178 #define type_check(X) !strcmp (symbol_name, X)
181 * This variable is used to keep track of the name of the symbol we are
182 * working on while we are parsing the stabs directives.
184 static const char *symbol_name
;
186 /* We use this counter to assign numbers to all of the structures, unions
187 * and enums that we define. When we actually declare a variable to the
188 * debugger, we can simply do it by number, rather than describing the
189 * whole thing each time.
192 static structure_count
= 0;
194 /* This variable is used to indicate that we are making the last attempt to
195 parse the stabs, and that we should define as much as we can, and ignore
198 static int final_pass
;
200 /* This variable is used to keep track of the current structure number
201 * for a given variable. If this is < 0, that means that the structure
202 * has not yet been defined to the debugger. This is still cool, since
203 * the VMS object language has ways of fixing things up after the fact,
204 * so we just make a note of this, and generate fixups at the end.
206 static int struct_number
;
208 /* This is used to distinguish between D_float and G_float for telling
209 the debugger about doubles. gcc outputs the same .stabs regardless
210 of whether -mg is used to select alternate doubles. */
212 static int vax_g_doubles
= 0;
214 /* Local symbol references (used to handle N_ABS symbols; gcc does not
215 generate those, but they're possible with hand-coded assembler input)
216 are always made relative to some particular environment. If the current
217 input has any such symbols, then we expect this to get incremented
218 exactly once and end up having all of them be in environment #0. */
220 static int Current_Environment
= -1;
224 * Variable descriptors are used tell the debugger the data types of certain
225 * more complicated variables (basically anything involving a structure,
226 * union, enum, array or pointer). Some non-pointer variables of the
227 * basic types that the debugger knows about do not require a variable
230 * Since it is impossible to have a variable descriptor longer than 128
231 * bytes by virtue of the way that the VMS object language is set up,
232 * it makes not sense to make the arrays any longer than this, or worrying
233 * about dynamic sizing of the array.
235 * These are the arrays and counters that we use to build a variable
239 #define MAX_DEBUG_RECORD 128
240 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
241 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
242 static int Lpnt
; /* index into Local */
243 static int Apoint
; /* index into Asuffix */
244 static char overflow
; /* flag to indicate we have written too much*/
245 static int total_len
; /* used to calculate the total length of variable
246 descriptor plus array descriptor - used for len byte*/
248 /* Flag if we have told user about finding global constants in the text
250 static int gave_compiler_message
= 0;
254 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
256 static int VMS_Object_File_FD
; /* File Descriptor for object file */
257 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
258 static int Object_Record_Offset
;/* Offset to end of data */
259 static int Current_Object_Record_Type
; /* Type of record in above */
262 * Macros for moving data around. Must work on big-endian systems.
264 #ifdef VMS /* These are more efficient for VMS->VMS systems */
265 #define COPY_LONG(dest,val) ( *(long *)(dest) = (val) )
266 #define COPY_SHORT(dest,val) ( *(short *)(dest) = (val) )
268 #define COPY_LONG(dest,val) md_number_to_chars ((dest), (val), 4)
269 #define COPY_SHORT(dest,val) md_number_to_chars ((dest), (val), 2)
272 * Macros for placing data into the object record buffer
274 #define PUT_LONG(val) \
275 ( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \
276 Object_Record_Offset += 4 )
278 #define PUT_SHORT(val) \
279 ( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \
280 Object_Record_Offset += 2 )
282 #define PUT_CHAR(val) ( Object_Record_Buffer[Object_Record_Offset++] = (val) )
284 #define PUT_COUNTED_STRING(cp) do { \
285 register const char *p = (cp); \
286 PUT_CHAR ((char) strlen (p)); \
287 while (*p) PUT_CHAR (*p++); } while (0)
290 * Macro for determining if a Name has psect attributes attached
293 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
294 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
296 #define HAS_PSECT_ATTRIBUTES(Name) \
297 (strncmp ((*Name == '_' ? Name + 1 : Name), \
298 PSECT_ATTRIBUTES_STRING, \
299 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
302 /* in: segT out: N_TYPE bits */
303 const short seg_N_TYPE
[] =
309 N_UNDF
, /* unknown */
311 N_UNDF
, /* expression */
315 N_REGISTER
, /* register */
318 const segT N_TYPE_seg
[N_TYPE
+ 2] =
319 { /* N_TYPE == 0x1E = 32-2 */
320 SEG_UNKNOWN
, /* N_UNDF == 0 */
322 SEG_ABSOLUTE
, /* N_ABS == 2 */
324 SEG_TEXT
, /* N_TEXT == 4 */
326 SEG_DATA
, /* N_DATA == 6 */
328 SEG_BSS
, /* N_BSS == 8 */
330 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
331 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
332 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
333 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
338 /* Local support routines which return a value. */
340 static struct input_file
*find_file
PARAMS ((symbolS
*));
341 static struct VMS_DBG_Symbol
*find_symbol
PARAMS ((int));
342 static symbolS
*Define_Routine
PARAMS ((symbolS
*,int,symbolS
*,int));
344 static char *cvt_integer
PARAMS ((char *,int *));
345 static char *fix_name
PARAMS ((char *));
346 static char *get_struct_name
PARAMS ((char *));
348 static int VMS_TBT_Source_File
PARAMS ((char *,int));
349 static int gen1
PARAMS ((struct VMS_DBG_Symbol
*,int));
350 static int forward_reference
PARAMS ((char *));
351 static int final_forward_reference
PARAMS ((struct VMS_DBG_Symbol
*));
352 static int VMS_typedef_parse
PARAMS ((char *));
353 static int hash_string
PARAMS ((const char *));
354 static int VMS_Psect_Spec
PARAMS ((const char *,int,enum ps_type
,
355 struct VMS_Symbol
*));
356 static int VMS_Initialized_Data_Size
PARAMS ((symbolS
*,int));
358 /* Local support routines which don't directly return any value. */
360 static void s_const
PARAMS ((int));
361 static void Create_VMS_Object_File
PARAMS ((void));
362 static void Flush_VMS_Object_Record_Buffer
PARAMS ((void));
363 static void Set_VMS_Object_File_Record
PARAMS ((int));
364 static void Close_VMS_Object_File
PARAMS ((void));
365 static void vms_tir_stack_psect
PARAMS ((int,int,int));
366 static void VMS_Store_Immediate_Data
PARAMS ((const char *,int,int));
367 static void VMS_Set_Data
PARAMS ((int,int,int,int));
368 static void VMS_Store_Struct
PARAMS ((int));
369 static void VMS_Def_Struct
PARAMS ((int));
370 static void VMS_Set_Struct
PARAMS ((int));
371 static void VMS_TBT_Module_Begin
PARAMS ((void));
372 static void VMS_TBT_Module_End
PARAMS ((void));
373 static void VMS_TBT_Routine_Begin
PARAMS ((symbolS
*,int));
374 static void VMS_TBT_Routine_End
PARAMS ((int,symbolS
*));
375 static void VMS_TBT_Block_Begin
PARAMS ((symbolS
*,int,char *));
376 static void VMS_TBT_Block_End
PARAMS ((valueT
));
377 static void VMS_TBT_Line_PC_Correlation
PARAMS ((int,int,int,int));
378 static void VMS_TBT_Source_Lines
PARAMS ((int,int,int));
379 static void fpush
PARAMS ((int,int));
380 static void rpush
PARAMS ((int,int));
381 static void array_suffix
PARAMS ((struct VMS_DBG_Symbol
*));
382 static void new_forward_ref
PARAMS ((int));
383 static void generate_suffix
PARAMS ((struct VMS_DBG_Symbol
*,int));
384 static void bitfield_suffix
PARAMS ((struct VMS_DBG_Symbol
*,int));
385 static void setup_basic_type
PARAMS ((struct VMS_DBG_Symbol
*));
386 static void VMS_DBG_record
PARAMS ((struct VMS_DBG_Symbol
*,int,int,char *));
387 static void VMS_local_stab_Parse
PARAMS ((symbolS
*));
388 static void VMS_stab_parse
PARAMS ((symbolS
*,int,int,int,int));
389 static void VMS_GSYM_Parse
PARAMS ((symbolS
*,int));
390 static void VMS_LCSYM_Parse
PARAMS ((symbolS
*,int));
391 static void VMS_STSYM_Parse
PARAMS ((symbolS
*,int));
392 static void VMS_RSYM_Parse
PARAMS ((symbolS
*,symbolS
*,int));
393 static void VMS_LSYM_Parse
PARAMS ((void));
394 static void Define_Local_Symbols
PARAMS ((symbolS
*,symbolS
*,symbolS
*,int));
395 static void Write_VMS_MHD_Records
PARAMS ((void));
396 static void Write_VMS_EOM_Record
PARAMS ((int,int));
397 static void VMS_Case_Hack_Symbol
PARAMS ((const char *,char *));
398 static void VMS_Modify_Psect_Attributes
PARAMS ((const char *,int *));
399 static void VMS_Global_Symbol_Spec
PARAMS ((const char *,int,int,int));
400 static void VMS_Local_Environment_Setup
PARAMS ((const char *));
401 static void VMS_Emit_Globalvalues
PARAMS ((unsigned,unsigned,char *));
402 static void VMS_Procedure_Entry_Pt
PARAMS ((char *,int,int,int));
403 static void VMS_Set_Psect
PARAMS ((int,int,int));
404 static void VMS_Store_Repeated_Data
PARAMS ((int,char *,int,int));
405 static void VMS_Store_PIC_Symbol_Reference
PARAMS ((symbolS
*,int,
407 static void VMS_Fix_Indirect_Reference
PARAMS ((int,int,fragS
*,fragS
*));
409 /* Support code which used to be inline within vms_write_object_file. */
410 static void vms_fixup_text_section
PARAMS ((unsigned,struct frag
*,struct frag
*));
411 static void synthesize_data_segment
PARAMS ((unsigned,unsigned,struct frag
*));
412 static void vms_fixup_data_section
PARAMS ((unsigned,unsigned));
413 static void global_symbol_directory
PARAMS ((unsigned,unsigned));
414 static void local_symbols_DST
PARAMS ((symbolS
*,symbolS
*));
415 static void vms_build_DST
PARAMS ((unsigned));
418 /* The following code defines the special types of pseudo-ops that we
422 unsigned char const_flag
= IN_DEFAULT_SECTION
;
426 int arg
; /* 3rd field from obj_pseudo_table[]; not needed here */
428 /* Since we don't need `arg', use it as our scratch variable so that
429 we won't get any "not used" warnings about it. */
430 arg
= get_absolute_expression ();
431 subseg_set (SEG_DATA
, (subsegT
) arg
);
433 demand_empty_rest_of_line ();
436 const pseudo_typeS obj_pseudo_table
[] =
438 {"const", s_const
, 0},
440 }; /* obj_pseudo_table */
443 /* Routine to perform RESOLVE_SYMBOL_REDEFINITION(). */
446 vms_resolve_symbol_redef (sym
)
450 * If the new symbol is .comm AND it has a size of zero,
451 * we ignore it (i.e. the old symbol overrides it)
453 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)
454 && frag_now_fix () == 0)
456 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
461 * If the old symbol is .comm and it has a size of zero,
462 * we override it with the new symbol value.
464 if (S_IS_EXTERNAL (sym
) && S_IS_DEFINED (sym
) && S_GET_VALUE (sym
) == 0)
466 as_warn ("compiler redefined zero-size common symbol `%s'",
468 sym
->sy_frag
= frag_now
;
469 S_SET_OTHER (sym
, const_flag
);
470 S_SET_VALUE (sym
, frag_now_fix ());
471 /* Keep N_EXT bit. */
472 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
);
479 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
480 dummy label(s) gcc inserts at the beginning of each file it generates.
481 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
482 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
485 vms_check_for_special_label (symbolP
)
488 /* Special labels only occur prior to explicit section directives. */
489 if ((const_flag
& IN_DEFAULT_SECTION
) != 0)
491 char *sym_name
= S_GET_NAME (symbolP
);
493 if (*sym_name
== '_')
496 if (!strcmp (sym_name
, "__vax_g_doubles"))
498 #if 0 /* not necessary */
499 else if (!strcmp (sym_name
, "__vax_d_doubles"))
502 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
503 else if (!strcmp (sym_name
, "gcc_compiled."))
505 else if (!strcmp (sym_name
, "__gnu_language_cplusplus"))
506 flag_hash_long_names
= 1;
513 obj_read_begin_hook ()
519 obj_crawl_symbol_chain (headers
)
520 object_headers
*headers
;
524 int symbol_number
= 0;
526 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
527 while ((symbolP
= *symbolPP
) != NULL
)
529 resolve_symbol_value (symbolP
);
531 /* OK, here is how we decide which symbols go out into the
532 brave new symtab. Symbols that do are:
534 * symbols with no name (stabd's?)
535 * symbols with debug info in their N_TYPE
536 * symbols with \1 as their 3rd character (numeric labels)
537 * "local labels" needed for PIC fixups
539 Symbols that don't are:
540 * symbols that are registers
542 All other symbols are output. We complain if a deleted
543 symbol was marked external. */
545 if (!S_IS_REGISTER (symbolP
))
547 symbolP
->sy_number
= symbol_number
++;
548 symbolP
->sy_name_offset
= 0;
549 symbolPP
= &(symbol_next (symbolP
));
553 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
555 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
558 /* Unhook it from the chain. */
559 *symbolPP
= symbol_next (symbolP
);
560 } /* if this symbol should be in the output */
562 } /* for each symbol */
564 H_SET_STRING_SIZE (headers
, string_byte_count
);
565 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
566 } /* obj_crawl_symbol_chain() */
569 /****** VMS OBJECT FILE HACKING ROUTINES *******/
573 * Create the VMS object file
576 Create_VMS_Object_File ()
578 #if defined(eunice) || !defined(VMS)
579 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
581 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
582 "mbc=16", "deq=64", "fop=tef", "shr=nil");
587 if (VMS_Object_File_FD
< 0)
588 as_fatal ("Couldn't create VMS object file \"%s\"", out_file_name
);
590 * Initialize object file hacking variables
592 Object_Record_Offset
= 0;
593 Current_Object_Record_Type
= -1;
598 * Flush the object record buffer to the object file
601 Flush_VMS_Object_Record_Buffer ()
610 * If the buffer is empty, we are done
612 if (Object_Record_Offset
== 0)
615 * Write the data to the file
617 #ifndef VMS /* For cross-assembly purposes. */
618 md_number_to_chars ((char *) &RecLen
, Object_Record_Offset
, 2);
619 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
621 i
= write (VMS_Object_File_FD
,
622 Object_Record_Buffer
,
623 Object_Record_Offset
);
624 if (i
!= Object_Record_Offset
)
625 error ("I/O error writing VMS object file");
626 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
628 /* pad it if needed */
630 if ((Object_Record_Offset
& 1) != 0)
631 write (VMS_Object_File_FD
, &zero
, 1);
634 * The buffer is now empty
636 Object_Record_Offset
= 0;
641 * Declare a particular type of object file record
644 Set_VMS_Object_File_Record (Type
)
648 * If the type matches, we are done
650 if (Type
== Current_Object_Record_Type
)
653 * Otherwise: flush the buffer
655 Flush_VMS_Object_Record_Buffer ();
659 Current_Object_Record_Type
= Type
;
665 * Close the VMS Object file
668 Close_VMS_Object_File ()
670 #ifndef VMS /* For cross-assembly purposes. */
671 short int m_one
= -1;
673 /* Write a record-length field of 0xffff into the file, which means
674 end-of-file when read later. It is only needed for variable-length
675 record files transferred to VMS as fixed-length record files
676 (typical for binary ftp). */
677 write (VMS_Object_File_FD
, &m_one
, 2);
679 /* When written on a VMS system, the file header (cf inode) will record
680 the actual end-of-file position and no inline marker is needed. */
683 close (VMS_Object_File_FD
);
688 * Stack Psect base followed by signed, varying-sized offset.
689 * Common to several object records.
692 vms_tir_stack_psect (Psect_Index
, Offset
, Force
)
697 int psect_width
, offset_width
;
699 psect_width
= ((unsigned) Psect_Index
> 255) ? 2 : 1;
700 offset_width
= (Force
|| Offset
> 32767 || Offset
< -32768) ? 4
701 : (Offset
> 127 || Offset
< -128) ? 2 : 1;
702 #define Sta_P(p,o) (((o)<<1) | ((p)-1))
703 /* byte or word psect; byte, word, or longword offset */
704 switch (Sta_P(psect_width
,offset_width
))
706 case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB
);
707 PUT_CHAR ((char)(unsigned char) Psect_Index
);
708 PUT_CHAR ((char) Offset
);
710 case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW
);
711 PUT_CHAR ((char)(unsigned char) Psect_Index
);
714 case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL
);
715 PUT_CHAR ((char)(unsigned char) Psect_Index
);
718 case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB
);
719 PUT_SHORT (Psect_Index
);
720 PUT_CHAR ((char) Offset
);
722 case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW
);
723 PUT_SHORT (Psect_Index
);
726 case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL
);
727 PUT_SHORT (Psect_Index
);
735 * Store immediate data in current Psect
738 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
746 * We are writing a "Record_Type" record
748 Set_VMS_Object_File_Record (Record_Type
);
750 * We can only store 128 bytes at a time
755 * Store a maximum of 128 bytes
757 i
= (Size
> 128) ? 128 : Size
;
760 * If we cannot accommodate this record, flush the
763 if ((Object_Record_Offset
+ i
+ 1) >= sizeof (Object_Record_Buffer
))
764 Flush_VMS_Object_Record_Buffer ();
766 * If the buffer is empty we must insert record type
768 if (Object_Record_Offset
== 0)
769 PUT_CHAR (Record_Type
);
773 PUT_CHAR (-i
& 0xff);
778 PUT_CHAR (*Pointer
++);
781 * Flush the buffer if it is more than 75% full.
783 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
784 Flush_VMS_Object_Record_Buffer ();
788 * Make a data reference
791 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
798 * We are writing a "Record_Type" record
800 Set_VMS_Object_File_Record (Record_Type
);
802 * If the buffer is empty we must insert the record type
804 if (Object_Record_Offset
== 0)
805 PUT_CHAR (Record_Type
);
807 * Stack the Psect base with its offset
809 vms_tir_stack_psect (Psect_Index
, Offset
, Force
);
811 * Set relocation base
813 PUT_CHAR (TIR_S_C_STO_PIDR
);
815 * Flush the buffer if it is more than 75% full
817 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
818 Flush_VMS_Object_Record_Buffer ();
822 * Make a debugger reference to a struct, union or enum.
825 VMS_Store_Struct (Struct_Index
)
829 * We are writing a "OBJ_S_C_DBG" record
831 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
833 * If the buffer is empty we must insert the record type
835 if (Object_Record_Offset
== 0)
836 PUT_CHAR (OBJ_S_C_DBG
);
837 PUT_CHAR (TIR_S_C_STA_UW
);
838 PUT_SHORT (Struct_Index
);
839 PUT_CHAR (TIR_S_C_CTL_STKDL
);
840 PUT_CHAR (TIR_S_C_STO_L
);
842 * Flush the buffer if it is more than 75% full
844 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
845 Flush_VMS_Object_Record_Buffer ();
849 * Make a debugger reference to partially define a struct, union or enum.
852 VMS_Def_Struct (Struct_Index
)
856 * We are writing a "OBJ_S_C_DBG" record
858 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
860 * If the buffer is empty we must insert the record type
862 if (Object_Record_Offset
== 0)
863 PUT_CHAR (OBJ_S_C_DBG
);
864 PUT_CHAR (TIR_S_C_STA_UW
);
865 PUT_SHORT (Struct_Index
);
866 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
868 * Flush the buffer if it is more than 75% full
870 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
871 Flush_VMS_Object_Record_Buffer ();
875 VMS_Set_Struct (Struct_Index
)
877 { /* see previous functions for comments */
878 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
879 if (Object_Record_Offset
== 0)
880 PUT_CHAR (OBJ_S_C_DBG
);
881 PUT_CHAR (TIR_S_C_STA_UW
);
882 PUT_SHORT (Struct_Index
);
883 PUT_CHAR (TIR_S_C_CTL_STLOC
);
884 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
885 Flush_VMS_Object_Record_Buffer ();
889 * Write the Traceback Module Begin record
892 VMS_TBT_Module_Begin ()
894 register char *cp
, *cp1
;
896 char Module_Name
[256];
900 * Get module name (the FILENAME part of the object file)
906 if ((*cp
== ']') || (*cp
== '>') ||
907 (*cp
== ':') || (*cp
== '/'))
913 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
917 * Limit it to 31 characters
919 while (--cp1
>= Module_Name
)
922 if (strlen (Module_Name
) > 31)
924 if (flag_hash_long_names
)
925 as_tsktsk ("Module name truncated: %s", Module_Name
);
929 * Arrange to store the data locally (leave room for size byte)
935 *cp
++ = DST_S_C_MODBEG
;
941 * Language type == "C"
943 COPY_LONG (cp
, DST_S_C_C
);
946 * Store the module name
948 *cp
++ = strlen (Module_Name
);
953 * Now we can store the record size
958 * Put it into the object record
960 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
965 * Write the Traceback Module End record
968 VMS_TBT_Module_End ()
976 Local
[1] = DST_S_C_MODEND
;
978 * Put it into the object record
980 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
985 * Write the Traceback Routine Begin record
988 VMS_TBT_Routine_Begin (symbolP
, Psect
)
992 register char *cp
, *cp1
;
999 * Strip the leading "_" from the name
1001 Name
= S_GET_NAME (symbolP
);
1005 * Get the text psect offset
1007 Offset
= S_GET_VALUE (symbolP
);
1009 * Calculate the record size
1011 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1019 Local
[1] = DST_S_C_RTNBEG
;
1025 * Store the data so far
1027 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1029 * Make sure we are still generating a OBJ_S_C_TBT record
1031 if (Object_Record_Offset
== 0)
1032 PUT_CHAR (OBJ_S_C_TBT
);
1036 vms_tir_stack_psect (Psect
, Offset
, 0);
1038 * Store the data reference
1040 PUT_CHAR (TIR_S_C_STO_PIDR
);
1042 * Store the counted string as data
1046 Size
= strlen (cp1
) + 1;
1050 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1055 * Write the Traceback Routine End record
1056 * We *must* search the symbol table to find the next routine, since
1057 * the assember has a way of reassembling the symbol table OUT OF ORDER
1058 * Thus the next routine in the symbol list is not necessarily the
1059 * next one in memory. For debugging to work correctly we must know the
1060 * size of the routine.
1063 VMS_TBT_Routine_End (Max_Size
, sp
)
1068 int Size
= 0x7fffffff;
1070 valueT sym_value
, sp_value
= S_GET_VALUE (sp
);
1072 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1074 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1076 if (*S_GET_NAME (symbolP
) == 'L')
1078 sym_value
= S_GET_VALUE (symbolP
);
1079 if (sym_value
> sp_value
&& sym_value
< Size
)
1083 * Dummy labels like "gcc_compiled." should no longer reach here.
1087 /* check if gcc_compiled. has size of zero */
1088 if (sym_value
== sp_value
&&
1090 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1091 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1096 if (Size
== 0x7fffffff)
1098 Size
-= sp_value
; /* and get the size of the routine */
1106 Local
[1] = DST_S_C_RTNEND
;
1114 COPY_LONG (&Local
[3], Size
);
1118 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1122 * Write the Traceback Block End record
1125 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1130 register char *cp
, *cp1
;
1137 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1143 * Begin Block - We simulate with a phony routine
1145 Local
[1] = DST_S_C_BLKBEG
;
1151 * Store the data so far
1153 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1155 * Make sure we are still generating a OBJ_S_C_DBG record
1157 if (Object_Record_Offset
== 0)
1158 PUT_CHAR (OBJ_S_C_DBG
);
1160 * Now get the symbol address
1162 PUT_CHAR (TIR_S_C_STA_WPL
);
1165 * Get the text psect offset
1167 Offset
= S_GET_VALUE (symbolP
);
1170 * Store the data reference
1172 PUT_CHAR (TIR_S_C_STO_PIDR
);
1174 * Store the counted string as data
1178 Size
= strlen (cp1
) + 1;
1182 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1187 * Write the Traceback Block End record
1190 VMS_TBT_Block_End (Size
)
1196 * End block - simulate with a phony end routine
1199 Local
[1] = DST_S_C_BLKEND
;
1200 Local
[2] = 0; /* unused, must be zero */
1201 COPY_LONG (&Local
[3], Size
);
1202 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1208 * Write a Line number / PC correlation record
1211 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1221 * If not delta, set our PC/Line number correlation
1228 Local
[0] = 1 + 1 + 2 + 1 + 4;
1230 * Line Number/PC correlation
1232 Local
[1] = DST_S_C_LINE_NUM
;
1236 Local
[2] = DST_S_C_SET_LINE_NUM
;
1237 COPY_SHORT (&Local
[3], Line_Number
- 1);
1241 Local
[5] = DST_S_C_SET_ABS_PC
;
1242 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1244 * Make sure we are still generating a OBJ_S_C_TBT record
1246 if (Object_Record_Offset
== 0)
1247 PUT_CHAR (OBJ_S_C_TBT
);
1248 vms_tir_stack_psect (Psect
, Offset
, 0);
1249 PUT_CHAR (TIR_S_C_STO_PIDR
);
1251 * Do a PC offset of 0 to register the line number
1254 Local
[1] = DST_S_C_LINE_NUM
;
1255 Local
[2] = 0; /* Increment PC by 0 and register line # */
1256 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1261 * If Delta is negative, terminate the line numbers
1265 Local
[0] = 1 + 1 + 4;
1266 Local
[1] = DST_S_C_LINE_NUM
;
1267 Local
[2] = DST_S_C_TERM_L
;
1268 COPY_LONG (&Local
[3], Offset
);
1269 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1276 * Do a PC/Line delta
1279 *cp
++ = DST_S_C_LINE_NUM
;
1280 if (Line_Number
> 1)
1283 * We need to increment the line number
1285 if (Line_Number
- 1 <= 255)
1287 *cp
++ = DST_S_C_INCR_LINUM
;
1288 *cp
++ = Line_Number
- 1;
1292 *cp
++ = DST_S_C_INCR_LINUM_W
;
1293 COPY_SHORT (cp
, Line_Number
- 1);
1306 if (Offset
< 0x10000)
1308 *cp
++ = DST_S_C_DELTA_PC_W
;
1309 COPY_SHORT (cp
, Offset
);
1314 *cp
++ = DST_S_C_DELTA_PC_L
;
1315 COPY_LONG (cp
, Offset
);
1319 Local
[0] = cp
- (Local
+ 1);
1320 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1326 * Describe a source file to the debugger
1329 VMS_TBT_Source_File (Filename
, ID_Number
)
1333 register char *cp
, *cp1
;
1336 #ifndef VMS /* Used for cross-assembly */
1337 i
= strlen (Filename
);
1339 static struct FAB Fab
;
1340 static struct NAM Nam
;
1341 static struct XABDAT Date_Xab
;
1342 static struct XABFHC File_Header_Xab
;
1343 char Es_String
[255], Rs_String
[255];
1348 Fab
.fab$b_bid
= FAB$C_BID
;
1349 Fab
.fab$b_bln
= sizeof (Fab
);
1350 Fab
.fab$l_nam
= (&Nam
);
1351 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1353 * Setup the Nam block so we can find out the FULL name
1354 * of the source file.
1356 Nam
.nam$b_bid
= NAM$C_BID
;
1357 Nam
.nam$b_bln
= sizeof (Nam
);
1358 Nam
.nam$l_rsa
= Rs_String
;
1359 Nam
.nam$b_rss
= sizeof (Rs_String
);
1360 Nam
.nam$l_esa
= Es_String
;
1361 Nam
.nam$b_ess
= sizeof (Es_String
);
1363 * Setup the Date and File Header Xabs
1365 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1366 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1367 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1368 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1369 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1371 * Get the file information
1373 Fab
.fab$l_fna
= Filename
;
1374 Fab
.fab$b_fns
= strlen (Filename
);
1375 Status
= sys$
open (&Fab
);
1378 as_tsktsk ("Couldn't find source file \"%s\", status=%%X%x",
1384 * Calculate the size of the resultant string
1391 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1393 * Source declaration
1395 Local
[1] = DST_S_C_SOURCE
;
1397 * Make formfeeds count as source records
1399 Local
[2] = DST_S_C_SRC_FORMFEED
;
1401 * Declare source file
1403 Local
[3] = DST_S_C_SRC_DECLFILE
;
1404 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1413 COPY_SHORT (cp
, ID_Number
);
1417 * Creation Date. Unknown, so we fill with zeroes.
1442 #else /* Use this code when assembling for VMS on a VMS system */
1446 memcpy (cp
, (char *) &Date_Xab
.xab$q_cdt
, 8);
1451 COPY_LONG (cp
, File_Header_Xab
.xab$l_ebk
);
1456 COPY_SHORT (cp
, File_Header_Xab
.xab$w_ffb
);
1461 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1471 * Library module name (none)
1477 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1483 * Give the number of source lines to the debugger
1486 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1488 int Starting_Line_Number
;
1489 int Number_Of_Lines
;
1497 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1499 * Source declaration
1501 Local
[1] = DST_S_C_SOURCE
;
1506 *cp
++ = DST_S_C_SRC_SETFILE
;
1510 COPY_SHORT (cp
, ID_Number
);
1515 *cp
++ = DST_S_C_SRC_SETREC_L
;
1516 COPY_LONG (cp
, Starting_Line_Number
);
1521 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1522 COPY_SHORT (cp
, Number_Of_Lines
);
1527 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1533 * This routine locates a file in the list of files. If an entry does not
1534 * exist, one is created. For include files, a new entry is always created
1535 * such that inline functions can be properly debugged.
1537 static struct input_file
*
1541 struct input_file
*same_file
= 0;
1542 struct input_file
*fpnt
, *last
= 0;
1545 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1547 if (fpnt
->spnt
== sp
)
1551 sp_name
= S_GET_NAME (sp
);
1552 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1554 if (strcmp (sp_name
, fpnt
->name
) == 0)
1556 if (fpnt
->flag
== 1)
1562 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1568 fpnt
->name
= sp_name
;
1569 fpnt
->min_line
= 0x7fffffff;
1573 fpnt
->file_number
= 0;
1575 fpnt
->same_file_fpnt
= same_file
;
1580 * The following functions and definitions are used to generate object records
1581 * that will describe program variables to the VMS debugger.
1583 * This file contains many of the routines needed to output debugging info into
1584 * the object file that the VMS debugger needs to understand symbols. These
1585 * routines are called very late in the assembly process, and thus we can be
1586 * fairly lax about changing things, since the GSD and the TIR sections have
1587 * already been output.
1591 /* This routine converts a number string into an integer, and stops when it
1592 * sees an invalid character. The return value is the address of the character
1593 * just past the last character read. No error is generated.
1596 cvt_integer (str
, rtn
)
1601 neg
= *str
== '-' ? ++str
, -1 : 1;
1603 while ((*str
<= '9') && (*str
>= '0'))
1604 ival
= 10 * ival
+ *str
++ - '0';
1609 /* this routine fixes the names that are generated by C++, ".this" is a good
1610 * example. The period does not work for the debugger, since it looks like
1611 * the syntax for a structure element, and thus it gets mightily confused
1613 * We also use this to strip the PsectAttribute hack from the name before we
1614 * write a debugger record */
1622 * Kill any leading "_"
1627 * Is there a Psect Attribute to skip??
1629 if (HAS_PSECT_ATTRIBUTES (pnt
))
1634 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1637 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1645 /* Here we fix the .this -> $this conversion */
1646 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1654 /* When defining a structure, this routine is called to find the name of
1655 * the actual structure. It is assumed that str points to the equal sign
1656 * in the definition, and it moves backward until it finds the start of the
1657 * name. If it finds a 0, then it knows that this structure def is in the
1658 * outermost level, and thus symbol_name points to the symbol name.
1661 get_struct_name (str
)
1666 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1669 return (char *) symbol_name
;
1671 while ((*pnt
!= ';') && (*pnt
!= '='))
1675 while ((*pnt
< '0') || (*pnt
> '9'))
1677 while ((*pnt
>= '0') && (*pnt
<= '9'))
1682 /* search symbol list for type number dbx_type. Return a pointer to struct */
1683 static struct VMS_DBG_Symbol
*
1684 find_symbol (dbx_type
)
1687 struct VMS_DBG_Symbol
*spnt
;
1689 spnt
= VMS_Symbol_type_list
[SYMTYP_HASH (dbx_type
)];
1692 if (spnt
->dbx_type
== dbx_type
)
1696 if (!spnt
|| spnt
->advanced
!= ALIAS
)
1698 return find_symbol (spnt
->type2
);
1702 #if 0 /* obsolete */
1703 /* this routine puts info into either Local or Asuffix, depending on the sign
1704 * of size. The reason is that it is easier to build the variable descriptor
1705 * backwards, while the array descriptor is best built forwards. In the end
1706 * they get put together, if there is not a struct/union/enum along the way
1722 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1726 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1729 Apoint
= MAX_DEBUG_RECORD
- 1;
1732 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1743 if (Apoint
+ size
>= MAX_DEBUG_RECORD
)
1746 Apoint
= MAX_DEBUG_RECORD
- 1;
1750 Asuffix
[Apoint
++] = (char) value
;
1753 md_number_to_chars (&Asuffix
[Apoint
], value
, size
);
1769 Local
[Lpnt
--] = (char) value
;
1773 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size
);
1777 /* this routine generates the array descriptor for a given array */
1779 array_suffix (spnt2
)
1780 struct VMS_DBG_Symbol
*spnt2
;
1782 struct VMS_DBG_Symbol
*spnt
;
1783 struct VMS_DBG_Symbol
*spnt1
;
1789 while (spnt
->advanced
!= ARRAY
)
1791 spnt
= find_symbol (spnt
->type2
);
1792 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1797 while (spnt1
->advanced
== ARRAY
)
1800 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1801 spnt1
= find_symbol (spnt1
->type2
);
1803 total_size
= total_size
* spnt1
->data_size
;
1804 fpush (spnt1
->data_size
, 2); /* element size */
1805 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1808 fpush (spnt1
->VMS_type
, 1); /* element type */
1809 fpush (DSC_K_CLASS_A
, 1); /* descriptor class */
1810 fpush (0, 4); /* base address */
1811 fpush (0, 1); /* scale factor -- not applicable */
1812 fpush (0, 1); /* digit count -- not applicable */
1813 fpush (0xc0, 1); /* flags: multiplier block & bounds present */
1814 fpush (rank
, 1); /* number of dimensions */
1815 fpush (total_size
, 4);
1816 fpush (0, 4); /* pointer to element [0][0]...[0] */
1818 while (spnt1
->advanced
== ARRAY
)
1820 fpush (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1821 spnt1
= find_symbol (spnt1
->type2
);
1824 while (spnt1
->advanced
== ARRAY
)
1826 fpush (spnt1
->index_min
, 4);
1827 fpush (spnt1
->index_max
, 4);
1828 spnt1
= find_symbol (spnt1
->type2
);
1832 /* this routine generates the start of a variable descriptor based upon
1833 * a struct/union/enum that has yet to be defined. We define this spot as
1834 * a new location, and save four bytes for the address. When the struct is
1835 * finally defined, then we can go back and plug in the correct address.
1838 new_forward_ref (dbx_type
)
1841 struct forward_ref
*fpnt
;
1842 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1843 fpnt
->next
= f_ref_root
;
1845 fpnt
->dbx_type
= dbx_type
;
1846 fpnt
->struc_numb
= ++structure_count
;
1847 fpnt
->resolved
= 'N';
1848 rpush (DST_K_TS_IND
, 1); /* indirect type specification */
1850 rpush (total_len
, 2);
1851 struct_number
= -fpnt
->struc_numb
;
1854 /* this routine generates the variable descriptor used to describe non-basic
1855 * variables. It calls itself recursively until it gets to the bottom of it
1856 * all, and then builds the descriptor backwards. It is easiest to do it this
1857 *way since we must periodically write length bytes, and it is easiest if we know
1858 *the value when it is time to write it.
1861 gen1 (spnt
, array_suffix_len
)
1862 struct VMS_DBG_Symbol
*spnt
;
1863 int array_suffix_len
;
1865 struct VMS_DBG_Symbol
*spnt1
;
1868 switch (spnt
->advanced
)
1871 rpush (DBG_S_C_VOID
, 1);
1873 rpush (total_len
, 2);
1877 if (array_suffix_len
== 0)
1879 rpush (spnt
->VMS_type
, 1);
1880 rpush (DBG_S_C_BASIC
, 1);
1882 rpush (total_len
, 2);
1886 rpush (DST_K_VFLAGS_DSC
, 1);
1887 rpush (DST_K_TS_DSC
, 1); /* descriptor type specification */
1893 struct_number
= spnt
->struc_numb
;
1894 if (struct_number
< 0)
1896 new_forward_ref (spnt
->dbx_type
);
1899 rpush (DBG_S_C_STRUCT
, 1);
1901 rpush (total_len
, 2);
1904 spnt1
= find_symbol (spnt
->type2
);
1907 new_forward_ref (spnt
->type2
);
1909 i
= gen1 (spnt1
, 0);
1911 { /* (*void) is a special case, do not put pointer suffix */
1912 rpush (DBG_S_C_POINTER
, 1);
1914 rpush (total_len
, 2);
1919 while (spnt1
->advanced
== ARRAY
)
1921 spnt1
= find_symbol (spnt1
->type2
);
1924 as_tsktsk ("debugger forward reference error, dbx type %d",
1929 /* It is too late to generate forward references, so the user gets a message.
1930 * This should only happen on a compiler error */
1931 (void) gen1 (spnt1
, 1);
1933 array_suffix (spnt
);
1934 array_suffix_len
= Apoint
- i
;
1935 switch (spnt1
->advanced
)
1943 rpush (total_len
, 2);
1944 rpush (DST_K_VFLAGS_DSC
, 1);
1945 rpush (1, 1); /* flags: element value spec included */
1946 rpush (1, 1); /* one dimension */
1947 rpush (DBG_S_C_COMPLEX_ARRAY
, 1);
1949 total_len
+= array_suffix_len
+ 8;
1950 rpush (total_len
, 2);
1952 default: /* lint suppression */
1958 /* This generates a suffix for a variable. If it is not a defined type yet,
1959 * then dbx_type contains the type we are expecting so we can generate a
1960 * forward reference. This calls gen1 to build most of the descriptor, and
1961 * then it puts the icing on at the end. It then dumps whatever is needed
1962 * to get a complete descriptor (i.e. struct reference, array suffix ).
1965 generate_suffix (spnt
, dbx_type
)
1966 struct VMS_DBG_Symbol
*spnt
;
1969 static const char pvoid
[6] = {
1970 5, /* record.length == 5 */
1971 DST_K_TYPSPEC
, /* record.type == 1 (type specification) */
1972 0, /* name.length == 0, no name follows */
1973 1, 0, /* type.length == 1 {2 bytes, little endian} */
1974 DBG_S_C_VOID
/* type.type == 5 (pointer to unspecified) */
1979 Lpnt
= MAX_DEBUG_RECORD
- 1;
1984 new_forward_ref (dbx_type
);
1987 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1988 return; /* no suffix needed */
1991 rpush (0, 1); /* no name (len==0) */
1992 rpush (DST_K_TYPSPEC
, 1);
1994 rpush (total_len
, 1);
1995 /* if the variable descriptor overflows the record, output a descriptor for
1996 * a pointer to void.
1998 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
2000 as_warn ("Variable descriptor %d too complicated. Defined as `void *'.",
2002 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
2006 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
2007 Local
[i
++] = Local
[++Lpnt
];
2009 /* we use this for a reference to a structure that has already been defined */
2010 if (struct_number
> 0)
2012 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2014 VMS_Store_Struct (struct_number
);
2016 /* We use this for a forward reference to a structure that has yet to be
2017 * defined. We store four bytes of zero to make room for the actual address
2020 if (struct_number
< 0)
2022 struct_number
= -struct_number
;
2023 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2025 VMS_Def_Struct (struct_number
);
2026 COPY_LONG (&Local
[Lpnt
], 0L);
2028 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2033 Local
[Lpnt
++] = Asuffix
[i
++];
2035 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2039 /* "novel length" type doesn't work for simple atomic types */
2040 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
2041 #undef SETUP_BASIC_TYPES
2044 bitfield_suffix (spnt
, width
)
2045 struct VMS_DBG_Symbol
*spnt
;
2048 Local
[Lpnt
++] = 13; /* rec.len==13 */
2049 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* a type specification record */
2050 Local
[Lpnt
++] = 0; /* not named */
2051 COPY_SHORT (&Local
[Lpnt
], 9); /* typ.len==9 */
2053 Local
[Lpnt
++] = DST_K_TS_NOV_LENG
; /* This type is a "novel length"
2054 incarnation of some other type. */
2055 COPY_LONG (&Local
[Lpnt
], width
); /* size in bits == novel length */
2057 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2059 /* assert( spnt->struc_numb > 0 ); */
2060 VMS_Store_Struct (spnt
->struc_numb
); /* output 4 more bytes */
2063 /* Formally define a builtin type, so that it can serve as the target of
2064 an indirect reference. It makes bitfield_suffix() easier by avoiding
2065 the need to use a forward reference for the first occurrence of each
2066 type used in a bitfield. */
2068 setup_basic_type (spnt
)
2069 struct VMS_DBG_Symbol
*spnt
;
2071 #ifdef SETUP_BASIC_TYPES
2072 /* This would be very useful if "novel length" fields actually worked
2073 with basic types like they do with enumerated types. However,
2074 they do not, so this isn't worth doing just so that you can use
2075 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
2077 #ifndef SETUP_SYNONYM_TYPES
2078 /* This determines whether compatible things like `int' and `long int'
2079 ought to have distinct type records rather than sharing one. */
2080 struct VMS_DBG_Symbol
*spnt2
;
2082 /* first check whether this type has already been seen by another name */
2083 for (spnt2
= VMS_Symbol_type_list
[SYMTYP_HASH (spnt
->VMS_type
)];
2085 spnt2
= spnt2
->next
)
2086 if (spnt2
!= spnt
&& spnt2
->VMS_type
== spnt
->VMS_type
)
2088 spnt
->struc_numb
= spnt2
->struc_numb
;
2093 /* `structure number' doesn't really mean `structure'; it means an index
2094 into a linker maintained set of saved locations which can be referenced
2096 spnt
->struc_numb
= ++structure_count
;
2097 VMS_Def_Struct (spnt
->struc_numb
); /* remember where this type lives */
2098 /* define the simple scalar type */
2099 Local
[Lpnt
++] = 6 + strlen (symbol_name
) + 2; /* rec.len */
2100 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* rec.typ==type specification */
2101 Local
[Lpnt
++] = strlen (symbol_name
) + 2;
2102 Local
[Lpnt
++] = '_'; /* prefix name with "__" */
2103 Local
[Lpnt
++] = '_';
2104 for (p
= symbol_name
; *p
; p
++)
2105 Local
[Lpnt
++] = *p
== ' ' ? '_' : *p
;
2106 COPY_SHORT (&Local
[Lpnt
], 2); /* typ.len==2 */
2108 Local
[Lpnt
++] = DST_K_TS_ATOM
; /* typ.kind is simple type */
2109 Local
[Lpnt
++] = spnt
->VMS_type
; /* typ.type */
2110 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2112 #endif /* SETUP_BASIC_TYPES */
2116 /* This routine generates a symbol definition for a C symbol for the debugger.
2117 * It takes a psect and offset for global symbols; if psect < 0, then this is
2118 * a local variable and the offset is relative to FP. In this case it can
2119 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2122 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2123 struct VMS_DBG_Symbol
*spnt
;
2132 /* if there are bad characters in name, convert them */
2133 Name_pnt
= fix_name (Name
);
2135 len
= strlen (Name_pnt
);
2137 { /* this is a local variable, referenced to SP */
2138 Local
[i
++] = 7 + len
;
2139 Local
[i
++] = spnt
->VMS_type
;
2140 Local
[i
++] = (Offset
> 0) ? DBG_C_FUNCTION_PARAM
: DBG_C_LOCAL_SYM
;
2141 COPY_LONG (&Local
[i
], Offset
);
2146 Local
[i
++] = 7 + len
;
2147 Local
[i
++] = spnt
->VMS_type
;
2148 Local
[i
++] = DST_K_VALKIND_ADDR
;
2149 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2151 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2154 while (*Name_pnt
!= '\0')
2155 Local
[i
++] = *Name_pnt
++;
2156 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2157 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2158 generate_suffix (spnt
, 0);
2162 /* This routine parses the stabs entries in order to make the definition
2163 * for the debugger of local symbols and function parameters
2166 VMS_local_stab_Parse (sp
)
2172 struct VMS_DBG_Symbol
*spnt
;
2176 str
= S_GET_NAME (sp
);
2177 pnt
= (char *) strchr (str
, ':');
2178 if (pnt
== (char *) NULL
)
2179 return; /* no colon present */
2180 pnt1
= pnt
++; /* save this for later, and skip colon */
2182 return; /* ignore static constants */
2184 /* there is one little catch that we must be aware of. Sometimes function
2185 * parameters are optimized into registers, and the compiler, in its infiite
2186 * wisdom outputs stabs records for *both*. In general we want to use the
2187 * register if it is present, so we must search the rest of the symbols for
2188 * this function to see if this parameter is assigned to a register.
2196 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2198 if (!S_IS_DEBUG (sp1
))
2200 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2202 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2203 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2205 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2207 str1
= S_GET_NAME (sp1
); /* and get the name */
2209 while (*pnt2
!= ':')
2216 if ((*str1
!= ':') || (*pnt2
!= ':'))
2218 return; /* they are the same! lets skip this one */
2220 /* first find the dbx symbol type from list, and then find VMS type */
2221 pnt
++; /* skip p in case no register */
2224 pnt
= cvt_integer (pnt
, &dbx_type
);
2225 spnt
= find_symbol (dbx_type
);
2227 return; /*Dunno what this is*/
2229 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2230 *pnt1
= ':'; /* and restore the string */
2234 /* This routine parses a stabs entry to find the information required to define
2235 * a variable. It is used for global and static variables.
2236 * Basically we need to know the address of the symbol. With older versions
2237 * of the compiler, const symbols are
2238 * treated differently, in that if they are global they are written into the
2239 * text psect. The global symbol entry for such a const is actually written
2240 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2241 * of psects, we must search the entry points as well. static consts are even
2242 * harder, since they are never assigned a memory address. The compiler passes
2243 * a stab to tell us the value, but I am not sure what to do with it.
2247 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2249 int expected_type
; /* char */
2250 int type1
, type2
, Text_Psect
;
2256 struct VMS_DBG_Symbol
*spnt
;
2257 struct VMS_Symbol
*vsp
;
2261 str
= S_GET_NAME (sp
);
2262 pnt
= (char *) strchr (str
, ':');
2263 if (pnt
== (char *) NULL
)
2264 return; /* no colon present */
2265 pnt1
= pnt
; /* save this for later*/
2267 if (*pnt
== expected_type
)
2269 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2270 spnt
= find_symbol (dbx_type
);
2271 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2272 return; /*Dunno what this is*/
2273 /* now we need to search the symbol table to find the psect and offset for
2278 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2280 pnt
= S_GET_NAME (vsp
->Symbol
);
2281 if (pnt
!= (char *) NULL
)
2283 /* make sure name is the same, and make sure correct symbol type */
2284 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2285 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2286 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2290 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2292 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2293 *pnt1
= ':'; /* and restore the string */
2296 /* the symbol was not in the symbol list, but it may be an "entry point"
2297 if it was a constant */
2298 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2301 * Dispatch on STAB type
2303 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2305 pnt
= S_GET_NAME (sp1
);
2308 if (strcmp (pnt
, str
) == 0)
2310 if (!gave_compiler_message
&& expected_type
== 'G')
2312 static const char long_const_msg
[] = "\
2313 ***Warning - the assembly code generated by the compiler has placed \n\
2314 global constant(s) in the text psect. These will not be available to \n\
2315 other modules, since this is not the correct way to handle this. You \n\
2316 have two options: 1) get a patched compiler that does not put global \n\
2317 constants in the text psect, or 2) remove the 'const' keyword from \n\
2318 definitions of global variables in your source module(s). Don't say \n\
2319 I didn't warn you! \n";
2321 as_tsktsk (long_const_msg
);
2322 gave_compiler_message
= 1;
2324 VMS_DBG_record (spnt
,
2329 *S_GET_NAME (sp1
) = 'L';
2330 /* fool assembler to not output this
2331 * as a routine in the TBT */
2336 *pnt1
= ':'; /* and restore the string */
2341 VMS_GSYM_Parse (sp
, Text_Psect
)
2344 { /* Global variables */
2345 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2350 VMS_LCSYM_Parse (sp
, Text_Psect
)
2353 { /* Static symbols - uninitialized */
2354 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2358 VMS_STSYM_Parse (sp
, Text_Psect
)
2361 { /* Static symbols - initialized */
2362 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2366 /* for register symbols, we must figure out what range of addresses within the
2367 * psect are valid. We will use the brackets in the stab directives to give us
2368 * guidance as to the PC range that this variable is in scope. I am still not
2369 * completely comfortable with this but as I learn more, I seem to get a better
2370 * handle on what is going on.
2374 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2375 symbolS
*sp
, *Current_Routine
;
2382 struct VMS_DBG_Symbol
*spnt
;
2386 int Min_Offset
= -1; /* min PC of validity */
2387 int Max_Offset
= 0; /* max PC of validity */
2390 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2393 * Dispatch on STAB type
2395 switch (S_GET_RAW_TYPE (symbolP
))
2399 Min_Offset
= S_GET_VALUE (symbolP
);
2403 Max_Offset
= S_GET_VALUE (symbolP
) - 1;
2406 if ((Min_Offset
!= -1) && (bcnt
== 0))
2408 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2410 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2411 if (*pnt
== 'F' || *pnt
== 'f') break;
2415 /* Check to see that the addresses were defined. If not, then there were no
2416 * brackets in the function, and we must try to search for the next function.
2417 * Since functions can be in any order, we should search all of the symbol
2418 * list to find the correct ending address. */
2419 if (Min_Offset
== -1)
2421 int Max_Source_Offset
;
2423 Min_Offset
= S_GET_VALUE (sp
);
2424 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2427 * Dispatch on STAB type
2429 switch (S_GET_RAW_TYPE (symbolP
))
2431 case N_TEXT
| N_EXT
:
2432 This_Offset
= S_GET_VALUE (symbolP
);
2433 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2434 Max_Offset
= This_Offset
;
2437 This_Offset
= S_GET_VALUE (symbolP
);
2438 if (This_Offset
> Max_Source_Offset
)
2439 Max_Source_Offset
= This_Offset
;
2443 /* if this is the last routine, then we use the PC of the last source line
2444 * as a marker of the max PC for which this reg is valid */
2445 if (Max_Offset
== 0x7fffffff)
2446 Max_Offset
= Max_Source_Offset
;
2449 str
= S_GET_NAME (sp
);
2450 pnt
= (char *) strchr (str
, ':');
2451 if (pnt
== (char *) NULL
)
2452 return; /* no colon present */
2453 pnt1
= pnt
; /* save this for later*/
2457 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2458 spnt
= find_symbol (dbx_type
);
2460 return; /*Dunno what this is yet*/
2462 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2464 Local
[i
++] = 25 + len
;
2465 Local
[i
++] = spnt
->VMS_type
;
2466 Local
[i
++] = DST_K_VFLAGS_TVS
; /* trailing value specified */
2467 COPY_LONG (&Local
[i
], 1 + len
); /* relative offset, beyond name */
2469 Local
[i
++] = len
; /* name length (ascic prefix) */
2470 while (*pnt
!= '\0')
2471 Local
[i
++] = *pnt
++;
2472 Local
[i
++] = DST_K_VS_FOLLOWS
; /* value specification follows */
2473 COPY_SHORT (&Local
[i
], 15); /* length of rest of record */
2475 Local
[i
++] = DST_K_VS_ALLOC_SPLIT
; /* split lifetime */
2476 Local
[i
++] = 1; /* one binding follows */
2477 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2479 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2480 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2481 Local
[i
++] = DST_K_VALKIND_REG
; /* nested value spec */
2482 COPY_LONG (&Local
[i
], S_GET_VALUE (sp
));
2484 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2486 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2487 generate_suffix (spnt
, 0);
2490 /* this function examines a structure definition, checking all of the elements
2491 * to make sure that all of them are fully defined. The only thing that we
2492 * kick out are arrays of undefined structs, since we do not know how big
2493 * they are. All others we can handle with a normal forward reference.
2496 forward_reference (pnt
)
2500 struct VMS_DBG_Symbol
*spnt
;
2501 struct VMS_DBG_Symbol
*spnt1
;
2502 pnt
= cvt_integer (pnt
+ 1, &i
);
2504 return 0; /* no forward references */
2507 pnt
= (char *) strchr (pnt
, ':');
2508 pnt
= cvt_integer (pnt
+ 1, &i
);
2509 spnt
= find_symbol (i
);
2511 while (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
)
2514 spnt1
= find_symbol (spnt
->type2
);
2515 if ((spnt
->advanced
== ARRAY
) &&
2516 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2518 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2523 pnt
= cvt_integer (pnt
+ 1, &i
);
2524 pnt
= cvt_integer (pnt
+ 1, &i
);
2525 } while (*++pnt
!= ';');
2526 return 0; /* no forward refences found */
2529 /* Used to check a single element of a structure on the final pass*/
2532 final_forward_reference (spnt
)
2533 struct VMS_DBG_Symbol
*spnt
;
2535 struct VMS_DBG_Symbol
*spnt1
;
2537 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2539 spnt1
= find_symbol (spnt
->type2
);
2540 if (spnt
->advanced
== ARRAY
&& !spnt1
) return 1;
2543 return 0; /* no forward refences found */
2546 /* This routine parses the stabs directives to find any definitions of dbx type
2547 * numbers. It makes a note of all of them, creating a structure element
2548 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2549 * debugger that describes the struct/union/enum, so that further references
2550 * to these data types will be by number
2551 * We have to process pointers right away, since there can be references
2552 * to them later in the same stabs directive. We cannot have forward
2553 * references to pointers, (but we can have a forward reference to a pointer to
2554 * a structure/enum/union) and this is why we process them immediately.
2555 * After we process the pointer, then we search for defs that are nested even
2557 * 8/15/92: We have to process arrays right away too, because there can
2558 * be multiple references to identical array types in one structure
2559 * definition, and only the first one has the definition. (We tend to
2560 * parse from the back going forward.
2563 VMS_typedef_parse (str
)
2571 struct forward_ref
*fpnt
;
2572 int i1
, i2
, i3
, len
;
2573 struct VMS_DBG_Symbol
*spnt
;
2574 struct VMS_DBG_Symbol
*spnt1
;
2576 /* check for any nested def's */
2577 pnt
= (char *) strchr (str
+ 1, '=');
2578 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2579 && (str
[1] != 'a' || str
[2] != 'r'))
2580 if (VMS_typedef_parse (pnt
) == 1)
2582 /* now find dbx_type of entry */
2585 { /* check for static constants */
2586 *str
= '\0'; /* for now we ignore them */
2589 while ((*pnt
<= '9') && (*pnt
>= '0'))
2591 pnt
++; /* and get back to the number */
2592 cvt_integer (pnt
, &i1
);
2593 spnt
= find_symbol (i1
);
2594 /* first we see if this has been defined already, due to a forward reference*/
2597 i2
= SYMTYP_HASH (i1
);
2598 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2599 spnt
->next
= VMS_Symbol_type_list
[i2
];
2600 VMS_Symbol_type_list
[i2
] = spnt
;
2601 spnt
->dbx_type
= i1
; /* and save the type */
2602 spnt
->type2
= spnt
->VMS_type
= spnt
->data_size
= 0;
2603 spnt
->index_min
= spnt
->index_max
= spnt
->struc_numb
= 0;
2605 /* for structs and unions, do a partial parse, otherwise we sometimes get
2606 * circular definitions that are impossible to resolve. We read enough info
2607 * so that any reference to this type has enough info to be resolved
2609 pnt
= str
+ 1; /* point to character past equal sign */
2610 if ((*pnt
== 'u') || (*pnt
== 's'))
2613 if ((*pnt
<= '9') && (*pnt
>= '0'))
2615 if (type_check ("void"))
2616 { /* this is the void symbol */
2618 spnt
->advanced
= VOID
;
2621 if (type_check ("unknown type"))
2624 spnt
->advanced
= UNKNOWN
;
2627 pnt1
= cvt_integer (pnt
, &i1
);
2628 if (i1
!= spnt
->dbx_type
)
2630 spnt
->advanced
= ALIAS
;
2635 as_tsktsk ("debugginer output: %d is an unknown untyped variable.",
2637 return 1; /* do not know what this is */
2639 /* now define this module*/
2640 pnt
= str
+ 1; /* point to character past equal sign */
2644 spnt
->advanced
= BASIC
;
2645 if (type_check ("int"))
2647 spnt
->VMS_type
= DBG_S_C_SLINT
;
2648 spnt
->data_size
= 4;
2650 else if (type_check ("long int"))
2652 spnt
->VMS_type
= DBG_S_C_SLINT
;
2653 spnt
->data_size
= 4;
2655 else if (type_check ("unsigned int"))
2657 spnt
->VMS_type
= DBG_S_C_ULINT
;
2658 spnt
->data_size
= 4;
2660 else if (type_check ("long unsigned int"))
2662 spnt
->VMS_type
= DBG_S_C_ULINT
;
2663 spnt
->data_size
= 4;
2665 else if (type_check ("short int"))
2667 spnt
->VMS_type
= DBG_S_C_SSINT
;
2668 spnt
->data_size
= 2;
2670 else if (type_check ("short unsigned int"))
2672 spnt
->VMS_type
= DBG_S_C_USINT
;
2673 spnt
->data_size
= 2;
2675 else if (type_check ("char"))
2677 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2678 spnt
->data_size
= 1;
2680 else if (type_check ("signed char"))
2682 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2683 spnt
->data_size
= 1;
2685 else if (type_check ("unsigned char"))
2687 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2688 spnt
->data_size
= 1;
2690 else if (type_check ("float"))
2692 spnt
->VMS_type
= DBG_S_C_REAL4
;
2693 spnt
->data_size
= 4;
2695 else if (type_check ("double"))
2697 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2698 spnt
->data_size
= 8;
2700 else if (type_check ("long double"))
2702 /* same as double, at least for now */
2703 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2704 spnt
->data_size
= 8;
2706 else if (type_check ("long long int"))
2708 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2709 spnt
->data_size
= 8;
2711 else if (type_check ("long long unsigned int"))
2713 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2714 spnt
->data_size
= 8;
2716 else if (type_check ("complex float"))
2718 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2719 spnt
->data_size
= 2 * 4;
2721 else if (type_check ("complex double"))
2723 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2724 spnt
->data_size
= 2 * 8;
2726 else if (type_check ("complex long double"))
2728 /* same as complex double, at least for now */
2729 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2730 spnt
->data_size
= 2 * 8;
2735 * Shouldn't get here, but if we do, something
2736 * more substantial ought to be done...
2739 spnt
->data_size
= 0;
2741 if (spnt
->VMS_type
!= 0)
2742 setup_basic_type (spnt
);
2743 pnt1
= (char *) strchr (str
, ';') + 1;
2747 spnt
->advanced
= (*pnt
== 's') ? STRUCT
: UNION
;
2748 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2749 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2750 if (!final_pass
&& forward_reference (pnt
))
2752 spnt
->struc_numb
= -1;
2755 spnt
->struc_numb
= ++structure_count
;
2757 pnt
= get_struct_name (str
);
2758 VMS_Def_Struct (spnt
->struc_numb
);
2760 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2761 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2763 fpnt
->resolved
= 'Y';
2764 VMS_Set_Struct (fpnt
->struc_numb
);
2765 VMS_Store_Struct (spnt
->struc_numb
);
2769 VMS_Set_Struct (spnt
->struc_numb
);
2771 Local
[i
++] = 11 + strlen (pnt
);
2772 Local
[i
++] = DBG_S_C_STRUCT_START
;
2773 Local
[i
++] = DST_K_VFLAGS_NOVAL
; /* structure definition only */
2774 COPY_LONG (&Local
[i
], 0L); /* hence value is unused */
2776 Local
[i
++] = strlen (pnt
);
2778 while (*pnt2
!= '\0')
2779 Local
[i
++] = *pnt2
++;
2780 i2
= spnt
->data_size
* 8; /* number of bits */
2781 COPY_LONG (&Local
[i
], i2
);
2783 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2785 if (pnt
!= symbol_name
)
2787 pnt
+= strlen (pnt
);
2789 } /* replace colon for later */
2790 while (*++pnt1
!= ';')
2792 pnt
= (char *) strchr (pnt1
, ':');
2795 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2796 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2797 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2798 spnt1
= find_symbol (dtype
);
2799 len
= strlen (pnt2
);
2800 if (spnt1
&& (spnt1
->advanced
== BASIC
|| spnt1
->advanced
== ENUM
)
2801 && ((i3
!= spnt1
->data_size
* 8) || (i2
% 8 != 0)))
2803 if (USE_BITSTRING_DESCRIPTOR (spnt1
))
2805 /* This uses a type descriptor, which doesn't work if
2806 the enclosing structure has been placed in a register.
2807 Also, enum bitfields degenerate to simple integers. */
2808 int unsigned_type
= (spnt1
->VMS_type
== DBG_S_C_ULINT
2809 || spnt1
->VMS_type
== DBG_S_C_USINT
2810 || spnt1
->VMS_type
== DBG_S_C_UCHAR
2811 || spnt1
->VMS_type
== DBG_S_C_UQUAD
2812 || spnt1
->advanced
== ENUM
); /* (approximate) */
2814 fpush (19 + len
, 1);
2815 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2816 fpush (DST_K_VFLAGS_DSC
, 1); /* specified by descriptor */
2817 fpush (1 + len
, 4); /* relative offset to descriptor */
2818 fpush (len
, 1); /* length byte (ascic prefix) */
2819 while (*pnt2
!= '\0') /* name bytes */
2821 fpush (i3
, 2); /* dsc length == size of bitfield */
2822 /* dsc type == un?signed bitfield */
2823 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2824 fpush (DSC_K_CLASS_UBS
, 1); /* dsc class == unaligned bitstring */
2825 fpush (0x00, 4); /* dsc pointer == zeroes */
2826 fpush (i2
, 4); /* start position */
2827 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2832 /* Use a "novel length" type specification, which works
2833 right for register structures and for enum bitfields
2834 but results in larger object modules. */
2835 Local
[i
++] = 7 + len
;
2836 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
; /* type spec follows */
2837 Local
[i
++] = DBG_S_C_STRUCT_ITEM
; /* value is a bit offset */
2838 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2840 Local
[i
++] = strlen (pnt2
);
2841 while (*pnt2
!= '\0')
2842 Local
[i
++] = *pnt2
++;
2843 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2845 bitfield_suffix (spnt1
, i3
);
2849 { /* not a bitfield */
2850 /* check if this is a forward reference */
2851 if (final_pass
&& final_forward_reference (spnt1
))
2853 as_tsktsk ("debugger output: structure element `%s' has undefined type",
2857 Local
[i
++] = 7 + len
;
2858 Local
[i
++] = spnt1
? spnt1
->VMS_type
: DBG_S_C_ADVANCED_TYPE
;
2859 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2860 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2862 Local
[i
++] = strlen (pnt2
);
2863 while (*pnt2
!= '\0')
2864 Local
[i
++] = *pnt2
++;
2865 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2868 generate_suffix (spnt1
, dtype
);
2869 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2870 generate_suffix (spnt1
, 0);
2874 Local
[i
++] = 0x01; /* length byte */
2875 Local
[i
++] = DBG_S_C_STRUCT_END
;
2876 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2880 spnt
->advanced
= ENUM
;
2881 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2882 spnt
->struc_numb
= ++structure_count
;
2883 spnt
->data_size
= 4;
2884 VMS_Def_Struct (spnt
->struc_numb
);
2886 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2887 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2889 fpnt
->resolved
= 'Y';
2890 VMS_Set_Struct (fpnt
->struc_numb
);
2891 VMS_Store_Struct (spnt
->struc_numb
);
2895 VMS_Set_Struct (spnt
->struc_numb
);
2897 len
= strlen (symbol_name
);
2898 Local
[i
++] = 3 + len
;
2899 Local
[i
++] = DBG_S_C_ENUM_START
;
2900 Local
[i
++] = 4 * 8; /* enum values are 32 bits */
2903 while (*pnt2
!= '\0')
2904 Local
[i
++] = *pnt2
++;
2905 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2907 while (*++pnt
!= ';')
2909 pnt1
= (char *) strchr (pnt
, ':');
2911 pnt1
= cvt_integer (pnt1
, &i1
);
2913 Local
[i
++] = 7 + len
;
2914 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2915 Local
[i
++] = DST_K_VALKIND_LITERAL
;
2916 COPY_LONG (&Local
[i
], i1
);
2920 while (*pnt
!= '\0')
2921 Local
[i
++] = *pnt
++;
2922 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2924 pnt
= pnt1
; /* Skip final semicolon */
2926 Local
[i
++] = 0x01; /* len byte */
2927 Local
[i
++] = DBG_S_C_ENUM_END
;
2928 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2933 spnt
->advanced
= ARRAY
;
2934 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2935 pnt
= (char *) strchr (pnt
, ';');
2938 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2939 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2940 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2941 pnt
= (char *) strchr (str
+ 1, '=');
2942 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2946 spnt
->advanced
= FUNCTION
;
2947 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2948 /* this masquerades as a basic type*/
2949 spnt
->data_size
= 4;
2950 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2953 spnt
->advanced
= POINTER
;
2954 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2955 spnt
->data_size
= 4;
2956 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2957 pnt
= (char *) strchr (str
+ 1, '=');
2958 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2962 spnt
->advanced
= UNKNOWN
;
2964 as_tsktsk ("debugger output: %d is an unknown type of variable.",
2966 return 1; /* unable to decipher */
2968 /* this removes the evidence of the definition so that the outer levels of
2969 parsing do not have to worry about it */
2971 while (*pnt1
!= '\0')
2979 * This is the root routine that parses the stabs entries for definitions.
2980 * it calls VMS_typedef_parse, which can in turn call itself.
2981 * We need to be careful, since sometimes there are forward references to
2982 * other symbol types, and these cannot be resolved until we have completed
2985 * Also check and see if we are using continuation stabs, if we are, then
2986 * paste together the entire contents of the stab before we pass it to
2987 * VMS_typedef_parse.
2996 char *parse_buffer
= 0;
2998 int incomplete
, pass
, incom1
;
2999 struct forward_ref
*fpnt
;
3007 incom1
= incomplete
;
3009 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
3012 * Deal with STAB symbols
3014 if (S_IS_DEBUG (sp
))
3017 * Dispatch on STAB type
3019 switch (S_GET_RAW_TYPE (sp
))
3027 case N_FUN
: /*sometimes these contain typedefs*/
3028 str
= S_GET_NAME (sp
);
3030 pnt
= str
+ strlen (str
) - 1;
3031 if (*pnt
== '?') /* Continuation stab. */
3038 tlen
+= strlen (str
) - 1;
3039 spnext
= symbol_next (spnext
);
3040 str
= S_GET_NAME (spnext
);
3041 pnt
= str
+ strlen (str
) - 1;
3042 } while (*pnt
== '?');
3043 tlen
+= strlen (str
);
3044 parse_buffer
= (char *) xmalloc (tlen
+ 1);
3045 strcpy (parse_buffer
, S_GET_NAME (sp
));
3046 pnt2
= parse_buffer
+ strlen(parse_buffer
) - 1;
3050 spnext
= symbol_next (spnext
);
3051 str
= S_GET_NAME (spnext
);
3053 pnt2
+= strlen (str
) - 1;
3054 *str
= '\0'; /* Erase this string */
3055 if (*pnt2
!= '?') break;
3061 pnt
= (char *) strchr (str
, ':');
3062 if (pnt
!= (char *) NULL
)
3066 pnt2
= (char *) strchr (pnt1
, '=');
3067 if (pnt2
!= (char *) NULL
)
3068 incomplete
+= VMS_typedef_parse (pnt2
);
3071 /* At this point the parse buffer should just
3072 contain name:nn. If it does not, then we
3073 are in real trouble. Anyway, this is always
3074 shorter than the original line. */
3075 strcpy (S_GET_NAME (sp
), parse_buffer
);
3076 free (parse_buffer
);
3079 *pnt
= ':'; /* put back colon to restore dbx_type */
3086 /* Make one last pass, if needed, and define whatever we can that is left */
3087 if (final_pass
== 0 && incomplete
== incom1
)
3090 incom1
++; /* Force one last pass through */
3092 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
3093 /* repeat until all refs resolved if possible */
3094 /* if (pass > 1) printf (" Required %d passes\n", pass);*/
3095 if (incomplete
!= 0)
3097 as_tsktsk ("debugger output: Unable to resolve %d circular references.",
3102 while (fpnt
!= (struct forward_ref
*) NULL
)
3104 if (fpnt
->resolved
!= 'Y')
3106 if (find_symbol (fpnt
->dbx_type
) !=
3107 (struct VMS_DBG_Symbol
*) NULL
)
3109 as_tsktsk ("debugger forward reference error, dbx type %d",
3114 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
3115 pnt2
= (char *) strchr (&fixit
[1], '=');
3116 VMS_typedef_parse (pnt2
);
3123 Define_Local_Symbols (s0P
, s2P
, Current_Routine
, Text_Psect
)
3125 symbolS
*Current_Routine
;
3128 symbolS
*s1P
; /* each symbol from s0P .. s2P (exclusive) */
3130 for (s1P
= symbol_next (s0P
); s1P
!= s2P
; s1P
= symbol_next (s1P
))
3133 break; /* and return */
3134 if (S_GET_RAW_TYPE (s1P
) == N_FUN
)
3136 char *pnt
= (char *) strchr (S_GET_NAME (s1P
), ':') + 1;
3137 if (*pnt
== 'F' || *pnt
== 'f') break;
3139 if (!S_IS_DEBUG (s1P
))
3142 * Dispatch on STAB type
3144 switch (S_GET_RAW_TYPE (s1P
))
3147 continue; /* not left or right brace */
3151 VMS_local_stab_Parse (s1P
);
3155 VMS_RSYM_Parse (s1P
, Current_Routine
, Text_Psect
);
3162 /* This function crawls the symbol chain searching for local symbols that need
3163 * to be described to the debugger. When we enter a new scope with a "{", it
3164 * creates a new "block", which helps the debugger keep track of which scope
3165 * we are currently in.
3169 Define_Routine (s0P
, Level
, Current_Routine
, Text_Psect
)
3172 symbolS
*Current_Routine
;
3179 for (s1P
= symbol_next (s0P
); s1P
!= 0; s1P
= symbol_next (s1P
))
3181 if (S_GET_RAW_TYPE (s1P
) == N_FUN
)
3183 char *pnt
= (char *) strchr (S_GET_NAME (s1P
), ':') + 1;
3184 if (*pnt
== 'F' || *pnt
== 'f') break;
3186 if (!S_IS_DEBUG (s1P
))
3189 * Dispatch on STAB type
3191 switch (S_GET_RAW_TYPE (s1P
))
3194 continue; /* not left or right brace */
3200 sprintf (str
, "$%d", rcount
++);
3201 VMS_TBT_Block_Begin (s1P
, Text_Psect
, str
);
3203 Offset
= S_GET_VALUE (s1P
); /* side-effect: fully resolve symbol */
3204 Define_Local_Symbols (s0P
, s1P
, Current_Routine
, Text_Psect
);
3205 s1P
= Define_Routine (s1P
, Level
+ 1, Current_Routine
, Text_Psect
);
3207 VMS_TBT_Block_End (S_GET_VALUE (s1P
) - Offset
);
3216 /* We end up here if there were no brackets in this function.
3217 Define everything. */
3218 Define_Local_Symbols (s0P
, (symbolS
*)0, Current_Routine
, Text_Psect
);
3224 #include <sys/types.h>
3226 static void get_VMS_time_on_unix
PARAMS ((char *));
3228 /* Manufacture a VMS-like time string on a Unix based system. */
3230 get_VMS_time_on_unix (Now
)
3237 pnt
= ctime (&timeb
);
3243 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3245 #endif /* not VMS */
3248 * Write the MHD (Module Header) records
3251 Write_VMS_MHD_Records ()
3253 register const char *cp
;
3257 struct { unsigned short len
, mbz
; char *ptr
; } Descriptor
;
3259 char Module_Name
[255+1];
3263 * We are writing a module header record
3265 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3267 * ***************************
3268 * *MAIN MODULE HEADER RECORD*
3269 * ***************************
3271 * Store record type and header type
3273 PUT_CHAR (OBJ_S_C_HDR
);
3274 PUT_CHAR (MHD_S_C_MHD
);
3276 * Structure level is 0
3278 PUT_CHAR (OBJ_S_C_STRLVL
);
3280 * Maximum record size is size of the object record buffer
3282 PUT_SHORT (sizeof (Object_Record_Buffer
));
3285 * FIXME: module name and version should be user
3286 * specifiable via `.ident' and/or `#pragma ident'.
3290 * Get module name (the FILENAME part of the object file)
3296 if ((*cp
== ']') || (*cp
== '>') ||
3297 (*cp
== ':') || (*cp
== '/'))
3303 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3307 * Limit it to 31 characters and store in the object record
3309 while (--cp1
>= Module_Name
)
3312 if (strlen (Module_Name
) > 31)
3314 if (flag_hash_long_names
)
3315 as_tsktsk ("Module name truncated: %s\n", Module_Name
);
3316 Module_Name
[31] = 0;
3318 PUT_COUNTED_STRING (Module_Name
);
3320 * Module Version is "V1.0"
3322 PUT_COUNTED_STRING ("V1.0");
3324 * Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm".
3327 get_VMS_time_on_unix (Now
);
3329 Descriptor
.len
= sizeof Now
- 1;
3330 Descriptor
.mbz
= 0; /* type & class unspecified */
3331 Descriptor
.ptr
= Now
;
3332 (void) sys$
asctim ((unsigned short *)0, &Descriptor
, (long *)0, 0);
3334 for (i
= 0; i
< 17; i
++)
3337 * Patch time is "never" (17 zeros)
3339 for (i
= 0; i
< 17; i
++)
3344 Flush_VMS_Object_Record_Buffer ();
3346 * *************************
3347 * *LANGUAGE PROCESSOR NAME*
3348 * *************************
3350 * Store record type and header type
3352 PUT_CHAR (OBJ_S_C_HDR
);
3353 PUT_CHAR (MHD_S_C_LNM
);
3355 * Store language processor name and version
3356 * (not a counted string!)
3358 * This is normally supplied by the gcc driver for the command line
3359 * which invokes gas. If absent, we fall back to gas's version.
3361 cp
= compiler_version_string
;
3374 Flush_VMS_Object_Record_Buffer ();
3379 * Write the EOM (End Of Module) record
3382 Write_VMS_EOM_Record (Psect
, Offset
)
3387 * We are writing an end-of-module record
3388 * (this assumes that the entry point will always be in a psect
3389 * represented by a single byte, which is the case for code in
3392 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3393 PUT_CHAR (OBJ_S_C_EOM
); /* Record type. */
3394 PUT_CHAR (0); /* Error severity level (we ignore it). */
3396 * Store the entry point, if it exists
3406 Flush_VMS_Object_Record_Buffer ();
3410 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3416 register const unsigned char *p
= (unsigned char *) ptr
;
3417 register const unsigned char *end
= p
+ strlen (ptr
);
3418 register unsigned char c
;
3419 register int hash
= 0;
3424 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3430 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3433 VMS_Case_Hack_Symbol (In
, Out
)
3434 register const char *In
;
3441 const char *old_name
;
3443 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3445 int Case_Hack_Bits
= 0;
3447 static char Hex_Table
[16] =
3448 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3451 * Kill any leading "_"
3453 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3456 new_name
= Out
; /* save this for later*/
3458 #if barfoo /* Dead code */
3459 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3463 /* We may need to truncate the symbol, save the hash for later*/
3464 result
= (strlen (In
) > 23) ? hash_string (In
) : 0;
3466 * Is there a Psect Attribute to skip??
3468 if (HAS_PSECT_ATTRIBUTES (In
))
3473 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3476 if ((In
[0] == '$') && (In
[1] == '$'))
3486 /* if (strlen (In) > 31 && flag_hash_long_names)
3487 as_tsktsk ("Symbol name truncated: %s\n", In); */
3489 * Do the case conversion
3491 i
= 23; /* Maximum of 23 chars */
3492 while (*In
&& (--i
>= 0))
3494 Case_Hack_Bits
<<= 1;
3497 if ((destructor
== 1) && (i
== 21))
3499 switch (vms_name_mapping
)
3502 if (isupper (*In
)) {
3504 Case_Hack_Bits
|= 1;
3506 *Out
++ = islower (*In
) ? toupper (*In
++) : *In
++;
3509 case 3: *Out
++ = *In
++;
3512 if (islower (*In
)) {
3515 *Out
++ = isupper (*In
) ? tolower (*In
++) : *In
++;
3521 * If we saw a dollar sign, we don't do case hacking
3523 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3527 * If we have more than 23 characters and everything is lowercase
3528 * we can insert the full 31 characters
3533 * We have more than 23 characters
3534 * If we must add the case hack, then we have truncated the str
3538 if (Case_Hack_Bits
== 0)
3541 * And so far they are all lower case:
3542 * Check up to 8 more characters
3543 * and ensure that they are lowercase
3545 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3546 if (isupper (In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3552 if ((i
== 8) || (In
[i
] == 0))
3555 * They are: Copy up to 31 characters
3556 * to the output string
3559 while ((--i
>= 0) && (*In
))
3560 switch (vms_name_mapping
){
3561 case 0: *Out
++ = islower (*In
) ? toupper (*In
++) : *In
++;
3563 case 3: *Out
++ = *In
++;
3565 case 2: *Out
++ = isupper (*In
) ? tolower (*In
++) : *In
++;
3572 * If there were any uppercase characters in the name we
3573 * take on the case hacking string
3576 /* Old behavior for regular GNU-C compiler */
3577 if (!flag_hash_long_names
)
3579 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3584 for (i
= 0; i
< 6; i
++)
3586 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3587 Case_Hack_Bits
>>= 4;
3593 Out
= pnt
; /*Cut back to 23 characters maximum */
3595 for (i
= 0; i
< 7; i
++)
3597 init
= result
& 0x01f;
3598 *Out
++ = (init
< 10) ? ('0' + init
) : ('A' + init
- 10);
3599 result
= result
>> 5;
3607 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3608 as_tsktsk ("Symbol %s replaced by %s\n", old_name
, new_name
);
3613 * Scan a symbol name for a psect attribute specification
3615 #define GLOBALSYMBOL_BIT 0x10000
3616 #define GLOBALVALUE_BIT 0x20000
3620 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3622 int *Attribute_Pointer
;
3625 register const char *cp
;
3633 {"PIC", GPS_S_M_PIC
},
3634 {"LIB", GPS_S_M_LIB
},
3635 {"OVR", GPS_S_M_OVR
},
3636 {"REL", GPS_S_M_REL
},
3637 {"GBL", GPS_S_M_GBL
},
3638 {"SHR", GPS_S_M_SHR
},
3639 {"EXE", GPS_S_M_EXE
},
3641 {"WRT", GPS_S_M_WRT
},
3642 {"VEC", GPS_S_M_VEC
},
3643 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3644 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3654 * Check for a PSECT attribute list
3656 if (!HAS_PSECT_ATTRIBUTES (Name
))
3657 return; /* If not, return */
3659 * Skip the attribute list indicator
3661 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3663 * Process the attributes ("_" separated, "$" terminated)
3665 while (*Name
!= '$')
3668 * Assume not negating
3674 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3677 * We are negating (and skip the NO)
3683 * Find the token delimiter
3686 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3689 * Look for the token in the attribute list
3691 for (i
= 0; Attributes
[i
].Name
; i
++)
3694 * If the strings match, set/clear the attr.
3696 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3702 *Attribute_Pointer
&=
3703 ~Attributes
[i
].Value
;
3705 *Attribute_Pointer
|=
3706 Attributes
[i
].Value
;
3714 * Now skip the attribute
3723 #define GBLSYM_REF 0
3724 #define GBLSYM_DEF 1
3725 #define GBLSYM_VAL 2
3726 #define GBLSYM_LCL 4 /* not GBL after all... */
3729 * Define a global symbol (or possibly a local one).
3732 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Flags
)
3741 * We are writing a GSD record
3743 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3745 * If the buffer is empty we must insert the GSD record type
3747 if (Object_Record_Offset
== 0)
3748 PUT_CHAR (OBJ_S_C_GSD
);
3750 * We are writing a Global (or local) symbol definition subrecord.
3752 PUT_CHAR ((Flags
& GBLSYM_LCL
) != 0 ? GSD_S_C_LSY
:
3753 ((unsigned) Psect_Number
<= 255) ? GSD_S_C_SYM
: GSD_S_C_SYMW
);
3755 * Data type is undefined
3759 * Switch on Definition/Reference
3761 if ((Flags
& GBLSYM_DEF
) == 0)
3766 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ? GSY_S_M_REL
: 0);
3767 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3768 PUT_SHORT (Current_Environment
);
3774 *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
3776 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ?
3777 GSY_S_M_DEF
| GSY_S_M_REL
: GSY_S_M_DEF
);
3778 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3779 PUT_SHORT (Current_Environment
);
3783 if ((Flags
& GBLSYM_LCL
) == 0 && (unsigned) Psect_Number
<= 255)
3784 PUT_CHAR (Psect_Number
);
3786 PUT_SHORT (Psect_Number
);
3790 PUT_LONG (Psect_Offset
);
3793 * Finally, the global symbol name
3795 VMS_Case_Hack_Symbol (Name
, Local
);
3796 PUT_COUNTED_STRING (Local
);
3798 * Flush the buffer if it is more than 75% full
3800 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3801 Flush_VMS_Object_Record_Buffer ();
3805 * Define an environment to support local symbol references.
3806 * This is just to mollify the linker; we don't actually do
3807 * anything useful with it.
3810 VMS_Local_Environment_Setup (Env_Name
)
3811 const char *Env_Name
;
3813 /* We are writing a GSD record. */
3814 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3815 /* If the buffer is empty we must insert the GSD record type. */
3816 if (Object_Record_Offset
== 0)
3817 PUT_CHAR (OBJ_S_C_GSD
);
3818 /* We are writing an ENV subrecord. */
3819 PUT_CHAR (GSD_S_C_ENV
);
3821 ++Current_Environment
; /* index of environment being defined */
3823 /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
3824 PUT_SHORT (ENV_S_M_DEF
);
3825 /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
3828 /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
3829 if (!Env_Name
) Env_Name
= "";
3830 PUT_COUNTED_STRING ((char *)Env_Name
);
3832 /* Flush the buffer if it is more than 75% full. */
3833 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3834 Flush_VMS_Object_Record_Buffer ();
3842 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3846 struct VMS_Symbol
*vsp
;
3849 int Psect_Attributes
;
3852 * Generate the appropriate PSECT flags given the PSECT type
3857 /* Text psects are PIC,noOVR,REL,noGBL,SHR,EXE,RD,noWRT. */
3858 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_REL
|GPS_S_M_SHR
|GPS_S_M_EXE
3862 /* Data psects are PIC,noOVR,REL,noGBL,noSHR,noEXE,RD,WRT. */
3863 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_REL
|GPS_S_M_RD
|GPS_S_M_WRT
);
3866 /* Common block psects are: PIC,OVR,REL,GBL,SHR,noEXE,RD,WRT. */
3867 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_OVR
|GPS_S_M_REL
|GPS_S_M_GBL
3868 |GPS_S_M_SHR
|GPS_S_M_RD
|GPS_S_M_WRT
);
3871 /* Const data psects are: PIC,OVR,REL,GBL,SHR,noEXE,RD,noWRT. */
3872 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_OVR
|GPS_S_M_REL
|GPS_S_M_GBL
3873 |GPS_S_M_SHR
|GPS_S_M_RD
);
3877 error ("Unknown VMS psect type (%ld)", (long) Type
);
3881 * Modify the psect attributes according to any attribute string
3883 if (vsp
&& S_GET_TYPE (vsp
->Symbol
) == N_ABS
)
3884 Psect_Attributes
|= GLOBALVALUE_BIT
;
3885 else if (HAS_PSECT_ATTRIBUTES (Name
))
3886 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3888 * Check for globalref/def/val.
3890 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3893 * globalvalue symbols were generated before. This code
3894 * prevents unsightly psect buildup, and makes sure that
3895 * fixup references are emitted correctly.
3897 vsp
->Psect_Index
= -1; /* to catch errors */
3898 S_SET_TYPE (vsp
->Symbol
, N_UNDF
); /* make refs work */
3899 return 1; /* decrement psect counter */
3902 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3904 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3906 case N_UNDF
| N_EXT
:
3907 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3908 vsp
->Psect_Offset
, GBLSYM_REF
);
3909 vsp
->Psect_Index
= -1;
3910 S_SET_TYPE (vsp
->Symbol
, N_UNDF
);
3911 return 1; /* return and indicate no psect */
3912 case N_DATA
| N_EXT
:
3913 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3914 vsp
->Psect_Offset
, GBLSYM_DEF
);
3915 /* In this case we still generate the psect */
3918 as_fatal ("Globalsymbol attribute for symbol %s was unexpected.",
3924 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3926 * We are writing a GSD record
3928 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3930 * If the buffer is empty we must insert the GSD record type
3932 if (Object_Record_Offset
== 0)
3933 PUT_CHAR (OBJ_S_C_GSD
);
3935 * We are writing a PSECT definition subrecord
3937 PUT_CHAR (GSD_S_C_PSC
);
3939 * Psects are always LONGWORD aligned
3943 * Specify the psect attributes
3945 PUT_SHORT (Psect_Attributes
);
3947 * Specify the allocation
3951 * Finally, the psect name
3953 VMS_Case_Hack_Symbol (Name
, Local
);
3954 PUT_COUNTED_STRING (Local
);
3956 * Flush the buffer if it is more than 75% full
3958 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3959 Flush_VMS_Object_Record_Buffer ();
3965 * Given the pointer to a symbol we calculate how big the data at the
3966 * symbol is. We do this by looking for the next symbol (local or
3967 * global) which will indicate the start of another datum.
3970 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3971 register symbolS
*sp
;
3974 symbolS
*sp1
, *Next_Symbol
;
3975 /* Cache values to avoid extra lookups. */
3976 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
= 0;
3979 * Find the next symbol
3980 * it delimits this datum
3983 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3986 * The data type must match
3988 if (S_GET_TYPE (sp1
) != N_DATA
)
3991 sp1_val
= S_GET_VALUE (sp1
);
3994 * The symbol must be AFTER this symbol
3996 if (sp1_val
<= sp_val
)
3999 * We ignore THIS symbol
4004 * If there is already a candidate selected for the
4005 * next symbol, see if we are a better candidate
4010 * We are a better candidate if we are "closer"
4013 if (sp1_val
> next_val
)
4017 * Make this the candidate
4023 * Calculate its size
4025 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
4030 * Check symbol names for the Psect hack with a globalvalue, and then
4031 * generate globalvalues for those that have it.
4034 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
4039 register symbolS
*sp
;
4040 char *stripped_name
, *Name
;
4042 int Psect_Attributes
;
4047 * Scan the symbol table for globalvalues, and emit def/ref when
4048 * required. These will be caught again later and converted to
4051 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
4053 typ
= S_GET_RAW_TYPE (sp
);
4054 abstyp
= ((typ
& ~N_EXT
) == N_ABS
);
4056 * See if this is something we want to look at.
4059 typ
!= (N_DATA
| N_EXT
) &&
4060 typ
!= (N_UNDF
| N_EXT
))
4063 * See if this has globalvalue specification.
4065 Name
= S_GET_NAME (sp
);
4070 Psect_Attributes
= GLOBALVALUE_BIT
;
4072 else if (HAS_PSECT_ATTRIBUTES (Name
))
4074 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
4075 strcpy (stripped_name
, Name
);
4076 Psect_Attributes
= 0;
4077 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
4082 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
4087 /* Local symbol references will want
4088 to have an environment defined. */
4089 if (Current_Environment
< 0)
4090 VMS_Local_Environment_Setup (".N_ABS");
4091 VMS_Global_Symbol_Spec (Name
, 0,
4093 GBLSYM_DEF
|GBLSYM_VAL
|GBLSYM_LCL
);
4096 VMS_Global_Symbol_Spec (Name
, 0,
4098 GBLSYM_DEF
|GBLSYM_VAL
);
4100 case N_UNDF
| N_EXT
:
4101 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
4103 case N_DATA
| N_EXT
:
4104 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4106 error ("Invalid data type for globalvalue");
4107 globalvalue
= md_chars_to_number (Data_Segment
+
4108 S_GET_VALUE (sp
) - text_siz
, Size
);
4109 /* Three times for good luck. The linker seems to get confused
4110 if there are fewer than three */
4111 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
4112 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
4113 GBLSYM_DEF
|GBLSYM_VAL
);
4114 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
4115 GBLSYM_DEF
|GBLSYM_VAL
);
4118 as_warn ("Invalid globalvalue of %s", stripped_name
);
4122 if (stripped_name
) free (stripped_name
); /* clean up */
4129 * Define a procedure entry pt/mask
4132 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
4141 * We are writing a GSD record
4143 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
4145 * If the buffer is empty we must insert the GSD record type
4147 if (Object_Record_Offset
== 0)
4148 PUT_CHAR (OBJ_S_C_GSD
);
4150 * We are writing a Procedure Entry Pt/Mask subrecord
4152 PUT_CHAR (((unsigned) Psect_Number
<= 255) ? GSD_S_C_EPM
: GSD_S_C_EPMW
);
4154 * Data type is undefined
4158 * Flags = "RELOCATABLE" and "DEFINED"
4160 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4164 if ((unsigned) Psect_Number
<= 255)
4165 PUT_CHAR (Psect_Number
);
4167 PUT_SHORT (Psect_Number
);
4171 PUT_LONG (Psect_Offset
);
4175 PUT_SHORT (Entry_Mask
);
4177 * Finally, the global symbol name
4179 VMS_Case_Hack_Symbol (Name
, Local
);
4180 PUT_COUNTED_STRING (Local
);
4182 * Flush the buffer if it is more than 75% full
4184 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4185 Flush_VMS_Object_Record_Buffer ();
4190 * Set the current location counter to a particular Psect and Offset
4193 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4199 * We are writing a "Record_Type" record
4201 Set_VMS_Object_File_Record (Record_Type
);
4203 * If the buffer is empty we must insert the record type
4205 if (Object_Record_Offset
== 0)
4206 PUT_CHAR (Record_Type
);
4208 * Stack the Psect base + Offset
4210 vms_tir_stack_psect (Psect_Index
, Offset
, 0);
4212 * Set relocation base
4214 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4216 * Flush the buffer if it is more than 75% full
4218 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4219 Flush_VMS_Object_Record_Buffer ();
4224 * Store repeated immediate data in current Psect
4227 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4229 register char *Pointer
;
4235 * Ignore zero bytes/words/longwords
4240 if (Pointer
[3] != 0 || Pointer
[2] != 0) break;
4243 if (Pointer
[1] != 0) break;
4246 if (Pointer
[0] != 0) break;
4253 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4254 * then we do it manually
4258 while (--Repeat_Count
>= 0)
4259 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4263 * We are writing a "Record_Type" record
4265 Set_VMS_Object_File_Record (Record_Type
);
4267 * If the buffer is empty we must insert record type
4269 if (Object_Record_Offset
== 0)
4270 PUT_CHAR (Record_Type
);
4272 * Stack the repeat count
4274 PUT_CHAR (TIR_S_C_STA_LW
);
4275 PUT_LONG (Repeat_Count
);
4277 * And now the command and its data
4279 PUT_CHAR (TIR_S_C_STO_RIVB
);
4282 PUT_CHAR (*Pointer
++);
4284 * Flush the buffer if it is more than 75% full
4286 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4287 Flush_VMS_Object_Record_Buffer ();
4292 * Store a Position Independent Reference
4295 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4296 Psect
, Psect_Offset
, Record_Type
)
4304 register struct VMS_Symbol
*vsp
= Symbol
->sy_obj
;
4309 * We are writing a "Record_Type" record
4311 Set_VMS_Object_File_Record (Record_Type
);
4313 * If the buffer is empty we must insert record type
4315 if (Object_Record_Offset
== 0)
4316 PUT_CHAR (Record_Type
);
4318 * Set to the appropriate offset in the Psect.
4319 * For a Code reference we need to fix the operand
4320 * specifier as well, so back up 1 byte;
4321 * for a Data reference we just store HERE.
4323 VMS_Set_Psect (Psect
,
4324 PC_Relative
? Psect_Offset
- 1 : Psect_Offset
,
4327 * Make sure we are still generating a "Record Type" record
4329 if (Object_Record_Offset
== 0)
4330 PUT_CHAR (Record_Type
);
4332 * Dispatch on symbol type (so we can stack its value)
4334 switch (S_GET_RAW_TYPE (Symbol
))
4343 #ifdef NOT_VAX_11_C_COMPATIBLE
4344 case N_UNDF
| N_EXT
:
4345 case N_DATA
| N_EXT
:
4346 #endif /* NOT_VAX_11_C_COMPATIBLE */
4348 case N_TEXT
| N_EXT
:
4350 * Get the symbol name (case hacked)
4352 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4354 * Stack the global symbol value
4358 PUT_CHAR (TIR_S_C_STA_GBL
);
4362 /* Local symbols have an extra field. */
4363 PUT_CHAR (TIR_S_C_STA_LSY
);
4364 PUT_SHORT (Current_Environment
);
4366 PUT_COUNTED_STRING (Local
);
4370 * Stack the longword offset
4372 PUT_CHAR (TIR_S_C_STA_LW
);
4375 * Add the two, leaving the result on the stack
4377 PUT_CHAR (TIR_S_C_OPR_ADD
);
4381 * Uninitialized local data
4385 * Stack the Psect (+offset)
4387 vms_tir_stack_psect (vsp
->Psect_Index
,
4388 vsp
->Psect_Offset
+ Offset
,
4396 * Stack the Psect (+offset)
4398 vms_tir_stack_psect (vsp
->Psect_Index
,
4399 S_GET_VALUE (Symbol
) + Offset
,
4403 * Initialized local or global data
4406 #ifndef NOT_VAX_11_C_COMPATIBLE
4407 case N_UNDF
| N_EXT
:
4408 case N_DATA
| N_EXT
:
4409 #endif /* NOT_VAX_11_C_COMPATIBLE */
4411 * Stack the Psect (+offset)
4413 vms_tir_stack_psect (vsp
->Psect_Index
,
4414 vsp
->Psect_Offset
+ Offset
,
4419 * Store either a code or data reference
4421 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4423 * Flush the buffer if it is more than 75% full
4425 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4426 Flush_VMS_Object_Record_Buffer ();
4431 * Check in the text area for an indirect pc-relative reference
4432 * and fix it up with addressing mode 0xff [PC indirect]
4434 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4435 * PIC CODE GENERATING FIXUP ROUTINE.
4438 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4441 register fragS
*fragP
;
4442 fragS
*text_frag_root
;
4445 * The addressing mode byte is 1 byte before the address
4449 * Is it in THIS frag??
4451 if ((Offset
< fragP
->fr_address
) ||
4452 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4455 * We need to search for the fragment containing this
4458 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4460 if ((Offset
>= fragP
->fr_address
) &&
4461 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4465 * If we couldn't find the frag, things are BAD!!
4468 error ("Couldn't find fixup fragment when checking for indirect reference");
4471 * Check for indirect PC relative addressing mode
4473 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4475 static char Address_Mode
= (char) 0xff;
4478 * Yes: Store the indirect mode back into the image
4479 * to fix up the damage done by STO_PICR
4481 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4482 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4488 * If the procedure "main()" exists we have to add the instruction
4489 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4491 * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed
4492 * to `HACK_VAXCRTL_STARTUP' because Digital's compiler
4493 * named "DEC C" uses run-time library "DECC$SHR", but this
4494 * startup code is for "VAXCRTL", the library for Digital's
4495 * older "VAX C". Also, this extra code isn't needed for
4496 * supporting gcc because it already generates the VAXCRTL
4497 * startup call when compiling main(). The reference to
4498 * `flag_hash_long_names' looks very suspicious too;
4499 * probably an old-style command line option was inadvertently
4500 * overloaded here, then blindly converted into the new one.
4503 vms_check_for_main ()
4505 register symbolS
*symbolP
;
4506 #ifdef HACK_DEC_C_STARTUP /* JF */
4507 register struct frchain
*frchainP
;
4508 register fragS
*fragP
;
4509 register fragS
**prev_fragPP
;
4510 register struct fix
*fixP
;
4511 register fragS
*New_Frag
;
4513 #endif /* HACK_DEC_C_STARTUP */
4515 symbolP
= (symbolS
*) symbol_find ("_main");
4516 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4517 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4519 #ifdef HACK_DEC_C_STARTUP
4520 if (!flag_hash_long_names
)
4524 * Remember the entry point symbol
4526 Entry_Point_Symbol
= symbolP
;
4527 #ifdef HACK_DEC_C_STARTUP
4532 * Scan all the fragment chains for the one with "_main"
4533 * (Actually we know the fragment from the symbol, but we need
4534 * the previous fragment so we can change its pointer)
4536 frchainP
= frchain_root
;
4540 * Scan all the fragments in this chain, remembering
4541 * the "previous fragment"
4543 prev_fragPP
= &frchainP
->frch_root
;
4544 fragP
= frchainP
->frch_root
;
4545 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4548 * Is this the fragment?
4550 if (fragP
== symbolP
->sy_frag
)
4553 * Yes: Modify the fragment by replacing
4554 * it with a new fragment.
4556 New_Frag
= (fragS
*)
4557 xmalloc (sizeof (*New_Frag
) +
4562 * The fragments are the same except
4563 * that the "fixed" area is larger
4566 New_Frag
->fr_fix
+= 6;
4568 * Copy the literal data opening a hole
4569 * 2 bytes after "_main" (i.e. just after
4570 * the entry mask). Into which we place
4571 * the JSB instruction.
4573 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4574 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4575 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4576 New_Frag
->fr_literal
[3] = 0xef;
4577 New_Frag
->fr_literal
[4] = 0;
4578 New_Frag
->fr_literal
[5] = 0;
4579 New_Frag
->fr_literal
[6] = 0;
4580 New_Frag
->fr_literal
[7] = 0;
4581 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4582 New_Frag
->fr_literal
[i
+ 6] =
4583 fragP
->fr_literal
[i
];
4585 * Now replace the old fragment with the
4586 * newly generated one.
4588 *prev_fragPP
= New_Frag
;
4590 * Remember the entry point symbol
4592 Entry_Point_Symbol
= symbolP
;
4594 * Scan the text area fixup structures
4595 * as offsets in the fragment may have
4598 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4601 * Look for references to this
4604 if (fixP
->fx_frag
== fragP
)
4607 * Change the fragment
4610 fixP
->fx_frag
= New_Frag
;
4612 * If the offset is after
4613 * the entry mask we need
4614 * to account for the JSB
4615 * instruction we just
4618 if (fixP
->fx_where
>= 2)
4619 fixP
->fx_where
+= 6;
4623 * Scan the symbols as offsets in the
4624 * fragment may have changed
4626 for (symbolP
= symbol_rootP
;
4628 symbolP
= symbol_next (symbolP
))
4631 * Look for references to this
4634 if (symbolP
->sy_frag
== fragP
)
4637 * Change the fragment
4640 symbolP
->sy_frag
= New_Frag
;
4642 * If the offset is after
4643 * the entry mask we need
4644 * to account for the JSB
4645 * instruction we just
4648 if (S_GET_VALUE (symbolP
) >= 2)
4649 S_SET_VALUE (symbolP
,
4650 S_GET_VALUE (symbolP
) + 6);
4654 * Make a symbol reference to
4655 * "_c$main_args" so we can get
4656 * its address inserted into the
4659 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4660 S_SET_NAME (symbolP
, "_C$MAIN_ARGS");
4661 S_SET_TYPE (symbolP
, N_UNDF
);
4662 S_SET_OTHER (symbolP
, 0);
4663 S_SET_DESC (symbolP
, 0);
4664 S_SET_VALUE (symbolP
, 0);
4665 symbolP
->sy_name_offset
= 0;
4666 symbolP
->sy_number
= 0;
4667 symbolP
->sy_obj
= 0;
4668 symbolP
->sy_frag
= New_Frag
;
4669 symbolP
->sy_resolved
= 0;
4670 symbolP
->sy_resolving
= 0;
4671 /* this actually inserts at the beginning of the list */
4672 symbol_append (symbol_rootP
, symbolP
,
4673 &symbol_rootP
, &symbol_lastP
);
4675 symbol_rootP
= symbolP
;
4677 * Generate a text fixup structure
4678 * to get "_c$main_args" stored into the
4681 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4682 fixP
->fx_frag
= New_Frag
;
4684 fixP
->fx_addsy
= symbolP
;
4686 fixP
->fx_offset
= 0;
4689 fixP
->fx_next
= text_fix_root
;
4690 text_fix_root
= fixP
;
4692 * Now make sure we exit from the loop
4698 * Try the next fragment
4700 prev_fragPP
= &fragP
->fr_next
;
4701 fragP
= fragP
->fr_next
;
4704 * Try the next fragment chain
4707 frchainP
= frchainP
->frch_next
;
4710 #endif /* HACK_DEC_C_STARTUP */
4716 * Beginning of vms_write_object_file().
4720 struct vms_obj_state
{
4722 /* Next program section index to use. */
4725 /* Psect index for code. Always ends up #0. */
4728 /* Psect index for initialized static variables. */
4731 /* Psect index for uninitialized static variables. */
4734 /* Number of bytes used for local symbol data. */
4735 int local_initd_data_size
;
4737 /* Dynamic buffer for initialized data. */
4742 #define Psect_Number vms_obj_state.psect_number
4743 #define Text_Psect vms_obj_state.text_psect
4744 #define Data_Psect vms_obj_state.data_psect
4745 #define Bss_Psect vms_obj_state.bss_psect
4746 #define Local_Initd_Data_Size vms_obj_state.local_initd_data_size
4747 #define Data_Segment vms_obj_state.data_segment
4750 #define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
4754 * Perform text segment fixups.
4757 vms_fixup_text_section (text_siz
, text_frag_root
, data_frag_root
)
4759 struct frag
*text_frag_root
;
4760 struct frag
*data_frag_root
;
4762 register fragS
*fragP
;
4763 register struct fix
*fixP
;
4766 /* Scan the text fragments. */
4767 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4769 /* Stop if we get to the data fragments. */
4770 if (fragP
== data_frag_root
)
4772 /* Ignore fragments with no data. */
4773 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4775 /* Go the the appropriate offset in the Text Psect. */
4776 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4777 /* Store the "fixed" part. */
4779 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4782 /* Store the "variable" part. */
4783 if (fragP
->fr_var
&& fragP
->fr_offset
)
4784 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4785 fragP
->fr_literal
+ fragP
->fr_fix
,
4788 } /* text frag loop */
4791 * Now we go through the text segment fixups and generate
4792 * TIR records to fix up addresses within the Text Psect.
4794 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4796 /* We DO handle the case of "Symbol - Symbol" as
4797 long as it is in the same segment. */
4798 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4800 /* They need to be in the same segment. */
4801 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4802 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4803 error ("Fixup data addsy and subsy don't have the same type");
4804 /* And they need to be in one that we can check the psect on. */
4805 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4806 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4807 error ("Fixup data addsy and subsy don't have an appropriate type");
4808 /* This had better not be PC relative! */
4810 error ("Fixup data is erroneously \"pcrel\"");
4811 /* Subtract their values to get the difference. */
4812 dif
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
4813 md_number_to_chars (Local
, (valueT
)dif
, fixP
->fx_size
);
4814 /* Now generate the fixup object records;
4815 set the psect and store the data. */
4816 VMS_Set_Psect (Text_Psect
,
4817 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4819 VMS_Store_Immediate_Data (Local
,
4822 continue; /* done with this fixup */
4823 } /* if fx_subsy && fx_addsy */
4824 /* Size will HAVE to be "long". */
4825 if (fixP
->fx_size
!= 4)
4826 error ("Fixup datum is not a longword");
4827 /* Symbol must be "added" (if it is ever
4828 subtracted we can fix this assumption). */
4829 if (fixP
->fx_addsy
== 0)
4830 error ("Fixup datum is not \"fixP->fx_addsy\"");
4831 /* Store the symbol value in a PIC fashion. */
4832 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4836 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4839 * Check for indirect address reference, which has to be fixed up
4840 * (as the linker will screw it up with TIR_S_C_STO_PICR)...
4843 VMS_Fix_Indirect_Reference (Text_Psect
,
4844 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4847 } /* text fix loop */
4852 * Create a buffer holding the data segment.
4855 synthesize_data_segment (data_siz
, text_siz
, data_frag_root
)
4856 unsigned data_siz
, text_siz
;
4857 struct frag
*data_frag_root
;
4859 register fragS
*fragP
;
4861 long fill_size
, count
, i
;
4863 /* Allocate the data segment. */
4864 Data_Segment
= (char *) xmalloc (data_siz
);
4865 /* Run through the data fragments, filling in the segment. */
4866 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4868 i
= fragP
->fr_address
- text_siz
;
4870 memcpy (Data_Segment
+ i
, fragP
->fr_literal
, fragP
->fr_fix
);
4873 if ((fill_size
= fragP
->fr_var
) != 0)
4875 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4876 for (count
= fragP
->fr_offset
; count
; count
--)
4878 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4882 } /* data frag loop */
4888 * Perform data segment fixups.
4891 vms_fixup_data_section (data_siz
, text_siz
)
4892 unsigned data_siz
, text_siz
;
4894 register struct VMS_Symbol
*vsp
;
4895 register struct fix
*fixP
;
4896 register symbolS
*sp
;
4897 addressT fr_address
;
4901 /* Run through all the data symbols and store the data. */
4902 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4904 /* Ignore anything other than data symbols. */
4905 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
4907 /* Set the Psect + Offset. */
4908 VMS_Set_Psect (vsp
->Psect_Index
,
4911 /* Store the data. */
4912 val
= S_GET_VALUE (vsp
->Symbol
);
4913 VMS_Store_Immediate_Data (Data_Segment
+ val
- text_siz
,
4916 } /* N_DATA symbol loop */
4919 * Now we go through the data segment fixups and generate
4920 * TIR records to fix up addresses within the Data Psects.
4922 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4924 /* Find the symbol for the containing datum. */
4925 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4927 /* Only bother with Data symbols. */
4929 if (S_GET_TYPE (sp
) != N_DATA
)
4931 /* Ignore symbol if After fixup. */
4932 val
= S_GET_VALUE (sp
);
4933 fr_address
= fixP
->fx_frag
->fr_address
;
4934 if (val
> fixP
->fx_where
+ fr_address
)
4936 /* See if the datum is here. */
4937 if (val
+ vsp
->Size
<= fixP
->fx_where
+ fr_address
)
4939 /* We DO handle the case of "Symbol - Symbol" as
4940 long as it is in the same segment. */
4941 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4943 /* They need to be in the same segment. */
4944 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4945 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4946 error ("Fixup data addsy and subsy don't have the same type");
4947 /* And they need to be in one that we can check the psect on. */
4948 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4949 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4950 error ("Fixup data addsy and subsy don't have an appropriate type");
4951 /* This had better not be PC relative! */
4953 error ("Fixup data is erroneously \"pcrel\"");
4954 /* Subtract their values to get the difference. */
4955 dif
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
4956 md_number_to_chars (Local
, (valueT
)dif
, fixP
->fx_size
);
4958 * Now generate the fixup object records;
4959 * set the psect and store the data.
4961 VMS_Set_Psect (vsp
->Psect_Index
,
4962 fr_address
+ fixP
->fx_where
4963 - val
+ vsp
->Psect_Offset
,
4965 VMS_Store_Immediate_Data (Local
,
4968 break; /* done with this fixup */
4970 /* Size will HAVE to be "long". */
4971 if (fixP
->fx_size
!= 4)
4972 error ("Fixup datum is not a longword");
4973 /* Symbol must be "added" (if it is ever
4974 subtracted we can fix this assumption). */
4975 if (fixP
->fx_addsy
== 0)
4976 error ("Fixup datum is not \"fixP->fx_addsy\"");
4977 /* Store the symbol value in a PIC fashion. */
4978 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4982 fr_address
+ fixP
->fx_where
4983 - val
+ vsp
->Psect_Offset
,
4985 /* Done with this fixup. */
4987 } /* vms_symbol loop */
4989 } /* data fix loop */
4994 * Define symbols for the linker.
4997 global_symbol_directory (text_siz
, data_siz
)
4998 unsigned text_siz
, data_siz
;
5000 register fragS
*fragP
;
5001 register symbolS
*sp
;
5002 register struct VMS_Symbol
*vsp
;
5003 int Globalref
, define_as_global_symbol
;
5005 #ifndef gxx_bug_fixed
5007 * The g++ compiler does not write out external references to vtables
5008 * correctly. Check for this and holler if we see it happening.
5009 * If that compiler bug is ever fixed we can remove this.
5010 * (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
5012 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
5013 if (S_GET_RAW_TYPE (sp
) == N_UNDF
&& IS_GXX_VTABLE (sp
))
5015 S_SET_TYPE (sp
, N_UNDF
| N_EXT
);
5016 S_SET_OTHER (sp
, 1);
5017 as_warn ("g++ wrote an extern reference to `%s' as a routine.\n%s",
5019 "I will fix it, but I hope that it was not really a routine.");
5021 #endif /* gxx_bug_fixed */
5024 * Now scan the symbols and emit the appropriate GSD records
5026 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
5028 define_as_global_symbol
= 0;
5029 /* Dispatch on symbol type. */
5030 switch (S_GET_RAW_TYPE (sp
))
5033 /* Global uninitialized data. */
5034 case N_UNDF
| N_EXT
:
5035 /* Make a VMS data symbol entry. */
5036 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5038 vsp
->Size
= S_GET_VALUE (sp
);
5039 vsp
->Psect_Index
= Psect_Number
++;
5040 vsp
->Psect_Offset
= 0;
5041 vsp
->Next
= VMS_Symbols
;
5044 /* Make the psect for this data. */
5045 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
5047 S_GET_OTHER (sp
) ? ps_CONST
: ps_COMMON
,
5051 #ifdef NOT_VAX_11_C_COMPATIBLE
5052 define_as_global_symbol
= 1;
5054 /* See if this is an external vtable. We want to help the
5055 linker find these things in libraries, so we make a symbol
5056 reference. This is not compatible with VAX-C usage for
5057 variables, but since vtables are only used internally by
5058 g++, we can get away with this hack. */
5059 define_as_global_symbol
= IS_GXX_VTABLE (sp
);
5063 /* Local uninitialized data. */
5065 /* Make a VMS data symbol entry. */
5066 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5069 vsp
->Psect_Index
= Bss_Psect
;
5070 vsp
->Psect_Offset
= S_GET_VALUE (sp
) - bss_address_frag
.fr_address
;
5071 vsp
->Next
= VMS_Symbols
;
5076 /* Global initialized data. */
5077 case N_DATA
| N_EXT
:
5078 /* Make a VMS data symbol entry. */
5079 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5081 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
5082 vsp
->Psect_Index
= Psect_Number
++;
5083 vsp
->Psect_Offset
= 0;
5084 vsp
->Next
= VMS_Symbols
;
5087 /* Make its psect. */
5088 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
5090 S_GET_OTHER (sp
) ? ps_CONST
: ps_COMMON
,
5094 #ifdef NOT_VAX_11_C_COMPATIBLE
5095 define_as_global_symbol
= 1;
5097 /* See N_UNDF|N_EXT above for explanation. */
5098 define_as_global_symbol
= IS_GXX_VTABLE (sp
);
5102 /* Local initialized data. */
5105 char *sym_name
= S_GET_NAME (sp
);
5107 /* Always suppress local numeric labels. */
5108 if (!sym_name
|| strcmp (sym_name
, FAKE_LABEL_NAME
) != 0)
5110 /* Make a VMS data symbol entry. */
5111 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5113 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
5114 vsp
->Psect_Index
= Data_Psect
;
5115 vsp
->Psect_Offset
= Local_Initd_Data_Size
;
5116 Local_Initd_Data_Size
+= vsp
->Size
;
5117 vsp
->Next
= VMS_Symbols
;
5124 /* Global Text definition. */
5125 case N_TEXT
| N_EXT
:
5127 unsigned short Entry_Mask
;
5129 /* Get the entry mask. */
5130 fragP
= sp
->sy_frag
;
5131 /* First frag might be empty if we're generating listings.
5132 So skip empty rs_fill frags. */
5133 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
5134 fragP
= fragP
->fr_next
;
5136 /* If first frag doesn't contain the data, what do we do?
5137 If it's possibly smaller than two bytes, that would
5138 imply that the entry mask is not stored where we're
5141 If you can find a test case that triggers this, report
5142 it (and tell me what the entry mask field ought to be),
5143 and I'll try to fix it. KR */
5144 if (fragP
->fr_fix
< 2)
5147 Entry_Mask
= (fragP
->fr_literal
[0] & 0x00ff) |
5148 ((fragP
->fr_literal
[1] & 0x00ff) << 8);
5149 /* Define the procedure entry point. */
5150 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
5157 /* Local Text definition. */
5159 /* Make a VMS data symbol entry. */
5160 if (Text_Psect
!= -1)
5162 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5165 vsp
->Psect_Index
= Text_Psect
;
5166 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
5167 vsp
->Next
= VMS_Symbols
;
5173 /* Global Reference. */
5175 /* Make a GSD global symbol reference record. */
5176 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
5182 /* Absolute symbol. */
5185 /* gcc doesn't generate these;
5186 VMS_Emit_Globalvalue handles them though. */
5187 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5189 vsp
->Size
= 4; /* always assume 32 bits */
5190 vsp
->Psect_Index
= 0;
5191 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
5192 vsp
->Next
= VMS_Symbols
;
5197 /* Anything else. */
5199 /* Ignore STAB symbols, including .stabs emitted by g++. */
5200 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
5205 as_tsktsk ("unhandled stab type %d", S_GET_TYPE (sp
));
5209 /* Global symbols have different linkage than external variables. */
5210 if (define_as_global_symbol
)
5211 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
5222 * Output debugger symbol table information for symbols which
5223 * are local to a specific routine.
5226 local_symbols_DST (s0P
, Current_Routine
)
5227 symbolS
*s0P
, *Current_Routine
;
5230 char *s0P_name
, *pnt0
, *pnt1
;
5232 s0P_name
= S_GET_NAME (s0P
);
5233 if (*++s0P_name
!= '_')
5236 for (s1P
= Current_Routine
; s1P
; s1P
= symbol_next (s1P
))
5238 #if 0 /* redundant; RAW_TYPE != N_FUN suffices */
5239 if (!S_IS_DEBUG (s1P
))
5242 if (S_GET_RAW_TYPE (s1P
) != N_FUN
)
5245 pnt1
= S_GET_NAME (s1P
);
5246 /* We assume the two strings are never exactly equal... */
5247 while (*pnt0
++ == *pnt1
++)
5250 /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next.
5251 Note: both pointers have advanced one past the non-matching char. */
5252 if ((*pnt1
== 'F' || *pnt1
== 'f') && *--pnt1
== ':' && *--pnt0
== '\0')
5254 Define_Routine (s1P
, 0, Current_Routine
, Text_Psect
);
5261 * Construct and output the debug symbol table.
5264 vms_build_DST (text_siz
)
5267 register symbolS
*symbolP
;
5268 symbolS
*Current_Routine
= 0;
5269 struct input_file
*Cur_File
= 0;
5270 offsetT Cur_Offset
= -1;
5271 int Cur_Line_Number
= 0;
5272 int File_Number
= 0;
5273 int Debugger_Offset
= 0;
5279 * Write the Traceback Begin Module record
5281 VMS_TBT_Module_Begin ();
5284 * Output debugging info for global variables and static variables
5285 * that are not specific to one routine. We also need to examine
5286 * all stabs directives, to find the definitions to all of the
5287 * advanced data types, and this is done by VMS_LSYM_Parse. This
5288 * needs to be done before any definitions are output to the object
5289 * file, since there can be forward references in the stabs
5290 * directives. When through with parsing, the text of the stabs
5291 * directive is altered, with the definitions removed, so that later
5292 * passes will see directives as they would be written if the type
5293 * were already defined.
5295 * We also look for files and include files, and make a list of
5296 * them. We examine the source file numbers to establish the actual
5297 * lines that code was generated from, and then generate offsets.
5300 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5302 /* Only deal with STAB symbols here. */
5303 if (!S_IS_DEBUG (symbolP
))
5306 * Dispatch on STAB type.
5308 switch (S_GET_RAW_TYPE (symbolP
))
5311 dsc
= S_GET_DESC (symbolP
);
5312 if (dsc
> Cur_File
->max_line
)
5313 Cur_File
->max_line
= dsc
;
5314 if (dsc
< Cur_File
->min_line
)
5315 Cur_File
->min_line
= dsc
;
5318 Cur_File
= find_file (symbolP
);
5320 Cur_File
->min_line
= 1;
5323 Cur_File
= find_file (symbolP
);
5326 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5329 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5331 case N_FUN
: /* For static constant symbols */
5333 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5341 * Now we take a quick sweep through the files and assign offsets
5342 * to each one. This will essentially be the starting line number to
5343 * the debugger for each file. Output the info for the debugger to
5344 * specify the files, and then tell it how many lines to use.
5346 for (Cur_File
= file_root
; Cur_File
; Cur_File
= Cur_File
->next
)
5348 if (Cur_File
->max_line
== 0)
5350 if ((strncmp (Cur_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5353 if ((strncmp (Cur_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5356 /* show a few extra lines at the start of the region selected */
5357 if (Cur_File
->min_line
> 2)
5358 Cur_File
->min_line
-= 2;
5359 Cur_File
->offset
= Debugger_Offset
- Cur_File
->min_line
+ 1;
5360 Debugger_Offset
+= Cur_File
->max_line
- Cur_File
->min_line
+ 1;
5361 if (Cur_File
->same_file_fpnt
)
5363 Cur_File
->file_number
= Cur_File
->same_file_fpnt
->file_number
;
5367 Cur_File
->file_number
= ++File_Number
;
5368 file_available
= VMS_TBT_Source_File (Cur_File
->name
,
5369 Cur_File
->file_number
);
5370 if (!file_available
)
5372 Cur_File
->file_number
= 0;
5377 VMS_TBT_Source_Lines (Cur_File
->file_number
,
5379 Cur_File
->max_line
- Cur_File
->min_line
+ 1);
5381 Cur_File
= (struct input_file
*) NULL
;
5384 * Scan the symbols and write out the routines
5385 * (this makes the assumption that symbols are in
5386 * order of ascending text segment offset)
5388 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5391 * Deal with text symbols.
5393 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
5396 * Ignore symbols starting with "L", as they are local symbols.
5398 if (*S_GET_NAME (symbolP
) == 'L')
5401 * If there is a routine start defined, terminate it.
5403 if (Current_Routine
)
5404 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5407 * Check for & skip dummy labels like "gcc_compiled.".
5408 * They're identified by the IN_DEFAULT_SECTION flag.
5410 if ((S_GET_OTHER (symbolP
) & IN_DEFAULT_SECTION
) != 0 &&
5411 S_GET_VALUE (symbolP
) == 0)
5414 * Store the routine begin traceback info.
5416 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5417 Current_Routine
= symbolP
;
5419 * Define symbols local to this routine.
5421 local_symbols_DST (symbolP
, Current_Routine
);
5429 * Deal with STAB symbols.
5431 else if (S_IS_DEBUG (symbolP
))
5434 * Dispatch on STAB type.
5436 switch (S_GET_RAW_TYPE (symbolP
))
5442 /* Offset the line into the correct portion of the file. */
5443 if (Cur_File
->file_number
== 0)
5445 val
= S_GET_VALUE (symbolP
);
5446 /* Sometimes the same offset gets several source lines
5447 assigned to it. We should be selective about which
5448 lines we allow, we should prefer lines that are in
5449 the main source file when debugging inline functions. */
5450 if (val
== Cur_Offset
&& Cur_File
->file_number
!= 1)
5453 /* calculate actual debugger source line */
5454 dsc
= S_GET_DESC (symbolP
) + Cur_File
->offset
;
5455 S_SET_DESC (symbolP
, dsc
);
5457 * Define PC/Line correlation.
5459 if (Cur_Offset
== -1)
5462 * First N_SLINE; set up initial correlation.
5464 VMS_TBT_Line_PC_Correlation (dsc
,
5469 else if ((dsc
- Cur_Line_Number
) <= 0)
5472 * Line delta is not +ve, we need to close the line and
5473 * start a new PC/Line correlation.
5475 VMS_TBT_Line_PC_Correlation (0,
5479 VMS_TBT_Line_PC_Correlation (dsc
,
5487 * Line delta is +ve, all is well.
5489 VMS_TBT_Line_PC_Correlation (dsc
- Cur_Line_Number
,
5494 /* Update the current line/PC info. */
5495 Cur_Line_Number
= dsc
;
5503 /* Remember that we had a source file and emit
5504 the source file debugger record. */
5505 Cur_File
= find_file (symbolP
);
5509 /* We need to make sure that we are really in the actual
5510 source file when we compute the maximum line number.
5511 Otherwise the debugger gets really confused. */
5512 Cur_File
= find_file (symbolP
);
5518 } /* if (IS_DEBUG) */
5522 * If there is a routine start defined, terminate it
5523 * (and the line numbers).
5525 if (Current_Routine
)
5527 /* Terminate the line numbers. */
5528 VMS_TBT_Line_PC_Correlation (0,
5529 text_siz
- S_GET_VALUE (Current_Routine
),
5532 /* Terminate the routine. */
5533 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5537 * Write the Traceback End Module TBT record
5539 VMS_TBT_Module_End ();
5544 * Write a VAX/VMS object file (everything else has been done!)
5547 vms_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
5552 fragS
*text_frag_root
;
5553 fragS
*data_frag_root
;
5555 register struct VMS_Symbol
*vsp
;
5558 * Initialize program section indices; values get updated later.
5560 Psect_Number
= 0; /* next Psect Index to use */
5561 Text_Psect
= -1; /* Text Psect Index */
5562 Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
5563 Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
5564 /* Initialize other state variables. */
5566 Local_Initd_Data_Size
= 0;
5569 * Create the actual output file and populate it with required
5570 * "module header" information.
5572 Create_VMS_Object_File ();
5573 Write_VMS_MHD_Records ();
5576 * Create the Data segment:
5578 * Since this is REALLY hard to do any other way,
5579 * we actually manufacture the data segment and
5580 * then store the appropriate values out of it.
5581 * We need to generate this early, so that globalvalues
5582 * can be properly emitted.
5585 synthesize_data_segment (data_siz
, text_siz
, data_frag_root
);
5588 /******* Global Symbol Directory *******/
5591 * Emit globalvalues now. We must do this before the text psect is
5592 * defined, or we will get linker warnings about multiply defined
5593 * symbols. All of the globalvalues "reference" psect 0, although
5594 * it really does not have anything to do with it.
5596 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
5598 * Define the Text Psect
5600 Text_Psect
= Psect_Number
++;
5601 VMS_Psect_Spec ("$code", text_siz
, ps_TEXT
, 0);
5603 * Define the BSS Psect
5607 Bss_Psect
= Psect_Number
++;
5608 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, ps_DATA
, 0);
5611 * Define symbols to the linker.
5613 global_symbol_directory (text_siz
, data_siz
);
5615 * Define the Data Psect
5617 if (data_siz
> 0 && Local_Initd_Data_Size
> 0)
5619 Data_Psect
= Psect_Number
++;
5620 VMS_Psect_Spec ("$data", Local_Initd_Data_Size
, ps_DATA
, 0);
5622 * Local initialized data (N_DATA) symbols need to be updated to the
5623 * proper value of Data_Psect now that it's actually been defined.
5624 * (A dummy value was used in global_symbol_directory() above.)
5626 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5627 if (vsp
->Psect_Index
< 0 && S_GET_RAW_TYPE (vsp
->Symbol
) == N_DATA
)
5628 vsp
->Psect_Index
= Data_Psect
;
5632 /******* Text Information and Relocation Records *******/
5635 * Write the text segment data
5638 vms_fixup_text_section (text_siz
, text_frag_root
, data_frag_root
);
5640 * Write the data segment data, then discard it.
5644 vms_fixup_data_section (data_siz
, text_siz
);
5645 free (Data_Segment
), Data_Segment
= 0;
5649 /******* Debugger Symbol Table Records *******/
5651 vms_build_DST (text_siz
);
5655 * Write the End Of Module record
5657 if (Entry_Point_Symbol
== 0)
5658 Write_VMS_EOM_Record (-1, 0);
5660 Write_VMS_EOM_Record (Text_Psect
,
5661 S_GET_VALUE (Entry_Point_Symbol
));
5664 * All done, close the object file
5666 Close_VMS_Object_File ();
5669 /* end of obj-vms.c */