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;
222 /* Every object file must specify an module name, which is also used by
223 traceback records. Set in Write_VMS_MHD_Records(). */
225 static char Module_Name
[255+1];
228 * Variable descriptors are used tell the debugger the data types of certain
229 * more complicated variables (basically anything involving a structure,
230 * union, enum, array or pointer). Some non-pointer variables of the
231 * basic types that the debugger knows about do not require a variable
234 * Since it is impossible to have a variable descriptor longer than 128
235 * bytes by virtue of the way that the VMS object language is set up,
236 * it makes not sense to make the arrays any longer than this, or worrying
237 * about dynamic sizing of the array.
239 * These are the arrays and counters that we use to build a variable
243 #define MAX_DEBUG_RECORD 128
244 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
245 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
246 static int Lpnt
; /* index into Local */
247 static int Apoint
; /* index into Asuffix */
248 static char overflow
; /* flag to indicate we have written too much*/
249 static int total_len
; /* used to calculate the total length of variable
250 descriptor plus array descriptor - used for len byte*/
252 /* Flag if we have told user about finding global constants in the text
254 static int gave_compiler_message
= 0;
258 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
260 static int VMS_Object_File_FD
; /* File Descriptor for object file */
261 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
262 static int Object_Record_Offset
;/* Offset to end of data */
263 static int Current_Object_Record_Type
; /* Type of record in above */
266 * Macros for moving data around. Must work on big-endian systems.
268 #ifdef VMS /* These are more efficient for VMS->VMS systems */
269 #define COPY_LONG(dest,val) ( *(long *)(dest) = (val) )
270 #define COPY_SHORT(dest,val) ( *(short *)(dest) = (val) )
272 #define COPY_LONG(dest,val) md_number_to_chars ((dest), (val), 4)
273 #define COPY_SHORT(dest,val) md_number_to_chars ((dest), (val), 2)
276 * Macros for placing data into the object record buffer.
278 #define PUT_LONG(val) \
279 ( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \
280 Object_Record_Offset += 4 )
282 #define PUT_SHORT(val) \
283 ( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \
284 Object_Record_Offset += 2 )
286 #define PUT_CHAR(val) ( Object_Record_Buffer[Object_Record_Offset++] = (val) )
288 #define PUT_COUNTED_STRING(cp) do { \
289 register const char *p = (cp); \
290 PUT_CHAR ((char) strlen (p)); \
291 while (*p) PUT_CHAR (*p++); } while (0)
294 * Macro for determining if a Name has psect attributes attached
297 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
298 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
300 #define HAS_PSECT_ATTRIBUTES(Name) \
301 (strncmp ((*Name == '_' ? Name + 1 : Name), \
302 PSECT_ATTRIBUTES_STRING, \
303 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
306 /* in: segT out: N_TYPE bits */
307 const short seg_N_TYPE
[] =
313 N_UNDF
, /* unknown */
315 N_UNDF
, /* expression */
319 N_REGISTER
, /* register */
322 const segT N_TYPE_seg
[N_TYPE
+ 2] =
323 { /* N_TYPE == 0x1E = 32-2 */
324 SEG_UNKNOWN
, /* N_UNDF == 0 */
326 SEG_ABSOLUTE
, /* N_ABS == 2 */
328 SEG_TEXT
, /* N_TEXT == 4 */
330 SEG_DATA
, /* N_DATA == 6 */
332 SEG_BSS
, /* N_BSS == 8 */
334 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
335 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
336 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
337 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
342 /* Local support routines which return a value. */
344 static struct input_file
*find_file
PARAMS ((symbolS
*));
345 static struct VMS_DBG_Symbol
*find_symbol
PARAMS ((int));
346 static symbolS
*Define_Routine
PARAMS ((symbolS
*,int,symbolS
*,int));
348 static char *cvt_integer
PARAMS ((char *,int *));
349 static char *fix_name
PARAMS ((char *));
350 static char *get_struct_name
PARAMS ((char *));
352 static offsetT VMS_Initialized_Data_Size
PARAMS ((symbolS
*,unsigned));
354 static int VMS_TBT_Source_File
PARAMS ((char *,int));
355 static int gen1
PARAMS ((struct VMS_DBG_Symbol
*,int));
356 static int forward_reference
PARAMS ((char *));
357 static int final_forward_reference
PARAMS ((struct VMS_DBG_Symbol
*));
358 static int VMS_typedef_parse
PARAMS ((char *));
359 static int hash_string
PARAMS ((const char *));
360 static int VMS_Psect_Spec
PARAMS ((const char *,int,enum ps_type
,
361 struct VMS_Symbol
*));
363 /* Local support routines which don't directly return any value. */
365 static void s_const
PARAMS ((int));
366 static void Create_VMS_Object_File
PARAMS ((void));
367 static void Flush_VMS_Object_Record_Buffer
PARAMS ((void));
368 static void Set_VMS_Object_File_Record
PARAMS ((int));
369 static void Close_VMS_Object_File
PARAMS ((void));
370 static void vms_tir_stack_psect
PARAMS ((int,int,int));
371 static void VMS_Store_Immediate_Data
PARAMS ((const char *,int,int));
372 static void VMS_Set_Data
PARAMS ((int,int,int,int));
373 static void VMS_Store_Struct
PARAMS ((int));
374 static void VMS_Def_Struct
PARAMS ((int));
375 static void VMS_Set_Struct
PARAMS ((int));
376 static void VMS_TBT_Module_Begin
PARAMS ((void));
377 static void VMS_TBT_Module_End
PARAMS ((void));
378 static void VMS_TBT_Routine_Begin
PARAMS ((symbolS
*,int));
379 static void VMS_TBT_Routine_End
PARAMS ((int,symbolS
*));
380 static void VMS_TBT_Block_Begin
PARAMS ((symbolS
*,int,char *));
381 static void VMS_TBT_Block_End
PARAMS ((valueT
));
382 static void VMS_TBT_Line_PC_Correlation
PARAMS ((int,int,int,int));
383 static void VMS_TBT_Source_Lines
PARAMS ((int,int,int));
384 static void fpush
PARAMS ((int,int));
385 static void rpush
PARAMS ((int,int));
386 static void array_suffix
PARAMS ((struct VMS_DBG_Symbol
*));
387 static void new_forward_ref
PARAMS ((int));
388 static void generate_suffix
PARAMS ((struct VMS_DBG_Symbol
*,int));
389 static void bitfield_suffix
PARAMS ((struct VMS_DBG_Symbol
*,int));
390 static void setup_basic_type
PARAMS ((struct VMS_DBG_Symbol
*));
391 static void VMS_DBG_record
PARAMS ((struct VMS_DBG_Symbol
*,int,int,char *));
392 static void VMS_local_stab_Parse
PARAMS ((symbolS
*));
393 static void VMS_stab_parse
PARAMS ((symbolS
*,int,int,int,int));
394 static void VMS_GSYM_Parse
PARAMS ((symbolS
*,int));
395 static void VMS_LCSYM_Parse
PARAMS ((symbolS
*,int));
396 static void VMS_STSYM_Parse
PARAMS ((symbolS
*,int));
397 static void VMS_RSYM_Parse
PARAMS ((symbolS
*,symbolS
*,int));
398 static void VMS_LSYM_Parse
PARAMS ((void));
399 static void Define_Local_Symbols
PARAMS ((symbolS
*,symbolS
*,symbolS
*,int));
400 static void Write_VMS_MHD_Records
PARAMS ((void));
401 static void Write_VMS_EOM_Record
PARAMS ((int,valueT
));
402 static void VMS_Case_Hack_Symbol
PARAMS ((const char *,char *));
403 static void VMS_Modify_Psect_Attributes
PARAMS ((const char *,int *));
404 static void VMS_Global_Symbol_Spec
PARAMS ((const char *,int,int,int));
405 static void VMS_Local_Environment_Setup
PARAMS ((const char *));
406 static void VMS_Emit_Globalvalues
PARAMS ((unsigned,unsigned,char *));
407 static void VMS_Procedure_Entry_Pt
PARAMS ((char *,int,int,int));
408 static void VMS_Set_Psect
PARAMS ((int,int,int));
409 static void VMS_Store_Repeated_Data
PARAMS ((int,char *,int,int));
410 static void VMS_Store_PIC_Symbol_Reference
PARAMS ((symbolS
*,int,
412 static void VMS_Fix_Indirect_Reference
PARAMS ((int,int,fragS
*,fragS
*));
414 /* Support code which used to be inline within vms_write_object_file. */
415 static void vms_fixup_text_section
PARAMS ((unsigned,struct frag
*,struct frag
*));
416 static void synthesize_data_segment
PARAMS ((unsigned,unsigned,struct frag
*));
417 static void vms_fixup_data_section
PARAMS ((unsigned,unsigned));
418 static void global_symbol_directory
PARAMS ((unsigned,unsigned));
419 static void local_symbols_DST
PARAMS ((symbolS
*,symbolS
*));
420 static void vms_build_DST
PARAMS ((unsigned));
423 /* The following code defines the special types of pseudo-ops that we
426 unsigned char const_flag
= IN_DEFAULT_SECTION
;
430 int arg
; /* 3rd field from obj_pseudo_table[]; not needed here */
432 /* Since we don't need `arg', use it as our scratch variable so that
433 we won't get any "not used" warnings about it. */
434 arg
= get_absolute_expression ();
435 subseg_set (SEG_DATA
, (subsegT
) arg
);
437 demand_empty_rest_of_line ();
440 const pseudo_typeS obj_pseudo_table
[] =
442 {"const", s_const
, 0},
444 }; /* obj_pseudo_table */
447 /* Routine to perform RESOLVE_SYMBOL_REDEFINITION(). */
450 vms_resolve_symbol_redef (sym
)
454 * If the new symbol is .comm AND it has a size of zero,
455 * we ignore it (i.e. the old symbol overrides it)
457 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)
458 && frag_now_fix () == 0)
460 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
465 * If the old symbol is .comm and it has a size of zero,
466 * we override it with the new symbol value.
468 if (S_IS_EXTERNAL (sym
) && S_IS_DEFINED (sym
) && S_GET_VALUE (sym
) == 0)
470 as_warn ("compiler redefined zero-size common symbol `%s'",
472 sym
->sy_frag
= frag_now
;
473 S_SET_OTHER (sym
, const_flag
);
474 S_SET_VALUE (sym
, frag_now_fix ());
475 /* Keep N_EXT bit. */
476 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
);
484 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
485 dummy label(s) gcc inserts at the beginning of each file it generates.
486 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.7) puts "gcc2_compiled."
487 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
490 vms_check_for_special_label (symbolP
)
493 /* Special labels only occur prior to explicit section directives. */
494 if ((const_flag
& IN_DEFAULT_SECTION
) != 0)
496 char *sym_name
= S_GET_NAME (symbolP
);
498 if (*sym_name
== '_')
501 if (!strcmp (sym_name
, "__vax_g_doubles"))
503 #if 0 /* not necessary */
504 else if (!strcmp (sym_name
, "__vax_d_doubles"))
507 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
508 else if (!strcmp (sym_name
, "gcc_compiled."))
510 else if (!strcmp (sym_name
, "__gnu_language_cplusplus"))
511 flag_hash_long_names
= 1;
519 obj_read_begin_hook ()
526 obj_crawl_symbol_chain (headers
)
527 object_headers
*headers
;
531 int symbol_number
= 0;
533 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
534 while ((symbolP
= *symbolPP
) != NULL
)
536 resolve_symbol_value (symbolP
);
538 /* OK, here is how we decide which symbols go out into the
539 brave new symtab. Symbols that do are:
541 * symbols with no name (stabd's?)
542 * symbols with debug info in their N_TYPE
543 * symbols with \1 as their 3rd character (numeric labels)
544 * "local labels" needed for PIC fixups
546 Symbols that don't are:
547 * symbols that are registers
549 All other symbols are output. We complain if a deleted
550 symbol was marked external. */
552 if (!S_IS_REGISTER (symbolP
))
554 symbolP
->sy_number
= symbol_number
++;
555 symbolP
->sy_name_offset
= 0;
556 symbolPP
= &(symbol_next (symbolP
));
560 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
562 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
565 /* Unhook it from the chain. */
566 *symbolPP
= symbol_next (symbolP
);
567 } /* if this symbol should be in the output */
569 } /* for each symbol */
571 H_SET_STRING_SIZE (headers
, string_byte_count
);
572 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
573 } /* obj_crawl_symbol_chain() */
576 /****** VMS OBJECT FILE HACKING ROUTINES *******/
579 /* Create the VMS object file. */
582 Create_VMS_Object_File ()
584 #if defined(eunice) || !defined(VMS)
585 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
587 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
588 "mbc=16", "deq=64", "fop=tef", "shr=nil");
590 /* Deal with errors. */
591 if (VMS_Object_File_FD
< 0)
592 as_fatal ("Couldn't create VMS object file \"%s\"", out_file_name
);
593 /* Initialize object file hacking variables. */
594 Object_Record_Offset
= 0;
595 Current_Object_Record_Type
= -1;
599 /* Flush the object record buffer to the object file. */
602 Flush_VMS_Object_Record_Buffer ()
604 /* If the buffer is empty, there's nothing to do. */
605 if (Object_Record_Offset
== 0)
608 #ifndef VMS /* For cross-assembly purposes. */
612 /* "Variable-length record" files have a two byte length field
613 prepended to each record. It's normally out-of-band, and native
614 VMS output will insert it automatically for this type of file.
615 When cross-assembling, we must write it explicitly. */
616 md_number_to_chars (RecLen
, Object_Record_Offset
, 2);
617 if (write (VMS_Object_File_FD
, RecLen
, 2) != 2)
618 error ("I/O error writing VMS object file (length prefix)");
619 /* We also need to force the actual record to be an even number of
620 bytes. For native output, that's automatic; when cross-assembling,
621 pad with a NUL byte if length is odd. Do so _after_ writing the
622 pre-padded length. Since our buffer is defined with even size,
623 an odd offset implies that it has some room left. */
624 if ((Object_Record_Offset
& 1) != 0)
625 Object_Record_Buffer
[Object_Record_Offset
++] = '\0';
629 /* Write the data to the file. */
630 if (write (VMS_Object_File_FD
, Object_Record_Buffer
, Object_Record_Offset
)
631 != Object_Record_Offset
)
632 error ("I/O error writing VMS object file");
634 /* The buffer is now empty. */
635 Object_Record_Offset
= 0;
639 /* Declare a particular type of object file record. */
642 Set_VMS_Object_File_Record (Type
)
645 /* If the type matches, we are done. */
646 if (Type
== Current_Object_Record_Type
)
648 /* Otherwise: flush the buffer. */
649 Flush_VMS_Object_Record_Buffer ();
650 /* Remember the new type. */
651 Current_Object_Record_Type
= Type
;
655 /* Close the VMS Object file. */
658 Close_VMS_Object_File ()
660 /* Flush (should never be necessary) and reset saved record-type context. */
661 Set_VMS_Object_File_Record (-1);
663 #ifndef VMS /* For cross-assembly purposes. */
668 /* Write a 2 byte record-length field of -1 into the file, which
669 means end-of-block when read, hence end-of-file when occurring
670 in the file's last block. It is only needed for variable-length
671 record files transferred to VMS as fixed-length record files
672 (typical for binary FTP; NFS shouldn't need it, but it won't hurt). */
673 md_number_to_chars (RecLen
, minus_one
, 2);
674 write (VMS_Object_File_FD
, RecLen
, 2);
677 /* When written on a VMS system, the file header (cf inode) will record
678 the actual end-of-file position and no inline marker is needed. */
681 close (VMS_Object_File_FD
);
685 /****** Text Information and Relocation routines ******/
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
)
745 Set_VMS_Object_File_Record (Record_Type
);
746 /* We can only store as most 128 bytes at a time due to the way that
747 TIR commands are encoded. */
750 i
= (Size
> 128) ? 128 : Size
;
752 /* If we cannot accommodate this record, flush the buffer. */
753 if ((Object_Record_Offset
+ i
+ 1) >= sizeof Object_Record_Buffer
)
754 Flush_VMS_Object_Record_Buffer ();
755 /* If the buffer is empty we must insert record type. */
756 if (Object_Record_Offset
== 0)
757 PUT_CHAR (Record_Type
);
758 /* Store the count. The Store Immediate TIR command is implied by
759 a negative command byte, and the length of the immediate data
760 is abs(command_byte). So, we write the negated length value. */
761 PUT_CHAR ((char) (-i
& 0xff));
762 /* Now store the data. */
764 PUT_CHAR (*Pointer
++);
766 /* Flush the buffer if it is more than 75% full. */
767 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
768 Flush_VMS_Object_Record_Buffer ();
772 /* Make a data reference. */
775 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
781 Set_VMS_Object_File_Record (Record_Type
);
782 /* If the buffer is empty we must insert the record type. */
783 if (Object_Record_Offset
== 0)
784 PUT_CHAR (Record_Type
);
785 /* Stack the Psect base with its offset. */
786 vms_tir_stack_psect (Psect_Index
, Offset
, Force
);
787 /* Set relocation base. */
788 PUT_CHAR (TIR_S_C_STO_PIDR
);
789 /* Flush the buffer if it is more than 75% full. */
790 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
791 Flush_VMS_Object_Record_Buffer ();
795 /* Make a debugger reference to a struct, union or enum. */
798 VMS_Store_Struct (Struct_Index
)
801 /* We are writing a debug record. */
802 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
803 /* If the buffer is empty we must insert the record type. */
804 if (Object_Record_Offset
== 0)
805 PUT_CHAR (OBJ_S_C_DBG
);
806 PUT_CHAR (TIR_S_C_STA_UW
);
807 PUT_SHORT (Struct_Index
);
808 PUT_CHAR (TIR_S_C_CTL_STKDL
);
809 PUT_CHAR (TIR_S_C_STO_L
);
810 /* Flush the buffer if it is more than 75% full. */
811 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
812 Flush_VMS_Object_Record_Buffer ();
816 /* Make a debugger reference to partially define a struct, union or enum. */
819 VMS_Def_Struct (Struct_Index
)
822 /* We are writing a debug record. */
823 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
824 /* If the buffer is empty we must insert the record type. */
825 if (Object_Record_Offset
== 0)
826 PUT_CHAR (OBJ_S_C_DBG
);
827 PUT_CHAR (TIR_S_C_STA_UW
);
828 PUT_SHORT (Struct_Index
);
829 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
830 /* Flush the buffer if it is more than 75% full. */
831 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
832 Flush_VMS_Object_Record_Buffer ();
836 VMS_Set_Struct (Struct_Index
)
838 { /* see previous functions for comments */
839 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
840 if (Object_Record_Offset
== 0)
841 PUT_CHAR (OBJ_S_C_DBG
);
842 PUT_CHAR (TIR_S_C_STA_UW
);
843 PUT_SHORT (Struct_Index
);
844 PUT_CHAR (TIR_S_C_CTL_STLOC
);
845 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
846 Flush_VMS_Object_Record_Buffer ();
850 /****** Traceback Information routines ******/
853 /* Write the Traceback Module Begin record. */
856 VMS_TBT_Module_Begin ()
858 register char *cp
, *cp1
;
862 /* Arrange to store the data locally (leave room for size byte). */
865 *cp
++ = DST_S_C_MODBEG
;
866 *cp
++ = 0; /* flags; not used */
868 * Language type == "C"
870 * (FIXME: this should be based on the input...)
872 COPY_LONG (cp
, DST_S_C_C
);
874 /* Store the module name. */
875 *cp
++ = (char) strlen (Module_Name
);
879 /* Now we can store the record size. */
882 /* Put it into the object record. */
883 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
887 /* Write the Traceback Module End record. */
890 VMS_TBT_Module_End ()
896 Local
[1] = DST_S_C_MODEND
;
897 /* Put it into the object record. */
898 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
902 /* Write a Traceback Routine Begin record. */
905 VMS_TBT_Routine_Begin (symbolP
, Psect
)
909 register char *cp
, *cp1
;
915 /* Strip the leading "_" from the name. */
916 Name
= S_GET_NAME (symbolP
);
919 /* Get the text psect offset. */
920 Offset
= S_GET_VALUE (symbolP
);
921 /* Set the record size. */
922 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
924 /* DST type "routine begin". */
925 Local
[1] = DST_S_C_RTNBEG
;
926 /* Uses CallS/CallG. */
928 /* Store the data so far. */
929 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
930 /* Make sure we are still generating a OBJ_S_C_TBT record. */
931 if (Object_Record_Offset
== 0)
932 PUT_CHAR (OBJ_S_C_TBT
);
933 /* Stack the address. */
934 vms_tir_stack_psect (Psect
, Offset
, 0);
935 /* Store the data reference. */
936 PUT_CHAR (TIR_S_C_STO_PIDR
);
937 /* Store the counted string as data. */
940 Size
= strlen (cp1
) + 1;
944 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
948 /* Write a Traceback Routine End record.
950 We *must* search the symbol table to find the next routine, since the
951 assember has a way of reassembling the symbol table OUT OF ORDER Thus
952 the next routine in the symbol list is not necessarily the next one in
953 memory. For debugging to work correctly we must know the size of the
957 VMS_TBT_Routine_End (Max_Size
, sp
)
962 int Size
= 0x7fffffff;
964 valueT sym_value
, sp_value
= S_GET_VALUE (sp
);
966 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
968 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
970 if (*S_GET_NAME (symbolP
) == 'L')
972 sym_value
= S_GET_VALUE (symbolP
);
973 if (sym_value
> sp_value
&& sym_value
< Size
)
977 * Dummy labels like "gcc_compiled." should no longer reach here.
981 /* check if gcc_compiled. has size of zero */
982 if (sym_value
== sp_value
&&
984 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
985 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
990 if (Size
== 0x7fffffff)
992 Size
-= sp_value
; /* and get the size of the routine */
995 /* DST type is "routine end". */
996 Local
[1] = DST_S_C_RTNEND
;
997 Local
[2] = 0; /* unused */
998 /* Size of routine. */
999 COPY_LONG (&Local
[3], Size
);
1000 /* Store the record. */
1001 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1005 /* Write a Traceback Block Begin record. */
1008 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1013 register char *cp
, *cp1
;
1018 /* Set the record size. */
1019 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1021 /* DST type is "begin block"; we simulate with a phony routine. */
1022 Local
[1] = DST_S_C_BLKBEG
;
1023 /* Uses CallS/CallG. */
1025 /* Store the data so far. */
1026 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1027 /* Make sure we are still generating a debug record. */
1028 if (Object_Record_Offset
== 0)
1029 PUT_CHAR (OBJ_S_C_DBG
);
1030 /* Now get the symbol address. */
1031 PUT_CHAR (TIR_S_C_STA_WPL
);
1033 /* Get the text psect offset. */
1034 Offset
= S_GET_VALUE (symbolP
);
1036 /* Store the data reference. */
1037 PUT_CHAR (TIR_S_C_STO_PIDR
);
1038 /* Store the counted string as data. */
1041 Size
= strlen (cp1
) + 1;
1045 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1049 /* Write a Traceback Block End record. */
1052 VMS_TBT_Block_End (Size
)
1057 Local
[0] = 6; /* record length */
1058 /* DST type is "block end"; simulate with a phony end routine. */
1059 Local
[1] = DST_S_C_BLKEND
;
1060 Local
[2] = 0; /* unused, must be zero */
1061 COPY_LONG (&Local
[3], Size
);
1062 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1066 /* Write a Line number <-> Program Counter correlation record. */
1069 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1081 * If not delta, set our PC/Line number correlation.
1083 cp
= &Local
[1]; /* Put size in Local[0] later. */
1084 /* DST type is "Line Number/PC correlation". */
1085 *cp
++ = DST_S_C_LINE_NUM
;
1086 /* Set Line number. */
1087 if (Line_Number
- 1 <= 255)
1089 *cp
++ = DST_S_C_SET_LINUM_B
;
1090 *cp
++ = (char) (Line_Number
- 1);
1092 else if (Line_Number
- 1 <= 65535)
1094 *cp
++ = DST_S_C_SET_LINE_NUM
;
1095 COPY_SHORT (cp
, Line_Number
- 1), cp
+= 2;
1099 *cp
++ = DST_S_C_SET_LINUM_L
;
1100 COPY_LONG (cp
, Line_Number
- 1), cp
+= 4;
1103 *cp
++ = DST_S_C_SET_ABS_PC
;
1104 /* Store size now that we know it, then output the data. */
1105 Local
[0] = cp
- &Local
[1];
1106 /* Account for the space that TIR_S_C_STO_PIDR will use for the PC. */
1107 Local
[0] += 4; /* size includes length of another longword */
1108 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1109 /* Make sure we are still generating a OBJ_S_C_TBT record. */
1110 if (Object_Record_Offset
== 0)
1111 PUT_CHAR (OBJ_S_C_TBT
);
1112 vms_tir_stack_psect (Psect
, Offset
, 0);
1113 PUT_CHAR (TIR_S_C_STO_PIDR
);
1114 /* Do a PC offset of 0 to register the line number. */
1116 Local
[1] = DST_S_C_LINE_NUM
;
1117 Local
[2] = 0; /* Increment PC by 0 and register line # */
1118 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1125 * When delta is negative, terminate the line numbers.
1127 Local
[0] = 1 + 1 + 4;
1128 Local
[1] = DST_S_C_LINE_NUM
;
1129 Local
[2] = DST_S_C_TERM_L
;
1130 COPY_LONG (&Local
[3], Offset
);
1131 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1135 * Do a PC/Line delta.
1138 *cp
++ = DST_S_C_LINE_NUM
;
1139 if (Line_Number
> 1)
1141 /* We need to increment the line number. */
1142 if (Line_Number
- 1 <= 255)
1144 *cp
++ = DST_S_C_INCR_LINUM
;
1145 *cp
++ = Line_Number
- 1;
1147 else if (Line_Number
- 1 <= 65535)
1149 *cp
++ = DST_S_C_INCR_LINUM_W
;
1150 COPY_SHORT (cp
, Line_Number
- 1), cp
+= 2;
1154 *cp
++ = DST_S_C_INCR_LINUM_L
;
1155 COPY_LONG (cp
, Line_Number
- 1), cp
+= 4;
1163 /* Small offsets are encoded as negative numbers, rather than the
1164 usual non-negative type code followed by another data field. */
1165 *cp
++ = (char) -Offset
;
1167 else if (Offset
<= 65535)
1169 *cp
++ = DST_S_C_DELTA_PC_W
;
1170 COPY_SHORT (cp
, Offset
), cp
+= 2;
1174 *cp
++ = DST_S_C_DELTA_PC_L
;
1175 COPY_LONG (cp
, Offset
), cp
+= 4;
1177 /* Set size now that be know it, then output the data. */
1178 Local
[0] = cp
- &Local
[1];
1179 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1184 /* Describe a source file to the debugger. */
1187 VMS_TBT_Source_File (Filename
, ID_Number
)
1192 int len
, rfo
, ffb
, ebk
;
1195 #ifdef VMS /* Used for native assembly */
1197 struct FAB fab
; /* RMS file access block */
1198 struct NAM nam
; /* file name information */
1199 struct XABDAT xabdat
; /* date+time fields */
1200 struct XABFHC xabfhc
; /* file header characteristics */
1201 char resultant_string_buffer
[255 + 1];
1204 * Set up RMS structures:
1206 /* FAB -- file access block */
1207 memset ((char *) &fab
, 0, sizeof fab
);
1208 fab
.fab$b_bid
= FAB$C_BID
;
1209 fab
.fab$b_bln
= (unsigned char) sizeof fab
;
1210 fab
.fab$l_fna
= Filename
;
1211 fab
.fab$b_fns
= (unsigned char) strlen (Filename
);
1212 fab
.fab$l_nam
= (char *) &nam
;
1213 fab
.fab$l_xab
= (char *) &xabdat
;
1214 /* NAM -- file name block */
1215 memset ((char *) &nam
, 0, sizeof nam
);
1216 nam
.nam$b_bid
= NAM$C_BID
;
1217 nam
.nam$b_bln
= (unsigned char) sizeof nam
;
1218 nam
.nam$l_rsa
= resultant_string_buffer
;
1219 nam
.nam$b_rss
= (unsigned char) (sizeof resultant_string_buffer
- 1);
1220 /* XABs -- extended attributes blocks */
1221 memset ((char *) &xabdat
, 0, sizeof xabdat
);
1222 xabdat
.xab$b_cod
= XAB$C_DAT
;
1223 xabdat
.xab$b_bln
= (unsigned char) sizeof xabdat
;
1224 xabdat
.xab$l_nxt
= (char *) &xabfhc
;
1225 memset ((char *) &xabfhc
, 0, sizeof xabfhc
);
1226 xabfhc
.xab$b_cod
= XAB$C_FHC
;
1227 xabfhc
.xab$b_bln
= (unsigned char) sizeof xabfhc
;
1228 xabfhc
.xab$l_nxt
= 0;
1230 * Get the file information
1232 Status
= sys$
open (&fab
);
1235 as_tsktsk ("Couldn't find source file \"%s\", status=%%X%x",
1240 /* Now extract fields of interest. */
1241 memcpy (cdt
, (char *) &xabdat
.xab$q_cdt
, 8); /* creation date */
1242 ebk
= xabfhc
.xab$l_ebk
; /* end-of-file block */
1243 ffb
= xabfhc
.xab$w_ffb
; /* first free byte of last block */
1244 rfo
= xabfhc
.xab$b_rfo
; /* record format */
1245 len
= nam
.nam$b_rsl
; /* length of Filename */
1246 resultant_string_buffer
[len
] = '\0';
1247 Filename
= resultant_string_buffer
; /* full filename */
1248 #else /* Cross-assembly */
1249 /* [Perhaps we ought to use actual values derived from stat() here?] */
1250 memset (cdt
, 0, 8); /* null VMS quadword binary time */
1251 ebk
= ffb
= rfo
= 0;
1252 len
= strlen (Filename
);
1253 if (len
> 255) /* a single byte is used as count prefix */
1255 Filename
+= (len
- 255); /* tail end is more significant */
1260 cp
= &Local
[1]; /* fill in record length later */
1261 *cp
++ = DST_S_C_SOURCE
; /* DST type is "source file" */
1262 *cp
++ = DST_S_C_SRC_FORMFEED
; /* formfeeds count as source records */
1263 *cp
++ = DST_S_C_SRC_DECLFILE
; /* declare source file */
1264 know (cp
== &Local
[4]);
1265 *cp
++ = 0; /* fill in this length below */
1266 *cp
++ = 0; /* flags; must be zero */
1267 COPY_SHORT (cp
, ID_Number
), cp
+= 2; /* file ID number */
1268 memcpy (cp
, cdt
, 8), cp
+= 8; /* creation date+time */
1269 COPY_LONG (cp
, ebk
), cp
+= 4; /* end-of-file block */
1270 COPY_SHORT (cp
, ffb
), cp
+= 2; /* first free byte of last block */
1271 *cp
++ = (char) rfo
; /* RMS record format */
1275 *cp
++ = *Filename
++;
1276 /* Library module name (none). */
1278 /* Now that size is known, fill it in and write out the record. */
1279 Local
[4] = cp
- &Local
[5]; /* source file declaration size */
1280 Local
[0] = cp
- &Local
[1]; /* TBT record size */
1281 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1286 /* Traceback information is described in terms of lines from compiler
1287 listing files, not lines from source files. We need to set up the
1288 correlation between listing line numbers and source line numbers.
1289 Since gcc's .stabn directives refer to the source lines, we just
1290 need to describe a one-to-one correspondence. */
1293 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1295 int Starting_Line_Number
;
1296 int Number_Of_Lines
;
1300 char Local
[128]; /* room enough to describe 1310700 lines... */
1302 cp
= &Local
[1]; /* Put size in Local[0] later. */
1303 *cp
++ = DST_S_C_SOURCE
; /* DST type is "source file". */
1304 *cp
++ = DST_S_C_SRC_SETFILE
; /* Set Source File. */
1305 COPY_SHORT (cp
, ID_Number
), cp
+= 2; /* File ID Number. */
1306 /* Set record number and define lines. Since no longword form of
1307 SRC_DEFLINES is available, we need to be able to cope with any huge
1308 files a chunk at a time. It doesn't matter for tracebacks, since
1309 unspecified lines are mapped one-to-one and work out right, but it
1310 does matter within the debugger. Without this explicit mapping,
1311 it will complain about lines not existing in the module. */
1312 chunk_limit
= (sizeof Local
- 5) / 6;
1313 if (Number_Of_Lines
> 65535 * chunk_limit
) /* avoid buffer overflow */
1314 Number_Of_Lines
= 65535 * chunk_limit
;
1315 while (Number_Of_Lines
> 65535)
1317 *cp
++ = DST_S_C_SRC_SETREC_L
;
1318 COPY_LONG (cp
, Starting_Line_Number
), cp
+= 4;
1319 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1320 COPY_SHORT (cp
, 65535), cp
+= 2;
1321 Starting_Line_Number
+= 65535;
1322 Number_Of_Lines
-= 65535;
1324 /* Set record number and define lines, normal case. */
1325 if (Starting_Line_Number
<= 65535)
1327 *cp
++ = DST_S_C_SRC_SETREC_W
;
1328 COPY_SHORT (cp
, Starting_Line_Number
), cp
+= 2;
1332 *cp
++ = DST_S_C_SRC_SETREC_L
;
1333 COPY_LONG (cp
, Starting_Line_Number
), cp
+= 4;
1335 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1336 COPY_SHORT (cp
, Number_Of_Lines
), cp
+= 2;
1337 /* Set size now that be know it, then output the data. */
1338 Local
[0] = cp
- &Local
[1];
1339 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1343 /****** Debugger Information support routines ******/
1346 /* This routine locates a file in the list of files. If an entry does
1347 not exist, one is created. For include files, a new entry is always
1348 created such that inline functions can be properly debugged. */
1350 static struct input_file
*
1354 struct input_file
*same_file
= 0;
1355 struct input_file
*fpnt
, *last
= 0;
1358 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1360 if (fpnt
->spnt
== sp
)
1364 sp_name
= S_GET_NAME (sp
);
1365 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1367 if (strcmp (sp_name
, fpnt
->name
) == 0)
1369 if (fpnt
->flag
== 1)
1375 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1381 fpnt
->name
= sp_name
;
1382 fpnt
->min_line
= 0x7fffffff;
1386 fpnt
->file_number
= 0;
1388 fpnt
->same_file_fpnt
= same_file
;
1393 /* This routine converts a number string into an integer, and stops when
1394 it sees an invalid character. The return value is the address of the
1395 character just past the last character read. No error is generated. */
1398 cvt_integer (str
, rtn
)
1402 int ival
= 0, sgn
= 1;
1406 while (*str
>= '0' && *str
<= '9')
1407 ival
= 10 * ival
+ *str
++ - '0';
1414 * The following functions and definitions are used to generate object
1415 * records that will describe program variables to the VMS debugger.
1417 * This file contains many of the routines needed to output debugging info
1418 * into the object file that the VMS debugger needs to understand symbols.
1419 * These routines are called very late in the assembly process, and thus
1420 * we can be fairly lax about changing things, since the GSD and the TIR
1421 * sections have already been output.
1425 /* This routine fixes the names that are generated by C++, ".this" is a good
1426 example. The period does not work for the debugger, since it looks like
1427 the syntax for a structure element, and thus it gets mightily confused.
1429 We also use this to strip the PsectAttribute hack from the name before we
1430 write a debugger record. */
1438 /* Kill any leading "_". */
1442 /* Is there a Psect Attribute to skip?? */
1443 if (HAS_PSECT_ATTRIBUTES (pnt
))
1446 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1449 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1458 /* Here we fix the .this -> $this conversion. */
1459 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1467 /* When defining a structure, this routine is called to find the name of
1468 the actual structure. It is assumed that str points to the equal sign
1469 in the definition, and it moves backward until it finds the start of the
1470 name. If it finds a 0, then it knows that this structure def is in the
1471 outermost level, and thus symbol_name points to the symbol name. */
1474 get_struct_name (str
)
1479 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1482 return (char *) symbol_name
;
1484 while ((*pnt
!= ';') && (*pnt
!= '='))
1488 while ((*pnt
< '0') || (*pnt
> '9'))
1490 while ((*pnt
>= '0') && (*pnt
<= '9'))
1496 /* Search symbol list for type number dbx_type.
1497 Return a pointer to struct. */
1499 static struct VMS_DBG_Symbol
*
1500 find_symbol (dbx_type
)
1503 struct VMS_DBG_Symbol
*spnt
;
1505 spnt
= VMS_Symbol_type_list
[SYMTYP_HASH (dbx_type
)];
1508 if (spnt
->dbx_type
== dbx_type
)
1512 if (!spnt
|| spnt
->advanced
!= ALIAS
)
1514 return find_symbol (spnt
->type2
);
1518 #if 0 /* obsolete */
1519 /* this routine puts info into either Local or Asuffix, depending on the sign
1520 * of size. The reason is that it is easier to build the variable descriptor
1521 * backwards, while the array descriptor is best built forwards. In the end
1522 * they get put together, if there is not a struct/union/enum along the way
1538 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1542 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1545 Apoint
= MAX_DEBUG_RECORD
- 1;
1548 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1559 if (Apoint
+ size
>= MAX_DEBUG_RECORD
)
1562 Apoint
= MAX_DEBUG_RECORD
- 1;
1566 Asuffix
[Apoint
++] = (char) value
;
1569 md_number_to_chars (&Asuffix
[Apoint
], value
, size
);
1585 Local
[Lpnt
--] = (char) value
;
1589 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size
);
1594 /* This routine generates the array descriptor for a given array. */
1597 array_suffix (spnt2
)
1598 struct VMS_DBG_Symbol
*spnt2
;
1600 struct VMS_DBG_Symbol
*spnt
;
1601 struct VMS_DBG_Symbol
*spnt1
;
1607 while (spnt
->advanced
!= ARRAY
)
1609 spnt
= find_symbol (spnt
->type2
);
1615 while (spnt1
->advanced
== ARRAY
)
1618 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1619 spnt1
= find_symbol (spnt1
->type2
);
1621 total_size
= total_size
* spnt1
->data_size
;
1622 fpush (spnt1
->data_size
, 2); /* element size */
1623 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1626 fpush (spnt1
->VMS_type
, 1); /* element type */
1627 fpush (DSC_K_CLASS_A
, 1); /* descriptor class */
1628 fpush (0, 4); /* base address */
1629 fpush (0, 1); /* scale factor -- not applicable */
1630 fpush (0, 1); /* digit count -- not applicable */
1631 fpush (0xc0, 1); /* flags: multiplier block & bounds present */
1632 fpush (rank
, 1); /* number of dimensions */
1633 fpush (total_size
, 4);
1634 fpush (0, 4); /* pointer to element [0][0]...[0] */
1636 while (spnt1
->advanced
== ARRAY
)
1638 fpush (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1639 spnt1
= find_symbol (spnt1
->type2
);
1642 while (spnt1
->advanced
== ARRAY
)
1644 fpush (spnt1
->index_min
, 4);
1645 fpush (spnt1
->index_max
, 4);
1646 spnt1
= find_symbol (spnt1
->type2
);
1651 /* This routine generates the start of a variable descriptor based upon
1652 a struct/union/enum that has yet to be defined. We define this spot as
1653 a new location, and save four bytes for the address. When the struct is
1654 finally defined, then we can go back and plug in the correct address. */
1657 new_forward_ref (dbx_type
)
1660 struct forward_ref
*fpnt
;
1661 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1662 fpnt
->next
= f_ref_root
;
1664 fpnt
->dbx_type
= dbx_type
;
1665 fpnt
->struc_numb
= ++structure_count
;
1666 fpnt
->resolved
= 'N';
1667 rpush (DST_K_TS_IND
, 1); /* indirect type specification */
1669 rpush (total_len
, 2);
1670 struct_number
= -fpnt
->struc_numb
;
1674 /* This routine generates the variable descriptor used to describe non-basic
1675 variables. It calls itself recursively until it gets to the bottom of it
1676 all, and then builds the descriptor backwards. It is easiest to do it
1677 this way since we must periodically write length bytes, and it is easiest
1678 if we know the value when it is time to write it. */
1681 gen1 (spnt
, array_suffix_len
)
1682 struct VMS_DBG_Symbol
*spnt
;
1683 int array_suffix_len
;
1685 struct VMS_DBG_Symbol
*spnt1
;
1688 switch (spnt
->advanced
)
1691 rpush (DBG_S_C_VOID
, 1);
1693 rpush (total_len
, 2);
1697 if (array_suffix_len
== 0)
1699 rpush (spnt
->VMS_type
, 1);
1700 rpush (DBG_S_C_BASIC
, 1);
1702 rpush (total_len
, 2);
1706 rpush (DST_K_VFLAGS_DSC
, 1);
1707 rpush (DST_K_TS_DSC
, 1); /* descriptor type specification */
1713 struct_number
= spnt
->struc_numb
;
1714 if (struct_number
< 0)
1716 new_forward_ref (spnt
->dbx_type
);
1719 rpush (DBG_S_C_STRUCT
, 1);
1721 rpush (total_len
, 2);
1724 spnt1
= find_symbol (spnt
->type2
);
1727 new_forward_ref (spnt
->type2
);
1729 i
= gen1 (spnt1
, 0);
1731 { /* (*void) is a special case, do not put pointer suffix */
1732 rpush (DBG_S_C_POINTER
, 1);
1734 rpush (total_len
, 2);
1739 while (spnt1
->advanced
== ARRAY
)
1741 spnt1
= find_symbol (spnt1
->type2
);
1744 as_tsktsk ("debugger forward reference error, dbx type %d",
1749 /* It is too late to generate forward references, so the user gets a message.
1750 * This should only happen on a compiler error */
1751 (void) gen1 (spnt1
, 1);
1753 array_suffix (spnt
);
1754 array_suffix_len
= Apoint
- i
;
1755 switch (spnt1
->advanced
)
1763 rpush (total_len
, 2);
1764 rpush (DST_K_VFLAGS_DSC
, 1);
1765 rpush (1, 1); /* flags: element value spec included */
1766 rpush (1, 1); /* one dimension */
1767 rpush (DBG_S_C_COMPLEX_ARRAY
, 1);
1769 total_len
+= array_suffix_len
+ 8;
1770 rpush (total_len
, 2);
1772 default: /* lint suppression */
1779 /* This generates a suffix for a variable. If it is not a defined type yet,
1780 then dbx_type contains the type we are expecting so we can generate a
1781 forward reference. This calls gen1 to build most of the descriptor, and
1782 then it puts the icing on at the end. It then dumps whatever is needed
1783 to get a complete descriptor (i.e. struct reference, array suffix). */
1786 generate_suffix (spnt
, dbx_type
)
1787 struct VMS_DBG_Symbol
*spnt
;
1790 static const char pvoid
[6] = {
1791 5, /* record.length == 5 */
1792 DST_K_TYPSPEC
, /* record.type == 1 (type specification) */
1793 0, /* name.length == 0, no name follows */
1794 1, 0, /* type.length == 1 {2 bytes, little endian} */
1795 DBG_S_C_VOID
/* type.type == 5 (pointer to unspecified) */
1800 Lpnt
= MAX_DEBUG_RECORD
- 1;
1805 new_forward_ref (dbx_type
);
1808 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1809 return; /* no suffix needed */
1812 rpush (0, 1); /* no name (len==0) */
1813 rpush (DST_K_TYPSPEC
, 1);
1815 rpush (total_len
, 1);
1816 /* If the variable descriptor overflows the record, output a descriptor
1817 for a pointer to void. */
1818 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1820 as_warn ("Variable descriptor %d too complicated. Defined as `void *'.",
1822 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1826 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1827 Local
[i
++] = Local
[++Lpnt
];
1829 /* we use this for reference to structure that has already been defined */
1830 if (struct_number
> 0)
1832 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1834 VMS_Store_Struct (struct_number
);
1836 /* We use this for a forward reference to a structure that has yet to
1837 be defined. We store four bytes of zero to make room for the actual
1838 address once it is known. */
1839 if (struct_number
< 0)
1841 struct_number
= -struct_number
;
1842 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1844 VMS_Def_Struct (struct_number
);
1845 COPY_LONG (&Local
[Lpnt
], 0L);
1847 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1852 Local
[Lpnt
++] = Asuffix
[i
++];
1854 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1859 /* "novel length" type doesn't work for simple atomic types */
1860 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
1861 #undef SETUP_BASIC_TYPES
1863 /* This routine generates a type description for a bitfield. */
1866 bitfield_suffix (spnt
, width
)
1867 struct VMS_DBG_Symbol
*spnt
;
1870 Local
[Lpnt
++] = 13; /* rec.len==13 */
1871 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* a type specification record */
1872 Local
[Lpnt
++] = 0; /* not named */
1873 COPY_SHORT (&Local
[Lpnt
], 9); /* typ.len==9 */
1875 Local
[Lpnt
++] = DST_K_TS_NOV_LENG
; /* This type is a "novel length"
1876 incarnation of some other type. */
1877 COPY_LONG (&Local
[Lpnt
], width
); /* size in bits == novel length */
1879 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1881 /* assert( spnt->struc_numb > 0 ); */
1882 VMS_Store_Struct (spnt
->struc_numb
); /* output 4 more bytes */
1886 /* Formally define a builtin type, so that it can serve as the target of
1887 an indirect reference. It makes bitfield_suffix() easier by avoiding
1888 the need to use a forward reference for the first occurrence of each
1889 type used in a bitfield. */
1892 setup_basic_type (spnt
)
1893 struct VMS_DBG_Symbol
*spnt
;
1895 #ifdef SETUP_BASIC_TYPES
1896 /* This would be very useful if "novel length" fields actually worked
1897 with basic types like they do with enumerated types. However,
1898 they do not, so this isn't worth doing just so that you can use
1899 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
1901 #ifndef SETUP_SYNONYM_TYPES
1902 /* This determines whether compatible things like `int' and `long int'
1903 ought to have distinct type records rather than sharing one. */
1904 struct VMS_DBG_Symbol
*spnt2
;
1906 /* first check whether this type has already been seen by another name */
1907 for (spnt2
= VMS_Symbol_type_list
[SYMTYP_HASH (spnt
->VMS_type
)];
1909 spnt2
= spnt2
->next
)
1910 if (spnt2
!= spnt
&& spnt2
->VMS_type
== spnt
->VMS_type
)
1912 spnt
->struc_numb
= spnt2
->struc_numb
;
1917 /* `structure number' doesn't really mean `structure'; it means an index
1918 into a linker maintained set of saved locations which can be referenced
1920 spnt
->struc_numb
= ++structure_count
;
1921 VMS_Def_Struct (spnt
->struc_numb
); /* remember where this type lives */
1922 /* define the simple scalar type */
1923 Local
[Lpnt
++] = 6 + strlen (symbol_name
) + 2; /* rec.len */
1924 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* rec.typ==type specification */
1925 Local
[Lpnt
++] = strlen (symbol_name
) + 2;
1926 Local
[Lpnt
++] = '_'; /* prefix name with "__" */
1927 Local
[Lpnt
++] = '_';
1928 for (p
= symbol_name
; *p
; p
++)
1929 Local
[Lpnt
++] = *p
== ' ' ? '_' : *p
;
1930 COPY_SHORT (&Local
[Lpnt
], 2); /* typ.len==2 */
1932 Local
[Lpnt
++] = DST_K_TS_ATOM
; /* typ.kind is simple type */
1933 Local
[Lpnt
++] = spnt
->VMS_type
; /* typ.type */
1934 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
1936 #endif /* SETUP_BASIC_TYPES */
1941 /* This routine generates a symbol definition for a C symbol for the debugger.
1942 It takes a psect and offset for global symbols; if psect < 0, then this is
1943 a local variable and the offset is relative to FP. In this case it can
1944 be either a variable (Offset < 0) or a parameter (Offset > 0). */
1947 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
1948 struct VMS_DBG_Symbol
*spnt
;
1957 /* if there are bad characters in name, convert them */
1958 Name_pnt
= fix_name (Name
);
1960 len
= strlen (Name_pnt
);
1962 { /* this is a local variable, referenced to SP */
1963 Local
[i
++] = 7 + len
;
1964 Local
[i
++] = spnt
->VMS_type
;
1965 Local
[i
++] = (Offset
> 0) ? DBG_C_FUNCTION_PARAM
: DBG_C_LOCAL_SYM
;
1966 COPY_LONG (&Local
[i
], Offset
);
1971 Local
[i
++] = 7 + len
;
1972 Local
[i
++] = spnt
->VMS_type
;
1973 Local
[i
++] = DST_K_VALKIND_ADDR
;
1974 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1976 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
1979 while (*Name_pnt
!= '\0')
1980 Local
[i
++] = *Name_pnt
++;
1981 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
1982 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1983 generate_suffix (spnt
, 0);
1987 /* This routine parses the stabs entries in order to make the definition
1988 for the debugger of local symbols and function parameters. */
1991 VMS_local_stab_Parse (sp
)
1994 struct VMS_DBG_Symbol
*spnt
;
2001 str
= S_GET_NAME (sp
);
2002 pnt
= (char *) strchr (str
, ':');
2004 return; /* no colon present */
2005 pnt1
= pnt
++; /* save this for later, and skip colon */
2007 return; /* ignore static constants */
2009 /* there is one little catch that we must be aware of. Sometimes function
2010 * parameters are optimized into registers, and the compiler, in its infiite
2011 * wisdom outputs stabs records for *both*. In general we want to use the
2012 * register if it is present, so we must search the rest of the symbols for
2013 * this function to see if this parameter is assigned to a register.
2022 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2024 if (!S_IS_DEBUG (sp1
))
2026 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2028 pnt2
= (char *) strchr (S_GET_NAME (sp1
), ':') + 1;
2029 if (*pnt2
== 'F' || *pnt2
== 'f')
2032 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2034 str1
= S_GET_NAME (sp1
); /* and get the name */
2036 while (*pnt2
!= ':')
2043 if (*str1
== ':' && *pnt2
== ':')
2044 return; /* they are the same! lets skip this one */
2046 pnt
++; /* skip p in case no register */
2050 pnt
= cvt_integer (pnt
, &dbx_type
);
2051 spnt
= find_symbol (dbx_type
);
2053 return; /*Dunno what this is*/
2055 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2056 *pnt1
= ':'; /* and restore the string */
2061 /* This routine parses a stabs entry to find the information required
2062 to define a variable. It is used for global and static variables.
2063 Basically we need to know the address of the symbol. With older
2064 versions of the compiler, const symbols are treated differently, in
2065 that if they are global they are written into the text psect. The
2066 global symbol entry for such a const is actually written as a program
2067 entry point (Yuk!!), so if we cannot find a symbol in the list of
2068 psects, we must search the entry points as well. static consts are
2069 even harder, since they are never assigned a memory address. The
2070 compiler passes a stab to tell us the value, but I am not sure what
2074 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2076 int expected_type
; /* char */
2077 int type1
, type2
, Text_Psect
;
2083 struct VMS_DBG_Symbol
*spnt
;
2084 struct VMS_Symbol
*vsp
;
2088 str
= S_GET_NAME (sp
);
2089 pnt
= (char *) strchr (str
, ':');
2091 return; /* no colon present */
2092 pnt1
= pnt
; /* save this for later*/
2094 if (*pnt
== expected_type
)
2096 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2097 spnt
= find_symbol (dbx_type
);
2099 return; /*Dunno what this is*/
2101 * Now we need to search the symbol table to find the psect and
2102 * offset for this variable.
2108 pnt
= S_GET_NAME (vsp
->Symbol
);
2109 if (pnt
&& *pnt
++ == '_'
2110 /* make sure name is the same and symbol type matches */
2111 && strcmp (pnt
, str
) == 0
2112 && (S_GET_RAW_TYPE (vsp
->Symbol
) == type1
2113 || S_GET_RAW_TYPE (vsp
->Symbol
) == type2
))
2119 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2120 *pnt1
= ':'; /* and restore the string */
2123 /* The symbol was not in the symbol list, but it may be an
2124 "entry point" if it was a constant. */
2125 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2128 * Dispatch on STAB type
2130 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2132 pnt
= S_GET_NAME (sp1
);
2135 if (strcmp (pnt
, str
) == 0)
2137 if (!gave_compiler_message
&& expected_type
== 'G')
2139 static const char long_const_msg
[] = "\
2140 ***Warning - the assembly code generated by the compiler has placed \n\
2141 global constant(s) in the text psect. These will not be available to \n\
2142 other modules, since this is not the correct way to handle this. You \n\
2143 have two options: 1) get a patched compiler that does not put global \n\
2144 constants in the text psect, or 2) remove the 'const' keyword from \n\
2145 definitions of global variables in your source module(s). Don't say \n\
2146 I didn't warn you! \n";
2148 as_tsktsk (long_const_msg
);
2149 gave_compiler_message
= 1;
2151 VMS_DBG_record (spnt
,
2156 /* fool assembler to not output this as a routine in the TBT */
2157 pnt1
= S_GET_NAME (sp1
);
2159 S_SET_NAME (sp1
, pnt1
);
2164 *pnt1
= ':'; /* and restore the string */
2169 /* Simpler interfaces into VMS_stab_parse(). */
2172 VMS_GSYM_Parse (sp
, Text_Psect
)
2175 { /* Global variables */
2176 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2180 VMS_LCSYM_Parse (sp
, Text_Psect
)
2183 { /* Static symbols - uninitialized */
2184 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2188 VMS_STSYM_Parse (sp
, Text_Psect
)
2191 { /* Static symbols - initialized */
2192 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2196 /* For register symbols, we must figure out what range of addresses
2197 within the psect are valid. We will use the brackets in the stab
2198 directives to give us guidance as to the PC range that this variable
2199 is in scope. I am still not completely comfortable with this but
2200 as I learn more, I seem to get a better handle on what is going on.
2204 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2205 symbolS
*sp
, *Current_Routine
;
2209 struct VMS_DBG_Symbol
*spnt
;
2217 int Min_Offset
= -1; /* min PC of validity */
2218 int Max_Offset
= 0; /* max PC of validity */
2220 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2223 * Dispatch on STAB type
2225 switch (S_GET_RAW_TYPE (symbolP
))
2229 Min_Offset
= S_GET_VALUE (symbolP
);
2233 Max_Offset
= S_GET_VALUE (symbolP
) - 1;
2236 if ((Min_Offset
!= -1) && (bcnt
== 0))
2238 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2240 pnt
= (char *) strchr (S_GET_NAME (symbolP
), ':') + 1;
2241 if (*pnt
== 'F' || *pnt
== 'f') break;
2245 /* Check to see that the addresses were defined. If not, then there
2246 were no brackets in the function, and we must try to search for
2247 the next function. Since functions can be in any order, we should
2248 search all of the symbol list to find the correct ending address. */
2249 if (Min_Offset
== -1)
2251 int Max_Source_Offset
;
2254 Min_Offset
= S_GET_VALUE (sp
);
2255 Max_Source_Offset
= Min_Offset
; /* just in case no N_SLINEs found */
2256 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2257 switch (S_GET_RAW_TYPE (symbolP
))
2259 case N_TEXT
| N_EXT
:
2260 This_Offset
= S_GET_VALUE (symbolP
);
2261 if (This_Offset
> Min_Offset
&& This_Offset
< Max_Offset
)
2262 Max_Offset
= This_Offset
;
2265 This_Offset
= S_GET_VALUE (symbolP
);
2266 if (This_Offset
> Max_Source_Offset
)
2267 Max_Source_Offset
= This_Offset
;
2270 /* If this is the last routine, then we use the PC of the last source
2271 line as a marker of the max PC for which this reg is valid. */
2272 if (Max_Offset
== 0x7fffffff)
2273 Max_Offset
= Max_Source_Offset
;
2277 str
= S_GET_NAME (sp
);
2278 if ((pnt
= (char *) strchr (str
, ':')) == 0)
2279 return; /* no colon present */
2280 pnt1
= pnt
; /* save this for later*/
2284 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2285 spnt
= find_symbol (dbx_type
);
2287 return; /*Dunno what this is yet*/
2289 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2291 Local
[i
++] = 25 + len
;
2292 Local
[i
++] = spnt
->VMS_type
;
2293 Local
[i
++] = DST_K_VFLAGS_TVS
; /* trailing value specified */
2294 COPY_LONG (&Local
[i
], 1 + len
); /* relative offset, beyond name */
2296 Local
[i
++] = len
; /* name length (ascic prefix) */
2297 while (*pnt
!= '\0')
2298 Local
[i
++] = *pnt
++;
2299 Local
[i
++] = DST_K_VS_FOLLOWS
; /* value specification follows */
2300 COPY_SHORT (&Local
[i
], 15); /* length of rest of record */
2302 Local
[i
++] = DST_K_VS_ALLOC_SPLIT
; /* split lifetime */
2303 Local
[i
++] = 1; /* one binding follows */
2304 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2306 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2307 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2308 Local
[i
++] = DST_K_VALKIND_REG
; /* nested value spec */
2309 COPY_LONG (&Local
[i
], S_GET_VALUE (sp
));
2311 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2313 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2314 generate_suffix (spnt
, 0);
2318 /* This function examines a structure definition, checking all of the elements
2319 to make sure that all of them are fully defined. The only thing that we
2320 kick out are arrays of undefined structs, since we do not know how big
2321 they are. All others we can handle with a normal forward reference. */
2324 forward_reference (pnt
)
2327 struct VMS_DBG_Symbol
*spnt
, *spnt1
;
2330 pnt
= cvt_integer (pnt
+ 1, &i
);
2332 return 0; /* no forward references */
2335 pnt
= (char *) strchr (pnt
, ':');
2336 pnt
= cvt_integer (pnt
+ 1, &i
);
2337 spnt
= find_symbol (i
);
2338 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2340 spnt1
= find_symbol (spnt
->type2
);
2341 if (spnt
->advanced
== ARRAY
&& !spnt1
)
2345 pnt
= cvt_integer (pnt
+ 1, &i
);
2346 pnt
= cvt_integer (pnt
+ 1, &i
);
2347 } while (*++pnt
!= ';');
2348 return 0; /* no forward refences found */
2352 /* Used to check a single element of a structure on the final pass. */
2355 final_forward_reference (spnt
)
2356 struct VMS_DBG_Symbol
*spnt
;
2358 struct VMS_DBG_Symbol
*spnt1
;
2360 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2362 spnt1
= find_symbol (spnt
->type2
);
2363 if (spnt
->advanced
== ARRAY
&& !spnt1
)
2367 return 0; /* no forward refences found */
2371 /* This routine parses the stabs directives to find any definitions of dbx
2372 type numbers. It makes a note of all of them, creating a structure
2373 element of VMS_DBG_Symbol that describes it. This also generates the
2374 info for the debugger that describes the struct/union/enum, so that
2375 further references to these data types will be by number
2377 We have to process pointers right away, since there can be references
2378 to them later in the same stabs directive. We cannot have forward
2379 references to pointers, (but we can have a forward reference to a
2380 pointer to a structure/enum/union) and this is why we process them
2381 immediately. After we process the pointer, then we search for defs
2382 that are nested even deeper.
2384 8/15/92: We have to process arrays right away too, because there can
2385 be multiple references to identical array types in one structure
2386 definition, and only the first one has the definition. */
2389 VMS_typedef_parse (str
)
2397 struct forward_ref
*fpnt
;
2398 int i1
, i2
, i3
, len
;
2399 struct VMS_DBG_Symbol
*spnt
;
2400 struct VMS_DBG_Symbol
*spnt1
;
2402 /* check for any nested def's */
2403 pnt
= (char *) strchr (str
+ 1, '=');
2404 if (pnt
&& str
[1] != '*' && (str
[1] != 'a' || str
[2] != 'r')
2405 && VMS_typedef_parse (pnt
) == 1)
2407 /* now find dbx_type of entry */
2410 { /* check for static constants */
2411 *str
= '\0'; /* for now we ignore them */
2414 while ((*pnt
<= '9') && (*pnt
>= '0'))
2416 pnt
++; /* and get back to the number */
2417 cvt_integer (pnt
, &i1
);
2418 spnt
= find_symbol (i1
);
2419 /* first see if this has been defined already, due to forward reference */
2422 i2
= SYMTYP_HASH (i1
);
2423 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2424 spnt
->next
= VMS_Symbol_type_list
[i2
];
2425 VMS_Symbol_type_list
[i2
] = spnt
;
2426 spnt
->dbx_type
= i1
; /* and save the type */
2427 spnt
->type2
= spnt
->VMS_type
= spnt
->data_size
= 0;
2428 spnt
->index_min
= spnt
->index_max
= spnt
->struc_numb
= 0;
2431 * For structs and unions, do a partial parse, otherwise we sometimes get
2432 * circular definitions that are impossible to resolve. We read enough
2433 * info so that any reference to this type has enough info to be resolved.
2435 pnt
= str
+ 1; /* point to character past equal sign */
2436 if (*pnt
>= '0' && *pnt
<= '9')
2438 if (type_check ("void"))
2439 { /* this is the void symbol */
2441 spnt
->advanced
= VOID
;
2444 if (type_check ("unknown type"))
2447 spnt
->advanced
= UNKNOWN
;
2450 pnt1
= cvt_integer (pnt
, &i1
);
2451 if (i1
!= spnt
->dbx_type
)
2453 spnt
->advanced
= ALIAS
;
2458 as_tsktsk ("debugginer output: %d is an unknown untyped variable.",
2460 return 1; /* do not know what this is */
2463 pnt
= str
+ 1; /* point to character past equal sign */
2467 spnt
->advanced
= BASIC
;
2468 if (type_check ("int"))
2470 spnt
->VMS_type
= DBG_S_C_SLINT
;
2471 spnt
->data_size
= 4;
2473 else if (type_check ("long int"))
2475 spnt
->VMS_type
= DBG_S_C_SLINT
;
2476 spnt
->data_size
= 4;
2478 else if (type_check ("unsigned int"))
2480 spnt
->VMS_type
= DBG_S_C_ULINT
;
2481 spnt
->data_size
= 4;
2483 else if (type_check ("long unsigned int"))
2485 spnt
->VMS_type
= DBG_S_C_ULINT
;
2486 spnt
->data_size
= 4;
2488 else if (type_check ("short int"))
2490 spnt
->VMS_type
= DBG_S_C_SSINT
;
2491 spnt
->data_size
= 2;
2493 else if (type_check ("short unsigned int"))
2495 spnt
->VMS_type
= DBG_S_C_USINT
;
2496 spnt
->data_size
= 2;
2498 else if (type_check ("char"))
2500 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2501 spnt
->data_size
= 1;
2503 else if (type_check ("signed char"))
2505 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2506 spnt
->data_size
= 1;
2508 else if (type_check ("unsigned char"))
2510 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2511 spnt
->data_size
= 1;
2513 else if (type_check ("float"))
2515 spnt
->VMS_type
= DBG_S_C_REAL4
;
2516 spnt
->data_size
= 4;
2518 else if (type_check ("double"))
2520 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2521 spnt
->data_size
= 8;
2523 else if (type_check ("long double"))
2525 /* same as double, at least for now */
2526 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2527 spnt
->data_size
= 8;
2529 else if (type_check ("long long int"))
2531 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2532 spnt
->data_size
= 8;
2534 else if (type_check ("long long unsigned int"))
2536 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2537 spnt
->data_size
= 8;
2539 else if (type_check ("complex float"))
2541 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2542 spnt
->data_size
= 2 * 4;
2544 else if (type_check ("complex double"))
2546 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2547 spnt
->data_size
= 2 * 8;
2549 else if (type_check ("complex long double"))
2551 /* same as complex double, at least for now */
2552 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2553 spnt
->data_size
= 2 * 8;
2558 * Shouldn't get here, but if we do, something
2559 * more substantial ought to be done...
2562 spnt
->data_size
= 0;
2564 if (spnt
->VMS_type
!= 0)
2565 setup_basic_type (spnt
);
2566 pnt1
= (char *) strchr (str
, ';') + 1;
2570 spnt
->advanced
= (*pnt
== 's') ? STRUCT
: UNION
;
2571 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2572 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2573 if (!final_pass
&& forward_reference (pnt
))
2575 spnt
->struc_numb
= -1;
2578 spnt
->struc_numb
= ++structure_count
;
2580 pnt
= get_struct_name (str
);
2581 VMS_Def_Struct (spnt
->struc_numb
);
2583 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2584 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2586 fpnt
->resolved
= 'Y';
2587 VMS_Set_Struct (fpnt
->struc_numb
);
2588 VMS_Store_Struct (spnt
->struc_numb
);
2592 VMS_Set_Struct (spnt
->struc_numb
);
2594 Local
[i
++] = 11 + strlen (pnt
);
2595 Local
[i
++] = DBG_S_C_STRUCT_START
;
2596 Local
[i
++] = DST_K_VFLAGS_NOVAL
; /* structure definition only */
2597 COPY_LONG (&Local
[i
], 0L); /* hence value is unused */
2599 Local
[i
++] = strlen (pnt
);
2601 while (*pnt2
!= '\0')
2602 Local
[i
++] = *pnt2
++;
2603 i2
= spnt
->data_size
* 8; /* number of bits */
2604 COPY_LONG (&Local
[i
], i2
);
2606 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2608 if (pnt
!= symbol_name
)
2610 pnt
+= strlen (pnt
);
2612 } /* replace colon for later */
2613 while (*++pnt1
!= ';')
2615 pnt
= (char *) strchr (pnt1
, ':');
2618 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2619 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2620 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2621 spnt1
= find_symbol (dtype
);
2622 len
= strlen (pnt2
);
2623 if (spnt1
&& (spnt1
->advanced
== BASIC
|| spnt1
->advanced
== ENUM
)
2624 && ((i3
!= spnt1
->data_size
* 8) || (i2
% 8 != 0)))
2626 if (USE_BITSTRING_DESCRIPTOR (spnt1
))
2628 /* This uses a type descriptor, which doesn't work if
2629 the enclosing structure has been placed in a register.
2630 Also, enum bitfields degenerate to simple integers. */
2631 int unsigned_type
= (spnt1
->VMS_type
== DBG_S_C_ULINT
2632 || spnt1
->VMS_type
== DBG_S_C_USINT
2633 || spnt1
->VMS_type
== DBG_S_C_UCHAR
2634 || spnt1
->VMS_type
== DBG_S_C_UQUAD
2635 || spnt1
->advanced
== ENUM
); /* (approximate) */
2637 fpush (19 + len
, 1);
2638 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2639 fpush (DST_K_VFLAGS_DSC
, 1); /* specified by descriptor */
2640 fpush (1 + len
, 4); /* relative offset to descriptor */
2641 fpush (len
, 1); /* length byte (ascic prefix) */
2642 while (*pnt2
!= '\0') /* name bytes */
2644 fpush (i3
, 2); /* dsc length == size of bitfield */
2645 /* dsc type == un?signed bitfield */
2646 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2647 fpush (DSC_K_CLASS_UBS
, 1); /* dsc class == unaligned bitstring */
2648 fpush (0x00, 4); /* dsc pointer == zeroes */
2649 fpush (i2
, 4); /* start position */
2650 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2655 /* Use a "novel length" type specification, which works
2656 right for register structures and for enum bitfields
2657 but results in larger object modules. */
2658 Local
[i
++] = 7 + len
;
2659 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
; /* type spec follows */
2660 Local
[i
++] = DBG_S_C_STRUCT_ITEM
; /* value is a bit offset */
2661 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2663 Local
[i
++] = strlen (pnt2
);
2664 while (*pnt2
!= '\0')
2665 Local
[i
++] = *pnt2
++;
2666 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2668 bitfield_suffix (spnt1
, i3
);
2672 { /* not a bitfield */
2673 /* check if this is a forward reference */
2674 if (final_pass
&& final_forward_reference (spnt1
))
2676 as_tsktsk ("debugger output: structure element `%s' has undefined type",
2680 Local
[i
++] = 7 + len
;
2681 Local
[i
++] = spnt1
? spnt1
->VMS_type
: DBG_S_C_ADVANCED_TYPE
;
2682 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2683 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2685 Local
[i
++] = strlen (pnt2
);
2686 while (*pnt2
!= '\0')
2687 Local
[i
++] = *pnt2
++;
2688 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2691 generate_suffix (spnt1
, dtype
);
2692 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2693 generate_suffix (spnt1
, 0);
2697 Local
[i
++] = 0x01; /* length byte */
2698 Local
[i
++] = DBG_S_C_STRUCT_END
;
2699 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2703 spnt
->advanced
= ENUM
;
2704 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2705 spnt
->struc_numb
= ++structure_count
;
2706 spnt
->data_size
= 4;
2707 VMS_Def_Struct (spnt
->struc_numb
);
2709 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2710 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2712 fpnt
->resolved
= 'Y';
2713 VMS_Set_Struct (fpnt
->struc_numb
);
2714 VMS_Store_Struct (spnt
->struc_numb
);
2718 VMS_Set_Struct (spnt
->struc_numb
);
2720 len
= strlen (symbol_name
);
2721 Local
[i
++] = 3 + len
;
2722 Local
[i
++] = DBG_S_C_ENUM_START
;
2723 Local
[i
++] = 4 * 8; /* enum values are 32 bits */
2726 while (*pnt2
!= '\0')
2727 Local
[i
++] = *pnt2
++;
2728 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2730 while (*++pnt
!= ';')
2732 pnt1
= (char *) strchr (pnt
, ':');
2734 pnt1
= cvt_integer (pnt1
, &i1
);
2736 Local
[i
++] = 7 + len
;
2737 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2738 Local
[i
++] = DST_K_VALKIND_LITERAL
;
2739 COPY_LONG (&Local
[i
], i1
);
2743 while (*pnt
!= '\0')
2744 Local
[i
++] = *pnt
++;
2745 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2747 pnt
= pnt1
; /* Skip final semicolon */
2749 Local
[i
++] = 0x01; /* len byte */
2750 Local
[i
++] = DBG_S_C_ENUM_END
;
2751 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2756 spnt
->advanced
= ARRAY
;
2757 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2758 pnt
= (char *) strchr (pnt
, ';');
2761 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2762 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2763 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2764 pnt
= (char *) strchr (str
+ 1, '=');
2765 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2769 spnt
->advanced
= FUNCTION
;
2770 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2771 /* this masquerades as a basic type*/
2772 spnt
->data_size
= 4;
2773 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2776 spnt
->advanced
= POINTER
;
2777 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2778 spnt
->data_size
= 4;
2779 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2780 pnt
= (char *) strchr (str
+ 1, '=');
2781 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2785 spnt
->advanced
= UNKNOWN
;
2787 as_tsktsk ("debugger output: %d is an unknown type of variable.",
2789 return 1; /* unable to decipher */
2791 /* This removes the evidence of the definition so that the outer levels
2792 of parsing do not have to worry about it. */
2794 while (*pnt1
!= '\0')
2801 /* This is the root routine that parses the stabs entries for definitions.
2802 it calls VMS_typedef_parse, which can in turn call itself. We need to
2803 be careful, since sometimes there are forward references to other symbol
2804 types, and these cannot be resolved until we have completed the parse.
2806 Also check and see if we are using continuation stabs, if we are, then
2807 paste together the entire contents of the stab before we pass it to
2808 VMS_typedef_parse. */
2817 char *parse_buffer
= 0;
2819 int incomplete
, pass
, incom1
;
2820 struct forward_ref
*fpnt
;
2828 incom1
= incomplete
;
2830 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
2833 * Deal with STAB symbols
2835 if (S_IS_DEBUG (sp
))
2838 * Dispatch on STAB type
2840 switch (S_GET_RAW_TYPE (sp
))
2848 case N_FUN
: /*sometimes these contain typedefs*/
2849 str
= S_GET_NAME (sp
);
2851 pnt
= str
+ strlen (str
) - 1;
2852 if (*pnt
== '?') /* Continuation stab. */
2859 tlen
+= strlen (str
) - 1;
2860 spnext
= symbol_next (spnext
);
2861 str
= S_GET_NAME (spnext
);
2862 pnt
= str
+ strlen (str
) - 1;
2863 } while (*pnt
== '?');
2864 tlen
+= strlen (str
);
2865 parse_buffer
= (char *) xmalloc (tlen
+ 1);
2866 strcpy (parse_buffer
, S_GET_NAME (sp
));
2867 pnt2
= parse_buffer
+ strlen (parse_buffer
) - 1;
2871 spnext
= symbol_next (spnext
);
2872 str
= S_GET_NAME (spnext
);
2874 pnt2
+= strlen (str
) - 1;
2875 *str
= '\0'; /* Erase this string */
2876 /* S_SET_NAME (spnext, str); */
2877 if (*pnt2
!= '?') break;
2883 if ((pnt
= (char *) strchr (str
, ':')) != 0)
2887 if ((pnt2
= (char *) strchr (pnt1
, '=')) != 0)
2888 incomplete
+= VMS_typedef_parse (pnt2
);
2891 /* At this point the parse buffer should just
2892 contain name:nn. If it does not, then we
2893 are in real trouble. Anyway, this is always
2894 shorter than the original line. */
2895 pnt2
= S_GET_NAME (sp
);
2896 strcpy (pnt2
, parse_buffer
);
2897 /* S_SET_NAME (sp, pnt2); */
2898 free (parse_buffer
), parse_buffer
= 0;
2900 *pnt
= ':'; /* put back colon to restore dbx_type */
2908 * Make one last pass, if needed, and define whatever we can
2911 if (final_pass
== 0 && incomplete
== incom1
)
2914 incom1
++; /* Force one last pass through */
2916 } while (incomplete
!= 0 && incomplete
!= incom1
);
2917 /* repeat until all refs resolved if possible */
2918 /* if (pass > 1) printf (" Required %d passes\n", pass); */
2919 if (incomplete
!= 0)
2921 as_tsktsk ("debugger output: Unable to resolve %d circular references.",
2928 if (fpnt
->resolved
!= 'Y')
2930 if (find_symbol (fpnt
->dbx_type
))
2932 as_tsktsk ("debugger forward reference error, dbx type %d",
2937 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
2938 pnt2
= (char *) strchr (&fixit
[1], '=');
2939 VMS_typedef_parse (pnt2
);
2947 Define_Local_Symbols (s0P
, s2P
, Current_Routine
, Text_Psect
)
2949 symbolS
*Current_Routine
;
2952 symbolS
*s1P
; /* each symbol from s0P .. s2P (exclusive) */
2954 for (s1P
= symbol_next (s0P
); s1P
!= s2P
; s1P
= symbol_next (s1P
))
2957 break; /* and return */
2958 if (S_GET_RAW_TYPE (s1P
) == N_FUN
)
2960 char *pnt
= (char *) strchr (S_GET_NAME (s1P
), ':') + 1;
2961 if (*pnt
== 'F' || *pnt
== 'f') break;
2963 if (!S_IS_DEBUG (s1P
))
2966 * Dispatch on STAB type
2968 switch (S_GET_RAW_TYPE (s1P
))
2971 continue; /* not left or right brace */
2975 VMS_local_stab_Parse (s1P
);
2979 VMS_RSYM_Parse (s1P
, Current_Routine
, Text_Psect
);
2986 /* This function crawls the symbol chain searching for local symbols that
2987 need to be described to the debugger. When we enter a new scope with
2988 a "{", it creates a new "block", which helps the debugger keep track
2989 of which scope we are currently in. */
2992 Define_Routine (s0P
, Level
, Current_Routine
, Text_Psect
)
2995 symbolS
*Current_Routine
;
3002 for (s1P
= symbol_next (s0P
); s1P
!= 0; s1P
= symbol_next (s1P
))
3004 if (S_GET_RAW_TYPE (s1P
) == N_FUN
)
3006 char *pnt
= (char *) strchr (S_GET_NAME (s1P
), ':') + 1;
3007 if (*pnt
== 'F' || *pnt
== 'f') break;
3009 if (!S_IS_DEBUG (s1P
))
3012 * Dispatch on STAB type
3014 switch (S_GET_RAW_TYPE (s1P
))
3017 continue; /* not left or right brace */
3023 sprintf (str
, "$%d", rcount
++);
3024 VMS_TBT_Block_Begin (s1P
, Text_Psect
, str
);
3026 Offset
= S_GET_VALUE (s1P
); /* side-effect: fully resolve symbol */
3027 Define_Local_Symbols (s0P
, s1P
, Current_Routine
, Text_Psect
);
3028 s1P
= Define_Routine (s1P
, Level
+ 1, Current_Routine
, Text_Psect
);
3030 VMS_TBT_Block_End (S_GET_VALUE (s1P
) - Offset
);
3039 /* We end up here if there were no brackets in this function.
3040 Define everything. */
3041 Define_Local_Symbols (s0P
, (symbolS
*)0, Current_Routine
, Text_Psect
);
3047 #include <sys/types.h>
3049 static void get_VMS_time_on_unix
PARAMS ((char *));
3051 /* Manufacture a VMS-like time string on a Unix based system. */
3053 get_VMS_time_on_unix (Now
)
3060 pnt
= ctime (&timeb
);
3066 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3068 #endif /* not VMS */
3071 /* Write the MHD (Module Header) records. */
3074 Write_VMS_MHD_Records ()
3076 register const char *cp
;
3080 struct { unsigned short len
, mbz
; char *ptr
; } Descriptor
;
3084 /* We are writing a module header record. */
3085 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3087 * ***************************
3088 * *MAIN MODULE HEADER RECORD*
3089 * ***************************
3091 /* Store record type and header type. */
3092 PUT_CHAR (OBJ_S_C_HDR
);
3093 PUT_CHAR (MHD_S_C_MHD
);
3094 /* Structure level is 0. */
3095 PUT_CHAR (OBJ_S_C_STRLVL
);
3096 /* Maximum record size is size of the object record buffer. */
3097 PUT_SHORT (sizeof (Object_Record_Buffer
));
3100 * FIXME: module name and version should be user
3101 * specifiable via `.ident' and/or `#pragma ident'.
3104 /* Get module name (the FILENAME part of the object file). */
3109 if (*cp
== ']' || *cp
== '>' || *cp
== ':' || *cp
== '/')
3115 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3119 /* Limit it to 31 characters and store in the object record. */
3120 while (--cp1
>= Module_Name
)
3123 if (strlen (Module_Name
) > 31)
3125 if (flag_hash_long_names
)
3126 as_tsktsk ("Module name truncated: %s\n", Module_Name
);
3127 Module_Name
[31] = '\0';
3129 PUT_COUNTED_STRING (Module_Name
);
3130 /* Module Version is "V1.0". */
3131 PUT_COUNTED_STRING ("V1.0");
3132 /* Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm". */
3134 get_VMS_time_on_unix (Now
);
3136 Descriptor
.len
= sizeof Now
- 1;
3137 Descriptor
.mbz
= 0; /* type & class unspecified */
3138 Descriptor
.ptr
= Now
;
3139 (void) sys$
asctim ((unsigned short *)0, &Descriptor
, (long *)0, 0);
3141 for (i
= 0; i
< 17; i
++)
3143 /* Patch time is "never" (17 zeros). */
3144 for (i
= 0; i
< 17; i
++)
3146 /* Force this to be a separate output record. */
3147 Flush_VMS_Object_Record_Buffer ();
3150 * *************************
3151 * *LANGUAGE PROCESSOR NAME*
3152 * *************************
3154 /* Store record type and header type. */
3155 PUT_CHAR (OBJ_S_C_HDR
);
3156 PUT_CHAR (MHD_S_C_LNM
);
3158 * Store language processor name and version (not a counted string!).
3160 * This is normally supplied by the gcc driver for the command line
3161 * which invokes gas. If absent, we fall back to gas's version.
3163 cp
= compiler_version_string
;
3173 /* Force this to be a separate output record. */
3174 Flush_VMS_Object_Record_Buffer ();
3178 /* Write the EOM (End Of Module) record. */
3181 Write_VMS_EOM_Record (Psect
, Offset
)
3186 * We are writing an end-of-module record
3187 * (this assumes that the entry point will always be in a psect
3188 * represented by a single byte, which is the case for code in
3191 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3192 PUT_CHAR (OBJ_S_C_EOM
); /* Record type. */
3193 PUT_CHAR (0); /* Error severity level (we ignore it). */
3195 * Store the entry point, if it exists
3202 /* Flush the record; this will be our final output. */
3203 Flush_VMS_Object_Record_Buffer ();
3207 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3213 register const unsigned char *p
= (unsigned char *) ptr
;
3214 register const unsigned char *end
= p
+ strlen (ptr
);
3215 register unsigned char c
;
3216 register int hash
= 0;
3221 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3227 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3230 VMS_Case_Hack_Symbol (In
, Out
)
3231 register const char *In
;
3238 const char *old_name
;
3240 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3242 int Case_Hack_Bits
= 0;
3244 static char Hex_Table
[16] =
3245 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3248 * Kill any leading "_"
3250 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3253 new_name
= Out
; /* save this for later*/
3255 #if barfoo /* Dead code */
3256 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3260 /* We may need to truncate the symbol, save the hash for later*/
3261 result
= (strlen (In
) > 23) ? hash_string (In
) : 0;
3263 * Is there a Psect Attribute to skip??
3265 if (HAS_PSECT_ATTRIBUTES (In
))
3270 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3273 if ((In
[0] == '$') && (In
[1] == '$'))
3283 /* if (strlen (In) > 31 && flag_hash_long_names)
3284 as_tsktsk ("Symbol name truncated: %s\n", In); */
3286 * Do the case conversion
3288 i
= 23; /* Maximum of 23 chars */
3289 while (*In
&& (--i
>= 0))
3291 Case_Hack_Bits
<<= 1;
3294 if ((destructor
== 1) && (i
== 21))
3296 switch (vms_name_mapping
)
3299 if (isupper (*In
)) {
3301 Case_Hack_Bits
|= 1;
3303 *Out
++ = islower (*In
) ? toupper (*In
++) : *In
++;
3306 case 3: *Out
++ = *In
++;
3309 if (islower (*In
)) {
3312 *Out
++ = isupper (*In
) ? tolower (*In
++) : *In
++;
3318 * If we saw a dollar sign, we don't do case hacking
3320 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3324 * If we have more than 23 characters and everything is lowercase
3325 * we can insert the full 31 characters
3330 * We have more than 23 characters
3331 * If we must add the case hack, then we have truncated the str
3335 if (Case_Hack_Bits
== 0)
3338 * And so far they are all lower case:
3339 * Check up to 8 more characters
3340 * and ensure that they are lowercase
3342 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3343 if (isupper (In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3349 if ((i
== 8) || (In
[i
] == 0))
3352 * They are: Copy up to 31 characters
3353 * to the output string
3356 while ((--i
>= 0) && (*In
))
3357 switch (vms_name_mapping
){
3358 case 0: *Out
++ = islower (*In
) ? toupper (*In
++) : *In
++;
3360 case 3: *Out
++ = *In
++;
3362 case 2: *Out
++ = isupper (*In
) ? tolower (*In
++) : *In
++;
3369 * If there were any uppercase characters in the name we
3370 * take on the case hacking string
3373 /* Old behavior for regular GNU-C compiler */
3374 if (!flag_hash_long_names
)
3376 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3381 for (i
= 0; i
< 6; i
++)
3383 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3384 Case_Hack_Bits
>>= 4;
3390 Out
= pnt
; /*Cut back to 23 characters maximum */
3392 for (i
= 0; i
< 7; i
++)
3394 init
= result
& 0x01f;
3395 *Out
++ = (init
< 10) ? ('0' + init
) : ('A' + init
- 10);
3396 result
= result
>> 5;
3404 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3405 as_tsktsk ("Symbol %s replaced by %s\n", old_name
, new_name
);
3410 * Scan a symbol name for a psect attribute specification
3412 #define GLOBALSYMBOL_BIT 0x10000
3413 #define GLOBALVALUE_BIT 0x20000
3417 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3419 int *Attribute_Pointer
;
3422 register const char *cp
;
3430 {"PIC", GPS_S_M_PIC
},
3431 {"LIB", GPS_S_M_LIB
},
3432 {"OVR", GPS_S_M_OVR
},
3433 {"REL", GPS_S_M_REL
},
3434 {"GBL", GPS_S_M_GBL
},
3435 {"SHR", GPS_S_M_SHR
},
3436 {"EXE", GPS_S_M_EXE
},
3438 {"WRT", GPS_S_M_WRT
},
3439 {"VEC", GPS_S_M_VEC
},
3440 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3441 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3451 * Check for a PSECT attribute list
3453 if (!HAS_PSECT_ATTRIBUTES (Name
))
3454 return; /* If not, return */
3456 * Skip the attribute list indicator
3458 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3460 * Process the attributes ("_" separated, "$" terminated)
3462 while (*Name
!= '$')
3465 * Assume not negating
3471 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3474 * We are negating (and skip the NO)
3480 * Find the token delimiter
3483 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3486 * Look for the token in the attribute list
3488 for (i
= 0; Attributes
[i
].Name
; i
++)
3491 * If the strings match, set/clear the attr.
3493 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3499 *Attribute_Pointer
&=
3500 ~Attributes
[i
].Value
;
3502 *Attribute_Pointer
|=
3503 Attributes
[i
].Value
;
3511 * Now skip the attribute
3520 #define GBLSYM_REF 0
3521 #define GBLSYM_DEF 1
3522 #define GBLSYM_VAL 2
3523 #define GBLSYM_LCL 4 /* not GBL after all... */
3526 * Define a global symbol (or possibly a local one).
3529 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Flags
)
3538 * We are writing a GSD record
3540 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3542 * If the buffer is empty we must insert the GSD record type
3544 if (Object_Record_Offset
== 0)
3545 PUT_CHAR (OBJ_S_C_GSD
);
3547 * We are writing a Global (or local) symbol definition subrecord.
3549 PUT_CHAR ((Flags
& GBLSYM_LCL
) != 0 ? GSD_S_C_LSY
:
3550 ((unsigned) Psect_Number
<= 255) ? GSD_S_C_SYM
: GSD_S_C_SYMW
);
3552 * Data type is undefined
3556 * Switch on Definition/Reference
3558 if ((Flags
& GBLSYM_DEF
) == 0)
3563 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ? GSY_S_M_REL
: 0);
3564 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3565 PUT_SHORT (Current_Environment
);
3571 *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
3573 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ?
3574 GSY_S_M_DEF
| GSY_S_M_REL
: GSY_S_M_DEF
);
3575 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3576 PUT_SHORT (Current_Environment
);
3580 if ((Flags
& GBLSYM_LCL
) == 0 && (unsigned) Psect_Number
<= 255)
3581 PUT_CHAR (Psect_Number
);
3583 PUT_SHORT (Psect_Number
);
3587 PUT_LONG (Psect_Offset
);
3590 * Finally, the global symbol name
3592 VMS_Case_Hack_Symbol (Name
, Local
);
3593 PUT_COUNTED_STRING (Local
);
3595 * Flush the buffer if it is more than 75% full
3597 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3598 Flush_VMS_Object_Record_Buffer ();
3602 * Define an environment to support local symbol references.
3603 * This is just to mollify the linker; we don't actually do
3604 * anything useful with it.
3607 VMS_Local_Environment_Setup (Env_Name
)
3608 const char *Env_Name
;
3610 /* We are writing a GSD record. */
3611 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3612 /* If the buffer is empty we must insert the GSD record type. */
3613 if (Object_Record_Offset
== 0)
3614 PUT_CHAR (OBJ_S_C_GSD
);
3615 /* We are writing an ENV subrecord. */
3616 PUT_CHAR (GSD_S_C_ENV
);
3618 ++Current_Environment
; /* index of environment being defined */
3620 /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
3621 PUT_SHORT (ENV_S_M_DEF
);
3622 /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
3625 /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
3626 if (!Env_Name
) Env_Name
= "";
3627 PUT_COUNTED_STRING ((char *)Env_Name
);
3629 /* Flush the buffer if it is more than 75% full. */
3630 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3631 Flush_VMS_Object_Record_Buffer ();
3639 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3643 struct VMS_Symbol
*vsp
;
3646 int Psect_Attributes
;
3649 * Generate the appropriate PSECT flags given the PSECT type
3654 /* Text psects are PIC,noOVR,REL,noGBL,SHR,EXE,RD,noWRT. */
3655 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_REL
|GPS_S_M_SHR
|GPS_S_M_EXE
3659 /* Data psects are PIC,noOVR,REL,noGBL,noSHR,noEXE,RD,WRT. */
3660 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_REL
|GPS_S_M_RD
|GPS_S_M_WRT
);
3663 /* Common block psects are: PIC,OVR,REL,GBL,SHR,noEXE,RD,WRT. */
3664 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_OVR
|GPS_S_M_REL
|GPS_S_M_GBL
3665 |GPS_S_M_SHR
|GPS_S_M_RD
|GPS_S_M_WRT
);
3668 /* Const data psects are: PIC,OVR,REL,GBL,SHR,noEXE,RD,noWRT. */
3669 Psect_Attributes
= (GPS_S_M_PIC
|GPS_S_M_OVR
|GPS_S_M_REL
|GPS_S_M_GBL
3670 |GPS_S_M_SHR
|GPS_S_M_RD
);
3674 error ("Unknown VMS psect type (%ld)", (long) Type
);
3678 * Modify the psect attributes according to any attribute string
3680 if (vsp
&& S_GET_TYPE (vsp
->Symbol
) == N_ABS
)
3681 Psect_Attributes
|= GLOBALVALUE_BIT
;
3682 else if (HAS_PSECT_ATTRIBUTES (Name
))
3683 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3685 * Check for globalref/def/val.
3687 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3690 * globalvalue symbols were generated before. This code
3691 * prevents unsightly psect buildup, and makes sure that
3692 * fixup references are emitted correctly.
3694 vsp
->Psect_Index
= -1; /* to catch errors */
3695 S_SET_TYPE (vsp
->Symbol
, N_UNDF
); /* make refs work */
3696 return 1; /* decrement psect counter */
3699 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3701 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3703 case N_UNDF
| N_EXT
:
3704 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3705 vsp
->Psect_Offset
, GBLSYM_REF
);
3706 vsp
->Psect_Index
= -1;
3707 S_SET_TYPE (vsp
->Symbol
, N_UNDF
);
3708 return 1; /* return and indicate no psect */
3709 case N_DATA
| N_EXT
:
3710 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3711 vsp
->Psect_Offset
, GBLSYM_DEF
);
3712 /* In this case we still generate the psect */
3715 as_fatal ("Globalsymbol attribute for symbol %s was unexpected.",
3721 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3723 * We are writing a GSD record
3725 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3727 * If the buffer is empty we must insert the GSD record type
3729 if (Object_Record_Offset
== 0)
3730 PUT_CHAR (OBJ_S_C_GSD
);
3732 * We are writing a PSECT definition subrecord
3734 PUT_CHAR (GSD_S_C_PSC
);
3736 * Psects are always LONGWORD aligned
3740 * Specify the psect attributes
3742 PUT_SHORT (Psect_Attributes
);
3744 * Specify the allocation
3748 * Finally, the psect name
3750 VMS_Case_Hack_Symbol (Name
, Local
);
3751 PUT_COUNTED_STRING (Local
);
3753 * Flush the buffer if it is more than 75% full
3755 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3756 Flush_VMS_Object_Record_Buffer ();
3761 /* Given the pointer to a symbol we calculate how big the data at the
3762 symbol is. We do this by looking for the next symbol (local or global)
3763 which will indicate the start of another datum. */
3766 VMS_Initialized_Data_Size (s0P
, End_Of_Data
)
3767 register symbolS
*s0P
;
3768 unsigned End_Of_Data
;
3771 valueT s0P_val
= S_GET_VALUE (s0P
), s1P_val
,
3772 nearest_val
= (valueT
) End_Of_Data
;
3774 /* Find the nearest symbol what follows this one. */
3775 for (s1P
= symbol_rootP
; s1P
; s1P
= symbol_next (s1P
))
3777 /* The data type must match. */
3778 if (S_GET_TYPE (s1P
) != N_DATA
)
3780 s1P_val
= S_GET_VALUE (s1P
);
3781 if (s1P_val
> s0P_val
&& s1P_val
< nearest_val
)
3782 nearest_val
= s1P_val
;
3784 /* Calculate its size. */
3785 return (offsetT
) (nearest_val
- s0P_val
);
3789 /* Check symbol names for the Psect hack with a globalvalue, and then
3790 generate globalvalues for those that have it. */
3793 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
3798 register symbolS
*sp
;
3799 char *stripped_name
, *Name
;
3801 int Psect_Attributes
;
3806 * Scan the symbol table for globalvalues, and emit def/ref when
3807 * required. These will be caught again later and converted to
3810 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
3812 typ
= S_GET_RAW_TYPE (sp
);
3813 abstyp
= ((typ
& ~N_EXT
) == N_ABS
);
3815 * See if this is something we want to look at.
3818 typ
!= (N_DATA
| N_EXT
) &&
3819 typ
!= (N_UNDF
| N_EXT
))
3822 * See if this has globalvalue specification.
3824 Name
= S_GET_NAME (sp
);
3829 Psect_Attributes
= GLOBALVALUE_BIT
;
3831 else if (HAS_PSECT_ATTRIBUTES (Name
))
3833 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
3834 strcpy (stripped_name
, Name
);
3835 Psect_Attributes
= 0;
3836 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
3841 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3846 /* Local symbol references will want
3847 to have an environment defined. */
3848 if (Current_Environment
< 0)
3849 VMS_Local_Environment_Setup (".N_ABS");
3850 VMS_Global_Symbol_Spec (Name
, 0,
3852 GBLSYM_DEF
|GBLSYM_VAL
|GBLSYM_LCL
);
3855 VMS_Global_Symbol_Spec (Name
, 0,
3857 GBLSYM_DEF
|GBLSYM_VAL
);
3859 case N_UNDF
| N_EXT
:
3860 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
3862 case N_DATA
| N_EXT
:
3863 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
3865 error ("Invalid data type for globalvalue");
3866 globalvalue
= md_chars_to_number (Data_Segment
+
3867 S_GET_VALUE (sp
) - text_siz
, Size
);
3868 /* Three times for good luck. The linker seems to get confused
3869 if there are fewer than three */
3870 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
3871 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
3872 GBLSYM_DEF
|GBLSYM_VAL
);
3873 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
3874 GBLSYM_DEF
|GBLSYM_VAL
);
3877 as_warn ("Invalid globalvalue of %s", stripped_name
);
3881 if (stripped_name
) free (stripped_name
); /* clean up */
3888 * Define a procedure entry pt/mask
3891 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
3900 * We are writing a GSD record
3902 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3904 * If the buffer is empty we must insert the GSD record type
3906 if (Object_Record_Offset
== 0)
3907 PUT_CHAR (OBJ_S_C_GSD
);
3909 * We are writing a Procedure Entry Pt/Mask subrecord
3911 PUT_CHAR (((unsigned) Psect_Number
<= 255) ? GSD_S_C_EPM
: GSD_S_C_EPMW
);
3913 * Data type is undefined
3917 * Flags = "RELOCATABLE" and "DEFINED"
3919 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
3923 if ((unsigned) Psect_Number
<= 255)
3924 PUT_CHAR (Psect_Number
);
3926 PUT_SHORT (Psect_Number
);
3930 PUT_LONG (Psect_Offset
);
3934 PUT_SHORT (Entry_Mask
);
3936 * Finally, the global symbol name
3938 VMS_Case_Hack_Symbol (Name
, Local
);
3939 PUT_COUNTED_STRING (Local
);
3941 * Flush the buffer if it is more than 75% full
3943 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3944 Flush_VMS_Object_Record_Buffer ();
3949 * Set the current location counter to a particular Psect and Offset
3952 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
3958 * We are writing a "Record_Type" record
3960 Set_VMS_Object_File_Record (Record_Type
);
3962 * If the buffer is empty we must insert the record type
3964 if (Object_Record_Offset
== 0)
3965 PUT_CHAR (Record_Type
);
3967 * Stack the Psect base + Offset
3969 vms_tir_stack_psect (Psect_Index
, Offset
, 0);
3971 * Set relocation base
3973 PUT_CHAR (TIR_S_C_CTL_SETRB
);
3975 * Flush the buffer if it is more than 75% full
3977 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3978 Flush_VMS_Object_Record_Buffer ();
3983 * Store repeated immediate data in current Psect
3986 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
3988 register char *Pointer
;
3994 * Ignore zero bytes/words/longwords
3999 if (Pointer
[3] != 0 || Pointer
[2] != 0) break;
4002 if (Pointer
[1] != 0) break;
4005 if (Pointer
[0] != 0) break;
4012 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4013 * then we do it manually
4017 while (--Repeat_Count
>= 0)
4018 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4022 * We are writing a "Record_Type" record
4024 Set_VMS_Object_File_Record (Record_Type
);
4026 * If the buffer is empty we must insert record type
4028 if (Object_Record_Offset
== 0)
4029 PUT_CHAR (Record_Type
);
4031 * Stack the repeat count
4033 PUT_CHAR (TIR_S_C_STA_LW
);
4034 PUT_LONG (Repeat_Count
);
4036 * And now the command and its data
4038 PUT_CHAR (TIR_S_C_STO_RIVB
);
4041 PUT_CHAR (*Pointer
++);
4043 * Flush the buffer if it is more than 75% full
4045 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4046 Flush_VMS_Object_Record_Buffer ();
4051 * Store a Position Independent Reference
4054 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4055 Psect
, Psect_Offset
, Record_Type
)
4063 register struct VMS_Symbol
*vsp
= Symbol
->sy_obj
;
4068 * We are writing a "Record_Type" record
4070 Set_VMS_Object_File_Record (Record_Type
);
4072 * If the buffer is empty we must insert record type
4074 if (Object_Record_Offset
== 0)
4075 PUT_CHAR (Record_Type
);
4077 * Set to the appropriate offset in the Psect.
4078 * For a Code reference we need to fix the operand
4079 * specifier as well, so back up 1 byte;
4080 * for a Data reference we just store HERE.
4082 VMS_Set_Psect (Psect
,
4083 PC_Relative
? Psect_Offset
- 1 : Psect_Offset
,
4086 * Make sure we are still generating a "Record Type" record
4088 if (Object_Record_Offset
== 0)
4089 PUT_CHAR (Record_Type
);
4091 * Dispatch on symbol type (so we can stack its value)
4093 switch (S_GET_RAW_TYPE (Symbol
))
4102 #ifdef NOT_VAX_11_C_COMPATIBLE
4103 case N_UNDF
| N_EXT
:
4104 case N_DATA
| N_EXT
:
4105 #endif /* NOT_VAX_11_C_COMPATIBLE */
4107 case N_TEXT
| N_EXT
:
4109 * Get the symbol name (case hacked)
4111 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4113 * Stack the global symbol value
4117 PUT_CHAR (TIR_S_C_STA_GBL
);
4121 /* Local symbols have an extra field. */
4122 PUT_CHAR (TIR_S_C_STA_LSY
);
4123 PUT_SHORT (Current_Environment
);
4125 PUT_COUNTED_STRING (Local
);
4129 * Stack the longword offset
4131 PUT_CHAR (TIR_S_C_STA_LW
);
4134 * Add the two, leaving the result on the stack
4136 PUT_CHAR (TIR_S_C_OPR_ADD
);
4140 * Uninitialized local data
4144 * Stack the Psect (+offset)
4146 vms_tir_stack_psect (vsp
->Psect_Index
,
4147 vsp
->Psect_Offset
+ Offset
,
4155 * Stack the Psect (+offset)
4157 vms_tir_stack_psect (vsp
->Psect_Index
,
4158 S_GET_VALUE (Symbol
) + Offset
,
4162 * Initialized local or global data
4165 #ifndef NOT_VAX_11_C_COMPATIBLE
4166 case N_UNDF
| N_EXT
:
4167 case N_DATA
| N_EXT
:
4168 #endif /* NOT_VAX_11_C_COMPATIBLE */
4170 * Stack the Psect (+offset)
4172 vms_tir_stack_psect (vsp
->Psect_Index
,
4173 vsp
->Psect_Offset
+ Offset
,
4178 * Store either a code or data reference
4180 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
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 * Check in the text area for an indirect pc-relative reference
4191 * and fix it up with addressing mode 0xff [PC indirect]
4193 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4194 * PIC CODE GENERATING FIXUP ROUTINE.
4197 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4200 register fragS
*fragP
;
4201 fragS
*text_frag_root
;
4204 * The addressing mode byte is 1 byte before the address
4208 * Is it in THIS frag??
4210 if ((Offset
< fragP
->fr_address
) ||
4211 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4214 * We need to search for the fragment containing this
4217 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4219 if ((Offset
>= fragP
->fr_address
) &&
4220 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4224 * If we couldn't find the frag, things are BAD!!
4227 error ("Couldn't find fixup fragment when checking for indirect reference");
4230 * Check for indirect PC relative addressing mode
4232 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4234 static char Address_Mode
= (char) 0xff;
4237 * Yes: Store the indirect mode back into the image
4238 * to fix up the damage done by STO_PICR
4240 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4241 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4247 * If the procedure "main()" exists we have to add the instruction
4248 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4250 * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed
4251 * to `HACK_VAXCRTL_STARTUP' because Digital's compiler
4252 * named "DEC C" uses run-time library "DECC$SHR", but this
4253 * startup code is for "VAXCRTL", the library for Digital's
4254 * older "VAX C". Also, this extra code isn't needed for
4255 * supporting gcc because it already generates the VAXCRTL
4256 * startup call when compiling main(). The reference to
4257 * `flag_hash_long_names' looks very suspicious too;
4258 * probably an old-style command line option was inadvertently
4259 * overloaded here, then blindly converted into the new one.
4262 vms_check_for_main ()
4264 register symbolS
*symbolP
;
4265 #ifdef HACK_DEC_C_STARTUP /* JF */
4266 register struct frchain
*frchainP
;
4267 register fragS
*fragP
;
4268 register fragS
**prev_fragPP
;
4269 register struct fix
*fixP
;
4270 register fragS
*New_Frag
;
4272 #endif /* HACK_DEC_C_STARTUP */
4274 symbolP
= (symbolS
*) symbol_find ("_main");
4275 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4276 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4278 #ifdef HACK_DEC_C_STARTUP
4279 if (!flag_hash_long_names
)
4283 * Remember the entry point symbol
4285 Entry_Point_Symbol
= symbolP
;
4286 #ifdef HACK_DEC_C_STARTUP
4291 * Scan all the fragment chains for the one with "_main"
4292 * (Actually we know the fragment from the symbol, but we need
4293 * the previous fragment so we can change its pointer)
4295 frchainP
= frchain_root
;
4299 * Scan all the fragments in this chain, remembering
4300 * the "previous fragment"
4302 prev_fragPP
= &frchainP
->frch_root
;
4303 fragP
= frchainP
->frch_root
;
4304 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4307 * Is this the fragment?
4309 if (fragP
== symbolP
->sy_frag
)
4312 * Yes: Modify the fragment by replacing
4313 * it with a new fragment.
4315 New_Frag
= (fragS
*)
4316 xmalloc (sizeof (*New_Frag
) +
4321 * The fragments are the same except
4322 * that the "fixed" area is larger
4325 New_Frag
->fr_fix
+= 6;
4327 * Copy the literal data opening a hole
4328 * 2 bytes after "_main" (i.e. just after
4329 * the entry mask). Into which we place
4330 * the JSB instruction.
4332 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4333 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4334 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4335 New_Frag
->fr_literal
[3] = 0xef;
4336 New_Frag
->fr_literal
[4] = 0;
4337 New_Frag
->fr_literal
[5] = 0;
4338 New_Frag
->fr_literal
[6] = 0;
4339 New_Frag
->fr_literal
[7] = 0;
4340 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4341 New_Frag
->fr_literal
[i
+ 6] =
4342 fragP
->fr_literal
[i
];
4344 * Now replace the old fragment with the
4345 * newly generated one.
4347 *prev_fragPP
= New_Frag
;
4349 * Remember the entry point symbol
4351 Entry_Point_Symbol
= symbolP
;
4353 * Scan the text area fixup structures
4354 * as offsets in the fragment may have
4357 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4360 * Look for references to this
4363 if (fixP
->fx_frag
== fragP
)
4366 * Change the fragment
4369 fixP
->fx_frag
= New_Frag
;
4371 * If the offset is after
4372 * the entry mask we need
4373 * to account for the JSB
4374 * instruction we just
4377 if (fixP
->fx_where
>= 2)
4378 fixP
->fx_where
+= 6;
4382 * Scan the symbols as offsets in the
4383 * fragment may have changed
4385 for (symbolP
= symbol_rootP
;
4387 symbolP
= symbol_next (symbolP
))
4390 * Look for references to this
4393 if (symbolP
->sy_frag
== fragP
)
4396 * Change the fragment
4399 symbolP
->sy_frag
= New_Frag
;
4401 * If the offset is after
4402 * the entry mask we need
4403 * to account for the JSB
4404 * instruction we just
4407 if (S_GET_VALUE (symbolP
) >= 2)
4408 S_SET_VALUE (symbolP
,
4409 S_GET_VALUE (symbolP
) + 6);
4413 * Make a symbol reference to
4414 * "_c$main_args" so we can get
4415 * its address inserted into the
4418 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4419 S_SET_NAME (symbolP
, "_C$MAIN_ARGS");
4420 S_SET_TYPE (symbolP
, N_UNDF
);
4421 S_SET_OTHER (symbolP
, 0);
4422 S_SET_DESC (symbolP
, 0);
4423 S_SET_VALUE (symbolP
, 0);
4424 symbolP
->sy_name_offset
= 0;
4425 symbolP
->sy_number
= 0;
4426 symbolP
->sy_obj
= 0;
4427 symbolP
->sy_frag
= New_Frag
;
4428 symbolP
->sy_resolved
= 0;
4429 symbolP
->sy_resolving
= 0;
4430 /* this actually inserts at the beginning of the list */
4431 symbol_append (symbol_rootP
, symbolP
,
4432 &symbol_rootP
, &symbol_lastP
);
4434 symbol_rootP
= symbolP
;
4436 * Generate a text fixup structure
4437 * to get "_c$main_args" stored into the
4440 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4441 fixP
->fx_frag
= New_Frag
;
4443 fixP
->fx_addsy
= symbolP
;
4445 fixP
->fx_offset
= 0;
4448 fixP
->fx_next
= text_fix_root
;
4449 text_fix_root
= fixP
;
4451 * Now make sure we exit from the loop
4457 * Try the next fragment
4459 prev_fragPP
= &fragP
->fr_next
;
4460 fragP
= fragP
->fr_next
;
4463 * Try the next fragment chain
4466 frchainP
= frchainP
->frch_next
;
4469 #endif /* HACK_DEC_C_STARTUP */
4475 * Beginning of vms_write_object_file().
4479 struct vms_obj_state
{
4481 /* Next program section index to use. */
4484 /* Psect index for code. Always ends up #0. */
4487 /* Psect index for initialized static variables. */
4490 /* Psect index for uninitialized static variables. */
4493 /* Number of bytes used for local symbol data. */
4494 int local_initd_data_size
;
4496 /* Dynamic buffer for initialized data. */
4501 #define Psect_Number vms_obj_state.psect_number
4502 #define Text_Psect vms_obj_state.text_psect
4503 #define Data_Psect vms_obj_state.data_psect
4504 #define Bss_Psect vms_obj_state.bss_psect
4505 #define Local_Initd_Data_Size vms_obj_state.local_initd_data_size
4506 #define Data_Segment vms_obj_state.data_segment
4509 #define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
4512 /* Perform text segment fixups. */
4515 vms_fixup_text_section (text_siz
, text_frag_root
, data_frag_root
)
4517 struct frag
*text_frag_root
;
4518 struct frag
*data_frag_root
;
4520 register fragS
*fragP
;
4521 register struct fix
*fixP
;
4524 /* Scan the text fragments. */
4525 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4527 /* Stop if we get to the data fragments. */
4528 if (fragP
== data_frag_root
)
4530 /* Ignore fragments with no data. */
4531 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4533 /* Go the the appropriate offset in the Text Psect. */
4534 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4535 /* Store the "fixed" part. */
4537 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4540 /* Store the "variable" part. */
4541 if (fragP
->fr_var
&& fragP
->fr_offset
)
4542 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4543 fragP
->fr_literal
+ fragP
->fr_fix
,
4546 } /* text frag loop */
4549 * Now we go through the text segment fixups and generate
4550 * TIR records to fix up addresses within the Text Psect.
4552 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4554 /* We DO handle the case of "Symbol - Symbol" as
4555 long as it is in the same segment. */
4556 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4558 /* They need to be in the same segment. */
4559 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4560 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4561 error ("Fixup data addsy and subsy don't have the same type");
4562 /* And they need to be in one that we can check the psect on. */
4563 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4564 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4565 error ("Fixup data addsy and subsy don't have an appropriate type");
4566 /* This had better not be PC relative! */
4568 error ("Fixup data is erroneously \"pcrel\"");
4569 /* Subtract their values to get the difference. */
4570 dif
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
4571 md_number_to_chars (Local
, (valueT
)dif
, fixP
->fx_size
);
4572 /* Now generate the fixup object records;
4573 set the psect and store the data. */
4574 VMS_Set_Psect (Text_Psect
,
4575 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4577 VMS_Store_Immediate_Data (Local
,
4580 continue; /* done with this fixup */
4581 } /* if fx_subsy && fx_addsy */
4582 /* Size will HAVE to be "long". */
4583 if (fixP
->fx_size
!= 4)
4584 error ("Fixup datum is not a longword");
4585 /* Symbol must be "added" (if it is ever
4586 subtracted we can fix this assumption). */
4587 if (fixP
->fx_addsy
== 0)
4588 error ("Fixup datum is not \"fixP->fx_addsy\"");
4589 /* Store the symbol value in a PIC fashion. */
4590 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4594 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4597 * Check for indirect address reference, which has to be fixed up
4598 * (as the linker will screw it up with TIR_S_C_STO_PICR)...
4601 VMS_Fix_Indirect_Reference (Text_Psect
,
4602 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4605 } /* text fix loop */
4609 /* Create a buffer holding the data segment. */
4612 synthesize_data_segment (data_siz
, text_siz
, data_frag_root
)
4613 unsigned data_siz
, text_siz
;
4614 struct frag
*data_frag_root
;
4616 register fragS
*fragP
;
4618 long fill_size
, count
, i
;
4620 /* Allocate the data segment. */
4621 Data_Segment
= (char *) xmalloc (data_siz
);
4622 /* Run through the data fragments, filling in the segment. */
4623 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4625 i
= fragP
->fr_address
- text_siz
;
4627 memcpy (Data_Segment
+ i
, fragP
->fr_literal
, fragP
->fr_fix
);
4630 if ((fill_size
= fragP
->fr_var
) != 0)
4632 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4633 for (count
= fragP
->fr_offset
; count
; count
--)
4635 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4639 } /* data frag loop */
4645 /* Perform data segment fixups. */
4648 vms_fixup_data_section (data_siz
, text_siz
)
4649 unsigned data_siz
, text_siz
;
4651 register struct VMS_Symbol
*vsp
;
4652 register struct fix
*fixP
;
4653 register symbolS
*sp
;
4654 addressT fr_address
;
4658 /* Run through all the data symbols and store the data. */
4659 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4661 /* Ignore anything other than data symbols. */
4662 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
4664 /* Set the Psect + Offset. */
4665 VMS_Set_Psect (vsp
->Psect_Index
,
4668 /* Store the data. */
4669 val
= S_GET_VALUE (vsp
->Symbol
);
4670 VMS_Store_Immediate_Data (Data_Segment
+ val
- text_siz
,
4673 } /* N_DATA symbol loop */
4676 * Now we go through the data segment fixups and generate
4677 * TIR records to fix up addresses within the Data Psects.
4679 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4681 /* Find the symbol for the containing datum. */
4682 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4684 /* Only bother with Data symbols. */
4686 if (S_GET_TYPE (sp
) != N_DATA
)
4688 /* Ignore symbol if After fixup. */
4689 val
= S_GET_VALUE (sp
);
4690 fr_address
= fixP
->fx_frag
->fr_address
;
4691 if (val
> fixP
->fx_where
+ fr_address
)
4693 /* See if the datum is here. */
4694 if (val
+ vsp
->Size
<= fixP
->fx_where
+ fr_address
)
4696 /* We DO handle the case of "Symbol - Symbol" as
4697 long as it is in the same segment. */
4698 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4700 /* They need to be in the same segment. */
4701 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4702 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4703 error ("Fixup data addsy and subsy don't have the same type");
4704 /* And they need to be in one that we can check the psect on. */
4705 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4706 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4707 error ("Fixup data addsy and subsy don't have an appropriate type");
4708 /* This had better not be PC relative! */
4710 error ("Fixup data is erroneously \"pcrel\"");
4711 /* Subtract their values to get the difference. */
4712 dif
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
4713 md_number_to_chars (Local
, (valueT
)dif
, fixP
->fx_size
);
4715 * Now generate the fixup object records;
4716 * set the psect and store the data.
4718 VMS_Set_Psect (vsp
->Psect_Index
,
4719 fr_address
+ fixP
->fx_where
4720 - val
+ vsp
->Psect_Offset
,
4722 VMS_Store_Immediate_Data (Local
,
4725 break; /* done with this fixup */
4727 /* Size will HAVE to be "long". */
4728 if (fixP
->fx_size
!= 4)
4729 error ("Fixup datum is not a longword");
4730 /* Symbol must be "added" (if it is ever
4731 subtracted we can fix this assumption). */
4732 if (fixP
->fx_addsy
== 0)
4733 error ("Fixup datum is not \"fixP->fx_addsy\"");
4734 /* Store the symbol value in a PIC fashion. */
4735 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4739 fr_address
+ fixP
->fx_where
4740 - val
+ vsp
->Psect_Offset
,
4742 /* Done with this fixup. */
4744 } /* vms_symbol loop */
4746 } /* data fix loop */
4750 /* Define symbols for the linker. */
4753 global_symbol_directory (text_siz
, data_siz
)
4754 unsigned text_siz
, data_siz
;
4756 register fragS
*fragP
;
4757 register symbolS
*sp
;
4758 register struct VMS_Symbol
*vsp
;
4759 int Globalref
, define_as_global_symbol
;
4761 #ifndef gxx_bug_fixed
4763 * The g++ compiler does not write out external references to vtables
4764 * correctly. Check for this and holler if we see it happening.
4765 * If that compiler bug is ever fixed we can remove this.
4766 * (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
4768 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4769 if (S_GET_RAW_TYPE (sp
) == N_UNDF
&& IS_GXX_VTABLE (sp
))
4771 S_SET_TYPE (sp
, N_UNDF
| N_EXT
);
4772 S_SET_OTHER (sp
, 1);
4773 as_warn ("g++ wrote an extern reference to `%s' as a routine.\n%s",
4775 "I will fix it, but I hope that it was not really a routine.");
4777 #endif /* gxx_bug_fixed */
4780 * Now scan the symbols and emit the appropriate GSD records
4782 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
4784 define_as_global_symbol
= 0;
4786 /* Dispatch on symbol type. */
4787 switch (S_GET_RAW_TYPE (sp
))
4790 /* Global uninitialized data. */
4791 case N_UNDF
| N_EXT
:
4792 /* Make a VMS data symbol entry. */
4793 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
4795 vsp
->Size
= S_GET_VALUE (sp
);
4796 vsp
->Psect_Index
= Psect_Number
++;
4797 vsp
->Psect_Offset
= 0;
4798 vsp
->Next
= VMS_Symbols
;
4801 /* Make the psect for this data. */
4802 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
4804 S_GET_OTHER (sp
) ? ps_CONST
: ps_COMMON
,
4808 #ifdef NOT_VAX_11_C_COMPATIBLE
4809 define_as_global_symbol
= 1;
4811 /* See if this is an external vtable. We want to help the
4812 linker find these things in libraries, so we make a symbol
4813 reference. This is not compatible with VAX-C usage for
4814 variables, but since vtables are only used internally by
4815 g++, we can get away with this hack. */
4816 define_as_global_symbol
= IS_GXX_VTABLE (sp
);
4820 /* Local uninitialized data. */
4822 /* Make a VMS data symbol entry. */
4823 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
4826 vsp
->Psect_Index
= Bss_Psect
;
4827 vsp
->Psect_Offset
= S_GET_VALUE (sp
) - bss_address_frag
.fr_address
;
4828 vsp
->Next
= VMS_Symbols
;
4833 /* Global initialized data. */
4834 case N_DATA
| N_EXT
:
4835 /* Make a VMS data symbol entry. */
4836 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
4838 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4839 vsp
->Psect_Index
= Psect_Number
++;
4840 vsp
->Psect_Offset
= 0;
4841 vsp
->Next
= VMS_Symbols
;
4844 /* Make its psect. */
4845 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
4847 S_GET_OTHER (sp
) ? ps_CONST
: ps_COMMON
,
4851 #ifdef NOT_VAX_11_C_COMPATIBLE
4852 define_as_global_symbol
= 1;
4854 /* See N_UNDF|N_EXT above for explanation. */
4855 define_as_global_symbol
= IS_GXX_VTABLE (sp
);
4859 /* Local initialized data. */
4862 char *sym_name
= S_GET_NAME (sp
);
4864 /* Always suppress local numeric labels. */
4865 if (sym_name
&& strcmp (sym_name
, FAKE_LABEL_NAME
) == 0)
4868 /* Make a VMS data symbol entry. */
4869 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
4871 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4872 vsp
->Psect_Index
= Data_Psect
;
4873 vsp
->Psect_Offset
= Local_Initd_Data_Size
;
4874 Local_Initd_Data_Size
+= vsp
->Size
;
4875 vsp
->Next
= VMS_Symbols
;
4881 /* Global Text definition. */
4882 case N_TEXT
| N_EXT
:
4884 unsigned short Entry_Mask
;
4886 /* Get the entry mask. */
4887 fragP
= sp
->sy_frag
;
4888 /* First frag might be empty if we're generating listings.
4889 So skip empty rs_fill frags. */
4890 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
4891 fragP
= fragP
->fr_next
;
4893 /* If first frag doesn't contain the data, what do we do?
4894 If it's possibly smaller than two bytes, that would
4895 imply that the entry mask is not stored where we're
4898 If you can find a test case that triggers this, report
4899 it (and tell me what the entry mask field ought to be),
4900 and I'll try to fix it. KR */
4901 if (fragP
->fr_fix
< 2)
4904 Entry_Mask
= (fragP
->fr_literal
[0] & 0x00ff) |
4905 ((fragP
->fr_literal
[1] & 0x00ff) << 8);
4906 /* Define the procedure entry point. */
4907 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
4914 /* Local Text definition. */
4916 /* Make a VMS data symbol entry. */
4917 if (Text_Psect
!= -1)
4919 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
4922 vsp
->Psect_Index
= Text_Psect
;
4923 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4924 vsp
->Next
= VMS_Symbols
;
4930 /* Global Reference. */
4932 /* Make a GSD global symbol reference record. */
4933 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4939 /* Absolute symbol. */
4942 /* gcc doesn't generate these;
4943 VMS_Emit_Globalvalue handles them though. */
4944 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
4946 vsp
->Size
= 4; /* always assume 32 bits */
4947 vsp
->Psect_Index
= 0;
4948 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
4949 vsp
->Next
= VMS_Symbols
;
4954 /* Anything else. */
4956 /* Ignore STAB symbols, including .stabs emitted by g++. */
4957 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
4962 as_tsktsk ("unhandled stab type %d", S_GET_TYPE (sp
));
4966 /* Global symbols have different linkage than external variables. */
4967 if (define_as_global_symbol
)
4968 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
4978 /* Output debugger symbol table information for symbols which
4979 are local to a specific routine. */
4982 local_symbols_DST (s0P
, Current_Routine
)
4983 symbolS
*s0P
, *Current_Routine
;
4986 char *s0P_name
, *pnt0
, *pnt1
;
4988 s0P_name
= S_GET_NAME (s0P
);
4989 if (*s0P_name
++ != '_')
4992 for (s1P
= Current_Routine
; s1P
; s1P
= symbol_next (s1P
))
4994 #if 0 /* redundant; RAW_TYPE != N_FUN suffices */
4995 if (!S_IS_DEBUG (s1P
))
4998 if (S_GET_RAW_TYPE (s1P
) != N_FUN
)
5001 pnt1
= S_GET_NAME (s1P
);
5002 /* We assume the two strings are never exactly equal... */
5003 while (*pnt0
++ == *pnt1
++)
5006 /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next.
5007 Note: both pointers have advanced one past the non-matching char. */
5008 if ((*pnt1
== 'F' || *pnt1
== 'f') && *--pnt1
== ':' && *--pnt0
== '\0')
5010 Define_Routine (s1P
, 0, Current_Routine
, Text_Psect
);
5017 /* Construct and output the debug symbol table. */
5020 vms_build_DST (text_siz
)
5023 register symbolS
*symbolP
;
5024 symbolS
*Current_Routine
= 0;
5025 struct input_file
*Cur_File
= 0;
5026 offsetT Cur_Offset
= -1;
5027 int Cur_Line_Number
= 0;
5028 int File_Number
= 0;
5029 int Debugger_Offset
= 0;
5034 /* Write the Traceback Begin Module record. */
5035 VMS_TBT_Module_Begin ();
5038 * Output debugging info for global variables and static variables
5039 * that are not specific to one routine. We also need to examine
5040 * all stabs directives, to find the definitions to all of the
5041 * advanced data types, and this is done by VMS_LSYM_Parse. This
5042 * needs to be done before any definitions are output to the object
5043 * file, since there can be forward references in the stabs
5044 * directives. When through with parsing, the text of the stabs
5045 * directive is altered, with the definitions removed, so that later
5046 * passes will see directives as they would be written if the type
5047 * were already defined.
5049 * We also look for files and include files, and make a list of
5050 * them. We examine the source file numbers to establish the actual
5051 * lines that code was generated from, and then generate offsets.
5054 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5056 /* Only deal with STAB symbols here. */
5057 if (!S_IS_DEBUG (symbolP
))
5060 * Dispatch on STAB type.
5062 switch (S_GET_RAW_TYPE (symbolP
))
5065 dsc
= S_GET_DESC (symbolP
);
5066 if (dsc
> Cur_File
->max_line
)
5067 Cur_File
->max_line
= dsc
;
5068 if (dsc
< Cur_File
->min_line
)
5069 Cur_File
->min_line
= dsc
;
5072 Cur_File
= find_file (symbolP
);
5074 Cur_File
->min_line
= 1;
5077 Cur_File
= find_file (symbolP
);
5080 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5083 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5085 case N_FUN
: /* For static constant symbols */
5087 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5095 * Now we take a quick sweep through the files and assign offsets
5096 * to each one. This will essentially be the starting line number to
5097 * the debugger for each file. Output the info for the debugger to
5098 * specify the files, and then tell it how many lines to use.
5100 for (Cur_File
= file_root
; Cur_File
; Cur_File
= Cur_File
->next
)
5102 if (Cur_File
->max_line
== 0)
5104 if ((strncmp (Cur_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5107 if ((strncmp (Cur_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5110 /* show a few extra lines at the start of the region selected */
5111 if (Cur_File
->min_line
> 2)
5112 Cur_File
->min_line
-= 2;
5113 Cur_File
->offset
= Debugger_Offset
- Cur_File
->min_line
+ 1;
5114 Debugger_Offset
+= Cur_File
->max_line
- Cur_File
->min_line
+ 1;
5115 if (Cur_File
->same_file_fpnt
)
5117 Cur_File
->file_number
= Cur_File
->same_file_fpnt
->file_number
;
5121 Cur_File
->file_number
= ++File_Number
;
5122 file_available
= VMS_TBT_Source_File (Cur_File
->name
,
5123 Cur_File
->file_number
);
5124 if (!file_available
)
5126 Cur_File
->file_number
= 0;
5131 VMS_TBT_Source_Lines (Cur_File
->file_number
,
5133 Cur_File
->max_line
- Cur_File
->min_line
+ 1);
5135 Cur_File
= (struct input_file
*) NULL
;
5138 * Scan the symbols and write out the routines
5139 * (this makes the assumption that symbols are in
5140 * order of ascending text segment offset)
5142 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5145 * Deal with text symbols.
5147 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
5150 * Ignore symbols starting with "L", as they are local symbols.
5152 if (*S_GET_NAME (symbolP
) == 'L')
5155 * If there is a routine start defined, terminate it.
5157 if (Current_Routine
)
5158 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5161 * Check for & skip dummy labels like "gcc_compiled.".
5162 * They're identified by the IN_DEFAULT_SECTION flag.
5164 if ((S_GET_OTHER (symbolP
) & IN_DEFAULT_SECTION
) != 0 &&
5165 S_GET_VALUE (symbolP
) == 0)
5168 * Store the routine begin traceback info.
5170 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5171 Current_Routine
= symbolP
;
5173 * Define symbols local to this routine.
5175 local_symbols_DST (symbolP
, Current_Routine
);
5183 * Deal with STAB symbols.
5185 else if (S_IS_DEBUG (symbolP
))
5188 * Dispatch on STAB type.
5190 switch (S_GET_RAW_TYPE (symbolP
))
5196 /* Offset the line into the correct portion of the file. */
5197 if (Cur_File
->file_number
== 0)
5199 val
= S_GET_VALUE (symbolP
);
5200 /* Sometimes the same offset gets several source lines
5201 assigned to it. We should be selective about which
5202 lines we allow, we should prefer lines that are in
5203 the main source file when debugging inline functions. */
5204 if (val
== Cur_Offset
&& Cur_File
->file_number
!= 1)
5207 /* calculate actual debugger source line */
5208 dsc
= S_GET_DESC (symbolP
) + Cur_File
->offset
;
5209 S_SET_DESC (symbolP
, dsc
);
5211 * Define PC/Line correlation.
5213 if (Cur_Offset
== -1)
5216 * First N_SLINE; set up initial correlation.
5218 VMS_TBT_Line_PC_Correlation (dsc
,
5223 else if ((dsc
- Cur_Line_Number
) <= 0)
5226 * Line delta is not +ve, we need to close the line and
5227 * start a new PC/Line correlation.
5229 VMS_TBT_Line_PC_Correlation (0,
5233 VMS_TBT_Line_PC_Correlation (dsc
,
5241 * Line delta is +ve, all is well.
5243 VMS_TBT_Line_PC_Correlation (dsc
- Cur_Line_Number
,
5248 /* Update the current line/PC info. */
5249 Cur_Line_Number
= dsc
;
5257 /* Remember that we had a source file and emit
5258 the source file debugger record. */
5259 Cur_File
= find_file (symbolP
);
5263 /* We need to make sure that we are really in the actual
5264 source file when we compute the maximum line number.
5265 Otherwise the debugger gets really confused. */
5266 Cur_File
= find_file (symbolP
);
5272 } /* if (IS_DEBUG) */
5276 * If there is a routine start defined, terminate it
5277 * (and the line numbers).
5279 if (Current_Routine
)
5281 /* Terminate the line numbers. */
5282 VMS_TBT_Line_PC_Correlation (0,
5283 text_siz
- S_GET_VALUE (Current_Routine
),
5286 /* Terminate the routine. */
5287 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5290 /* Write the Traceback End Module TBT record. */
5291 VMS_TBT_Module_End ();
5295 /* Write a VAX/VMS object file (everything else has been done!). */
5298 vms_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
5303 fragS
*text_frag_root
;
5304 fragS
*data_frag_root
;
5306 register struct VMS_Symbol
*vsp
;
5309 * Initialize program section indices; values get updated later.
5311 Psect_Number
= 0; /* next Psect Index to use */
5312 Text_Psect
= -1; /* Text Psect Index */
5313 Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
5314 Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
5315 /* Initialize other state variables. */
5317 Local_Initd_Data_Size
= 0;
5320 * Create the actual output file and populate it with required
5321 * "module header" information.
5323 Create_VMS_Object_File ();
5324 Write_VMS_MHD_Records ();
5327 * Create the Data segment:
5329 * Since this is REALLY hard to do any other way,
5330 * we actually manufacture the data segment and
5331 * then store the appropriate values out of it.
5332 * We need to generate this early, so that globalvalues
5333 * can be properly emitted.
5336 synthesize_data_segment (data_siz
, text_siz
, data_frag_root
);
5339 /******* Global Symbol Directory *******/
5342 * Emit globalvalues now. We must do this before the text psect is
5343 * defined, or we will get linker warnings about multiply defined
5344 * symbols. All of the globalvalues "reference" psect 0, although
5345 * it really does not have anything to do with it.
5347 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
5349 * Define the Text Psect
5351 Text_Psect
= Psect_Number
++;
5352 VMS_Psect_Spec ("$code", text_siz
, ps_TEXT
, 0);
5354 * Define the BSS Psect
5358 Bss_Psect
= Psect_Number
++;
5359 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, ps_DATA
, 0);
5362 * Define symbols to the linker.
5364 global_symbol_directory (text_siz
, data_siz
);
5366 * Define the Data Psect
5368 if (data_siz
> 0 && Local_Initd_Data_Size
> 0)
5370 Data_Psect
= Psect_Number
++;
5371 VMS_Psect_Spec ("$data", Local_Initd_Data_Size
, ps_DATA
, 0);
5373 * Local initialized data (N_DATA) symbols need to be updated to the
5374 * proper value of Data_Psect now that it's actually been defined.
5375 * (A dummy value was used in global_symbol_directory() above.)
5377 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5378 if (vsp
->Psect_Index
< 0 && S_GET_RAW_TYPE (vsp
->Symbol
) == N_DATA
)
5379 vsp
->Psect_Index
= Data_Psect
;
5383 /******* Text Information and Relocation Records *******/
5386 * Write the text segment data
5389 vms_fixup_text_section (text_siz
, text_frag_root
, data_frag_root
);
5391 * Write the data segment data, then discard it.
5395 vms_fixup_data_section (data_siz
, text_siz
);
5396 free (Data_Segment
), Data_Segment
= 0;
5400 /******* Debugger Symbol Table Records *******/
5402 vms_build_DST (text_siz
);
5405 /******* Wrap things up *******/
5408 * Write the End Of Module record
5410 if (Entry_Point_Symbol
)
5411 Write_VMS_EOM_Record (Text_Psect
, S_GET_VALUE (Entry_Point_Symbol
));
5413 Write_VMS_EOM_Record (-1, (valueT
) 0);
5416 * All done, close the object file
5418 Close_VMS_Object_File ();
5421 /* end of obj-vms.c */