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 * This enum is used to keep track of the various types of variables that
110 BASIC
, POINTER
, ARRAY
, ENUM
, STRUCT
, UNION
, FUNCTION
, VOID
, ALIAS
, UNKNOWN
114 * This structure contains the information from the stabs directives, and the
115 * information is filled in by VMS_typedef_parse. Everything that is needed
116 * to generate the debugging record for a given symbol is present here.
117 * This could be done more efficiently, using nested struct/unions, but for now
118 * I am happy that it works.
120 struct VMS_DBG_Symbol
122 struct VMS_DBG_Symbol
*next
;
123 /* description of what this is */
124 enum advanced_type advanced
;
125 /* this record is for this type */
127 /* For advanced types this is the type referred to. I.e., the type
128 a pointer points to, or the type of object that makes up an
131 /* Use this type when generating a variable def */
133 /* used for arrays - this will be present for all */
135 /* entries, but will be meaningless for non-arrays */
137 /* Size in bytes of the data type. For an array, this is the size
138 of one element in the array */
140 /* Number of the structure/union/enum - used for ref */
144 #define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */
145 #define SYMTYP_HASH(x) ((unsigned)(x) & (SYMTYPLST_SIZE-1))
146 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
[SYMTYPLST_SIZE
];
149 * We need this structure to keep track of forward references to
150 * struct/union/enum that have not been defined yet. When they are ultimately
151 * defined, then we can go back and generate the TIR commands to make a back
157 struct forward_ref
*next
;
163 struct forward_ref
*f_ref_root
= (struct forward_ref
*) NULL
;
166 * This routine is used to compare the names of certain types to various
167 * fixed types that are known by the debugger.
169 #define type_check(X) !strcmp (symbol_name, X)
172 * This variable is used to keep track of the name of the symbol we are
173 * working on while we are parsing the stabs directives.
175 static const char *symbol_name
;
177 /* We use this counter to assign numbers to all of the structures, unions
178 * and enums that we define. When we actually declare a variable to the
179 * debugger, we can simply do it by number, rather than describing the
180 * whole thing each time.
183 static structure_count
= 0;
185 /* This variable is used to indicate that we are making the last attempt to
186 parse the stabs, and that we should define as much as we can, and ignore
189 static int final_pass
;
191 /* This variable is used to keep track of the current structure number
192 * for a given variable. If this is < 0, that means that the structure
193 * has not yet been defined to the debugger. This is still cool, since
194 * the VMS object language has ways of fixing things up after the fact,
195 * so we just make a note of this, and generate fixups at the end.
197 static int struct_number
;
199 /* This is used to distinguish between D_float and G_float for telling
200 the debugger about doubles. gcc outputs the same .stabs regardless
201 of whether -mg is used to select alternate doubles. */
203 static int vax_g_doubles
= 0;
205 /* Local symbol references (used to handle N_ABS symbols; gcc does not
206 generate those, but they're possible with hand-coded assembler input)
207 are always made relative to some particular environment. If the current
208 input has any such symbols, then we expect this to get incremented
209 exactly once and end up having all of them be in environment #0. */
211 static int Current_Environment
= -1;
215 * Variable descriptors are used tell the debugger the data types of certain
216 * more complicated variables (basically anything involving a structure,
217 * union, enum, array or pointer). Some non-pointer variables of the
218 * basic types that the debugger knows about do not require a variable
221 * Since it is impossible to have a variable descriptor longer than 128
222 * bytes by virtue of the way that the VMS object language is set up,
223 * it makes not sense to make the arrays any longer than this, or worrying
224 * about dynamic sizing of the array.
226 * These are the arrays and counters that we use to build a variable
230 #define MAX_DEBUG_RECORD 128
231 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
232 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
233 static int Lpnt
; /* index into Local */
234 static int Apoint
; /* index into Asuffix */
235 static char overflow
; /* flag to indicate we have written too much*/
236 static int total_len
; /* used to calculate the total length of variable
237 descriptor plus array descriptor - used for len byte*/
239 /* Flag if we have told user about finding global constants in the text
241 static int gave_compiler_message
= 0;
245 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
247 static int VMS_Object_File_FD
; /* File Descriptor for object file */
248 static char Object_Record_Buffer
[512]; /* Buffer for object file records */
249 static int Object_Record_Offset
;/* Offset to end of data */
250 static int Current_Object_Record_Type
; /* Type of record in above */
253 * Macros for moving data around. Must work on big-endian systems.
255 #ifdef VMS /* These are more efficient for VMS->VMS systems */
256 #define COPY_LONG(dest,val) {*(long *) dest = val; }
257 #define COPY_SHORT(dest,val) {*(short *) dest = val; }
259 #define COPY_LONG(dest,val) { md_number_to_chars(dest, val, 4); }
260 #define COPY_SHORT(dest,val) { md_number_to_chars(dest, val, 2); }
263 * Macros for placing data into the object record buffer
265 #define PUT_LONG(val) \
266 { COPY_LONG(&Object_Record_Buffer[Object_Record_Offset], val); \
267 Object_Record_Offset += 4; }
269 #define PUT_SHORT(val) \
270 { COPY_SHORT(&Object_Record_Buffer[Object_Record_Offset], val); \
271 Object_Record_Offset += 2; }
273 #define PUT_CHAR(val) Object_Record_Buffer[Object_Record_Offset++] = val
275 #define PUT_COUNTED_STRING(cp) {\
276 register const char *p = cp; \
277 PUT_CHAR(strlen(p)); \
278 while (*p) PUT_CHAR(*p++);}
281 * Macro for determining if a Name has psect attributes attached
284 #define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
285 #define PSECT_ATTRIBUTES_STRING_LENGTH 18
287 #define HAS_PSECT_ATTRIBUTES(Name) \
288 (strncmp((Name[0] == '_' ? Name + 1 : Name), \
289 PSECT_ATTRIBUTES_STRING, \
290 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
293 /* in: segT out: N_TYPE bits */
294 const short seg_N_TYPE
[] =
300 N_UNDF
, /* unknown */
302 N_UNDF
, /* expression */
306 N_REGISTER
, /* register */
309 const segT N_TYPE_seg
[N_TYPE
+ 2] =
310 { /* N_TYPE == 0x1E = 32-2 */
311 SEG_UNKNOWN
, /* N_UNDF == 0 */
313 SEG_ABSOLUTE
, /* N_ABS == 2 */
315 SEG_TEXT
, /* N_TEXT == 4 */
317 SEG_DATA
, /* N_DATA == 6 */
319 SEG_BSS
, /* N_BSS == 8 */
321 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
322 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
323 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
324 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
329 /* Local support routines which return a value. */
331 static struct input_file
*find_file
PARAMS ((symbolS
*));
332 static struct VMS_DBG_Symbol
*find_symbol
PARAMS ((int));
333 static symbolS
*Define_Routine
PARAMS ((symbolS
*,int,symbolS
*,int));
335 static char *cvt_integer
PARAMS ((char *,int *));
336 static char *fix_name
PARAMS ((char *));
337 static char *get_struct_name
PARAMS ((char *));
339 static int VMS_TBT_Source_File
PARAMS ((char *,int));
340 static int gen1
PARAMS ((struct VMS_DBG_Symbol
*,int));
341 static int forward_reference
PARAMS ((char *));
342 static int final_forward_reference
PARAMS ((struct VMS_DBG_Symbol
*));
343 static int VMS_typedef_parse
PARAMS ((char *));
344 static int hash_string
PARAMS ((const char *));
345 static int VMS_Psect_Spec
PARAMS ((const char *,int,const char *,
346 struct VMS_Symbol
*));
347 static int VMS_Initialized_Data_Size
PARAMS ((symbolS
*,int));
349 /* Local support routines which don't directly return any value. */
351 static void s_const
PARAMS ((int));
352 static void Create_VMS_Object_File
PARAMS ((void));
353 static void Flush_VMS_Object_Record_Buffer
PARAMS ((void));
354 static void Set_VMS_Object_File_Record
PARAMS ((int));
355 static void Close_VMS_Object_File
PARAMS ((void));
356 static void vms_tir_stack_psect
PARAMS ((int,int,int));
357 static void VMS_Store_Immediate_Data
PARAMS ((const char *,int,int));
358 static void VMS_Set_Data
PARAMS ((int,int,int,int));
359 static void VMS_Store_Struct
PARAMS ((int));
360 static void VMS_Def_Struct
PARAMS ((int));
361 static void VMS_Set_Struct
PARAMS ((int));
362 static void VMS_TBT_Module_Begin
PARAMS ((void));
363 static void VMS_TBT_Module_End
PARAMS ((void));
364 static void VMS_TBT_Routine_Begin
PARAMS ((symbolS
*,int));
365 static void VMS_TBT_Routine_End
PARAMS ((int,symbolS
*));
366 static void VMS_TBT_Block_Begin
PARAMS ((symbolS
*,int,char *));
367 static void VMS_TBT_Block_End
PARAMS ((valueT
));
368 static void VMS_TBT_Line_PC_Correlation
PARAMS ((int,int,int,int));
369 static void VMS_TBT_Source_Lines
PARAMS ((int,int,int));
370 static void fpush
PARAMS ((int,int));
371 static void rpush
PARAMS ((int,int));
372 static void array_suffix
PARAMS ((struct VMS_DBG_Symbol
*));
373 static void new_forward_ref
PARAMS ((int));
374 static void generate_suffix
PARAMS ((struct VMS_DBG_Symbol
*,int));
375 static void bitfield_suffix
PARAMS ((struct VMS_DBG_Symbol
*,int));
376 static void setup_basic_type
PARAMS ((struct VMS_DBG_Symbol
*));
377 static void VMS_DBG_record
PARAMS ((struct VMS_DBG_Symbol
*,int,int,char *));
378 static void VMS_local_stab_Parse
PARAMS ((symbolS
*));
379 static void VMS_stab_parse
PARAMS ((symbolS
*,int,int,int,int));
380 static void VMS_GSYM_Parse
PARAMS ((symbolS
*,int));
381 static void VMS_LCSYM_Parse
PARAMS ((symbolS
*,int));
382 static void VMS_STSYM_Parse
PARAMS ((symbolS
*,int));
383 static void VMS_RSYM_Parse
PARAMS ((symbolS
*,symbolS
*,int));
384 static void VMS_LSYM_Parse
PARAMS ((void));
385 static void Define_Local_Symbols
PARAMS ((symbolS
*,symbolS
*,symbolS
*,int));
386 static void Write_VMS_MHD_Records
PARAMS ((void));
387 static void Write_VMS_EOM_Record
PARAMS ((int,int));
388 static void VMS_Case_Hack_Symbol
PARAMS ((const char *,char *));
389 static void VMS_Modify_Psect_Attributes
PARAMS ((const char *,int *));
390 static void VMS_Global_Symbol_Spec
PARAMS ((const char *,int,int,int));
391 static void VMS_Local_Environment_Setup
PARAMS ((const char *));
392 static void VMS_Emit_Globalvalues
PARAMS ((unsigned,unsigned,char *));
393 static void VMS_Procedure_Entry_Pt
PARAMS ((char *,int,int,int));
394 static void VMS_Set_Psect
PARAMS ((int,int,int));
395 static void VMS_Store_Repeated_Data
PARAMS ((int,char *,int,int));
396 static void VMS_Store_PIC_Symbol_Reference
PARAMS ((symbolS
*,int,
398 static void VMS_Fix_Indirect_Reference
PARAMS ((int,int,fragS
*,fragS
*));
400 /* Support code which used to be inline within vms_write_object_file. */
401 static void vms_fixup_text_section
PARAMS ((unsigned,struct frag
*,struct frag
*));
402 static void synthesize_data_segment
PARAMS ((unsigned,unsigned,struct frag
*));
403 static void vms_fixup_data_section
PARAMS ((unsigned,unsigned));
404 static void global_symbol_directory
PARAMS ((unsigned,unsigned));
405 static void local_symbols_DST
PARAMS ((symbolS
*,symbolS
*));
406 static void vms_build_DST
PARAMS ((unsigned));
409 /* The following code defines the special types of pseudo-ops that we
413 char const_flag
= IN_DEFAULT_SECTION
;
417 int arg
; /* 3rd field from obj_pseudo_table[]; not needed here */
419 /* Since we don't need `arg', use it as our scratch variable so that
420 we won't get any "not used" warnings about it. */
421 arg
= get_absolute_expression ();
422 subseg_set (SEG_DATA
, (subsegT
) arg
);
424 demand_empty_rest_of_line ();
427 const pseudo_typeS obj_pseudo_table
[] =
429 {"const", s_const
, 0},
431 }; /* obj_pseudo_table */
434 vms_resolve_symbol_redef (sym
)
438 * If the new symbol is .comm AND it has a size of zero,
439 * we ignore it (i.e. the old symbol overrides it)
441 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg
) == (N_UNDF
| N_EXT
)
442 && frag_now_fix () == 0)
444 as_warn ("compiler emitted zero-size common symbol `%s' already defined",
449 * If the old symbol is .comm and it has a size of zero,
450 * we override it with the new symbol value.
452 if (S_IS_EXTERNAL(sym
) && S_IS_DEFINED(sym
)
453 && (S_GET_VALUE(sym
) == 0))
455 as_warn ("compiler redefined zero-size common symbol `%s'",
457 sym
->sy_frag
= frag_now
;
458 S_SET_OTHER(sym
, const_flag
);
459 S_SET_VALUE(sym
, frag_now_fix ());
460 /* Keep N_EXT bit. */
461 sym
->sy_symbol
.n_type
|= SEGMENT_TO_SYMBOL_TYPE((int) now_seg
);
468 /* `tc_frob_label' handler for colon(symbols.c), used to examine the
469 dummy label(s) gcc inserts at the beginning of each file it generates.
470 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
471 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
474 vms_check_for_special_label (symbolP
)
477 /* Special labels only occur prior to explicit section directives. */
478 if ((const_flag
& IN_DEFAULT_SECTION
) != 0)
480 char *sym_name
= S_GET_NAME(symbolP
);
482 if (*sym_name
== '_')
485 if (!strcmp (sym_name
, "__vax_g_doubles"))
487 #if 0 /* not necessary */
488 else if (!strcmp (sym_name
, "__vax_d_doubles"))
491 #if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
492 else if (!strcmp (sym_name
, "gcc_compiled."))
494 else if (!strcmp (sym_name
, "__gnu_language_cplusplus"))
495 flag_hash_long_names
= 1;
502 obj_read_begin_hook ()
508 obj_crawl_symbol_chain (headers
)
509 object_headers
*headers
;
513 int symbol_number
= 0;
515 symbolPP
= &symbol_rootP
; /* -> last symbol chain link. */
516 while ((symbolP
= *symbolPP
) != NULL
)
518 resolve_symbol_value (symbolP
);
520 /* OK, here is how we decide which symbols go out into the
521 brave new symtab. Symbols that do are:
523 * symbols with no name (stabd's?)
524 * symbols with debug info in their N_TYPE
525 * symbols with \1 as their 3rd character (numeric labels)
526 * "local labels" needed for PIC fixups
528 Symbols that don't are:
529 * symbols that are registers
531 All other symbols are output. We complain if a deleted
532 symbol was marked external. */
534 if (!S_IS_REGISTER (symbolP
))
536 symbolP
->sy_number
= symbol_number
++;
537 symbolP
->sy_name_offset
= 0;
538 symbolPP
= &(symbol_next (symbolP
));
542 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
544 as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP
));
547 /* Unhook it from the chain. */
548 *symbolPP
= symbol_next (symbolP
);
549 } /* if this symbol should be in the output */
551 } /* for each symbol */
553 H_SET_STRING_SIZE (headers
, string_byte_count
);
554 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
555 } /* obj_crawl_symbol_chain() */
558 /****** VMS OBJECT FILE HACKING ROUTINES *******/
562 * Create the VMS object file
565 Create_VMS_Object_File ()
567 #if defined(eunice) || !defined(VMS)
568 VMS_Object_File_FD
= creat (out_file_name
, 0777, "var");
570 VMS_Object_File_FD
= creat (out_file_name
, 0, "rfm=var",
571 "mbc=16", "deq=64", "fop=tef", "shr=nil");
576 if (VMS_Object_File_FD
< 0)
577 as_fatal ("Couldn't create VMS object file \"%s\"", out_file_name
);
579 * Initialize object file hacking variables
581 Object_Record_Offset
= 0;
582 Current_Object_Record_Type
= -1;
587 * Flush the object record buffer to the object file
590 Flush_VMS_Object_Record_Buffer ()
599 * If the buffer is empty, we are done
601 if (Object_Record_Offset
== 0)
604 * Write the data to the file
606 #ifndef VMS /* For cross-assembly purposes. */
607 md_number_to_chars((char *) &RecLen
, Object_Record_Offset
, 2);
608 i
= write (VMS_Object_File_FD
, &RecLen
, 2);
610 i
= write (VMS_Object_File_FD
,
611 Object_Record_Buffer
,
612 Object_Record_Offset
);
613 if (i
!= Object_Record_Offset
)
614 error ("I/O error writing VMS object file");
615 #ifndef VMS /* When cross-assembling, we need to pad the record to an even
617 /* pad it if needed */
619 if ((Object_Record_Offset
& 1) != 0)
620 write (VMS_Object_File_FD
, &zero
, 1);
623 * The buffer is now empty
625 Object_Record_Offset
= 0;
630 * Declare a particular type of object file record
633 Set_VMS_Object_File_Record (Type
)
637 * If the type matches, we are done
639 if (Type
== Current_Object_Record_Type
)
642 * Otherwise: flush the buffer
644 Flush_VMS_Object_Record_Buffer ();
648 Current_Object_Record_Type
= Type
;
654 * Close the VMS Object file
657 Close_VMS_Object_File ()
659 #ifndef VMS /* For cross-assembly purposes. */
660 short int m_one
= -1;
662 /* Write a record-length field of 0xffff into the file, which means
663 end-of-file when read later. It is only needed for variable-length
664 record files transferred to VMS as fixed-length record files
665 (typical for binary ftp). */
666 write (VMS_Object_File_FD
, &m_one
, 2);
668 /* When written on a VMS system, the file header (cf inode) will record
669 the actual end-of-file position and no inline marker is needed. */
672 close (VMS_Object_File_FD
);
677 * Stack Psect base followed by signed, varying-sized offset.
678 * Common to several object records.
681 vms_tir_stack_psect (Psect_Index
, Offset
, Force
)
686 int psect_width
, offset_width
;
688 psect_width
= ((unsigned) Psect_Index
> 255) ? 2 : 1;
689 offset_width
= (Force
|| Offset
> 32767 || Offset
< -32768) ? 4
690 : (Offset
> 127 || Offset
< -128) ? 2 : 1;
691 #define Sta_P(p,o) (((o)<<1) | ((p)-1))
692 /* byte or word psect; byte, word, or longword offset */
693 switch (Sta_P(psect_width
,offset_width
))
695 case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB
);
696 PUT_CHAR ((char)(unsigned char) Psect_Index
);
697 PUT_CHAR ((char) Offset
);
699 case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW
);
700 PUT_CHAR ((char)(unsigned char) Psect_Index
);
703 case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL
);
704 PUT_CHAR ((char)(unsigned char) Psect_Index
);
707 case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB
);
708 PUT_SHORT (Psect_Index
);
709 PUT_CHAR ((char) Offset
);
711 case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW
);
712 PUT_SHORT (Psect_Index
);
715 case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL
);
716 PUT_SHORT (Psect_Index
);
724 * Store immediate data in current Psect
727 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
)
735 * We are writing a "Record_Type" record
737 Set_VMS_Object_File_Record (Record_Type
);
739 * We can only store 128 bytes at a time
744 * Store a maximum of 128 bytes
746 i
= (Size
> 128) ? 128 : Size
;
749 * If we cannot accommodate this record, flush the
752 if ((Object_Record_Offset
+ i
+ 1) >= sizeof (Object_Record_Buffer
))
753 Flush_VMS_Object_Record_Buffer ();
755 * If the buffer is empty we must insert record type
757 if (Object_Record_Offset
== 0)
758 PUT_CHAR (Record_Type
);
762 PUT_CHAR (-i
& 0xff);
767 PUT_CHAR (*Pointer
++);
770 * Flush the buffer if it is more than 75% full.
772 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
773 Flush_VMS_Object_Record_Buffer ();
777 * Make a data reference
780 VMS_Set_Data (Psect_Index
, Offset
, Record_Type
, Force
)
787 * We are writing a "Record_Type" record
789 Set_VMS_Object_File_Record (Record_Type
);
791 * If the buffer is empty we must insert the record type
793 if (Object_Record_Offset
== 0)
794 PUT_CHAR (Record_Type
);
796 * Stack the Psect base with its offset
798 vms_tir_stack_psect (Psect_Index
, Offset
, Force
);
800 * Set relocation base
802 PUT_CHAR (TIR_S_C_STO_PIDR
);
804 * Flush the buffer if it is more than 75% full
806 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
807 Flush_VMS_Object_Record_Buffer ();
811 * Make a debugger reference to a struct, union or enum.
814 VMS_Store_Struct (Struct_Index
)
818 * We are writing a "OBJ_S_C_DBG" record
820 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
822 * If the buffer is empty we must insert the record type
824 if (Object_Record_Offset
== 0)
825 PUT_CHAR (OBJ_S_C_DBG
);
826 PUT_CHAR (TIR_S_C_STA_UW
);
827 PUT_SHORT (Struct_Index
);
828 PUT_CHAR (TIR_S_C_CTL_STKDL
);
829 PUT_CHAR (TIR_S_C_STO_L
);
831 * Flush the buffer if it is more than 75% full
833 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
834 Flush_VMS_Object_Record_Buffer ();
838 * Make a debugger reference to partially define a struct, union or enum.
841 VMS_Def_Struct (Struct_Index
)
845 * We are writing a "OBJ_S_C_DBG" record
847 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
849 * If the buffer is empty we must insert the record type
851 if (Object_Record_Offset
== 0)
852 PUT_CHAR (OBJ_S_C_DBG
);
853 PUT_CHAR (TIR_S_C_STA_UW
);
854 PUT_SHORT (Struct_Index
);
855 PUT_CHAR (TIR_S_C_CTL_DFLOC
);
857 * Flush the buffer if it is more than 75% full
859 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
860 Flush_VMS_Object_Record_Buffer ();
864 VMS_Set_Struct (Struct_Index
)
866 { /* see previous functions for comments */
867 Set_VMS_Object_File_Record (OBJ_S_C_DBG
);
868 if (Object_Record_Offset
== 0)
869 PUT_CHAR (OBJ_S_C_DBG
);
870 PUT_CHAR (TIR_S_C_STA_UW
);
871 PUT_SHORT (Struct_Index
);
872 PUT_CHAR (TIR_S_C_CTL_STLOC
);
873 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
874 Flush_VMS_Object_Record_Buffer ();
878 * Write the Traceback Module Begin record
881 VMS_TBT_Module_Begin ()
883 register char *cp
, *cp1
;
885 char Module_Name
[256];
889 * Get module name (the FILENAME part of the object file)
895 if ((*cp
== ']') || (*cp
== '>') ||
896 (*cp
== ':') || (*cp
== '/'))
902 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
906 * Limit it to 31 characters
908 while (--cp1
>= Module_Name
)
911 if (strlen (Module_Name
) > 31)
913 if (flag_hash_long_names
)
914 as_tsktsk ("Module name truncated: %s", Module_Name
);
918 * Arrange to store the data locally (leave room for size byte)
924 *cp
++ = DST_S_C_MODBEG
;
930 * Language type == "C"
932 COPY_LONG (cp
, DST_S_C_C
);
935 * Store the module name
937 *cp
++ = strlen (Module_Name
);
942 * Now we can store the record size
947 * Put it into the object record
949 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
954 * Write the Traceback Module End record
957 VMS_TBT_Module_End ()
965 Local
[1] = DST_S_C_MODEND
;
967 * Put it into the object record
969 VMS_Store_Immediate_Data (Local
, 2, OBJ_S_C_TBT
);
974 * Write the Traceback Routine Begin record
977 VMS_TBT_Routine_Begin (symbolP
, Psect
)
981 register char *cp
, *cp1
;
988 * Strip the leading "_" from the name
990 Name
= S_GET_NAME (symbolP
);
994 * Get the text psect offset
996 Offset
= S_GET_VALUE (symbolP
);
998 * Calculate the record size
1000 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1008 Local
[1] = DST_S_C_RTNBEG
;
1014 * Store the data so far
1016 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1018 * Make sure we are still generating a OBJ_S_C_TBT record
1020 if (Object_Record_Offset
== 0)
1021 PUT_CHAR (OBJ_S_C_TBT
);
1025 vms_tir_stack_psect (Psect
, Offset
, 0);
1027 * Store the data reference
1029 PUT_CHAR (TIR_S_C_STO_PIDR
);
1031 * Store the counted string as data
1035 Size
= strlen (cp1
) + 1;
1039 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_TBT
);
1044 * Write the Traceback Routine End record
1045 * We *must* search the symbol table to find the next routine, since
1046 * the assember has a way of reassembling the symbol table OUT OF ORDER
1047 * Thus the next routine in the symbol list is not necessarily the
1048 * next one in memory. For debugging to work correctly we must know the
1049 * size of the routine.
1052 VMS_TBT_Routine_End (Max_Size
, sp
)
1057 int Size
= 0x7fffffff;
1059 valueT sym_value
, sp_value
= S_GET_VALUE (sp
);
1061 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
1063 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
1065 if (*S_GET_NAME (symbolP
) == 'L')
1067 sym_value
= S_GET_VALUE (symbolP
);
1068 if (sym_value
> sp_value
&& sym_value
< Size
)
1072 * Dummy labels like "gcc_compiled." should no longer reach here.
1076 /* check if gcc_compiled. has size of zero */
1077 if (sym_value
== sp_value
&&
1079 (!strcmp (S_GET_NAME (sp
), "gcc_compiled.") ||
1080 !strcmp (S_GET_NAME (sp
), "gcc2_compiled.")))
1085 if (Size
== 0x7fffffff)
1087 Size
-= sp_value
; /* and get the size of the routine */
1095 Local
[1] = DST_S_C_RTNEND
;
1103 COPY_LONG (&Local
[3], Size
);
1107 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1111 * Write the Traceback Block End record
1114 VMS_TBT_Block_Begin (symbolP
, Psect
, Name
)
1119 register char *cp
, *cp1
;
1126 Size
= 1 + 1 + 4 + 1 + strlen (Name
);
1132 * Begin Block - We simulate with a phony routine
1134 Local
[1] = DST_S_C_BLKBEG
;
1140 * Store the data so far
1142 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_DBG
);
1144 * Make sure we are still generating a OBJ_S_C_DBG record
1146 if (Object_Record_Offset
== 0)
1147 PUT_CHAR (OBJ_S_C_DBG
);
1149 * Now get the symbol address
1151 PUT_CHAR (TIR_S_C_STA_WPL
);
1154 * Get the text psect offset
1156 Offset
= S_GET_VALUE (symbolP
);
1159 * Store the data reference
1161 PUT_CHAR (TIR_S_C_STO_PIDR
);
1163 * Store the counted string as data
1167 Size
= strlen (cp1
) + 1;
1171 VMS_Store_Immediate_Data (Local
, Size
, OBJ_S_C_DBG
);
1176 * Write the Traceback Block End record
1179 VMS_TBT_Block_End (Size
)
1185 * End block - simulate with a phony end routine
1188 Local
[1] = DST_S_C_BLKEND
;
1189 Local
[2] = 0; /* unused, must be zero */
1190 COPY_LONG (&Local
[3], Size
);
1191 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_DBG
);
1197 * Write a Line number / PC correlation record
1200 VMS_TBT_Line_PC_Correlation (Line_Number
, Offset
, Psect
, Do_Delta
)
1210 * If not delta, set our PC/Line number correlation
1217 Local
[0] = 1 + 1 + 2 + 1 + 4;
1219 * Line Number/PC correlation
1221 Local
[1] = DST_S_C_LINE_NUM
;
1225 Local
[2] = DST_S_C_SET_LINE_NUM
;
1226 COPY_SHORT (&Local
[3], Line_Number
- 1);
1230 Local
[5] = DST_S_C_SET_ABS_PC
;
1231 VMS_Store_Immediate_Data (Local
, 6, OBJ_S_C_TBT
);
1233 * Make sure we are still generating a OBJ_S_C_TBT record
1235 if (Object_Record_Offset
== 0)
1236 PUT_CHAR (OBJ_S_C_TBT
);
1237 vms_tir_stack_psect (Psect
, Offset
, 0);
1238 PUT_CHAR (TIR_S_C_STO_PIDR
);
1240 * Do a PC offset of 0 to register the line number
1243 Local
[1] = DST_S_C_LINE_NUM
;
1244 Local
[2] = 0; /* Increment PC by 0 and register line # */
1245 VMS_Store_Immediate_Data (Local
, 3, OBJ_S_C_TBT
);
1250 * If Delta is negative, terminate the line numbers
1254 Local
[0] = 1 + 1 + 4;
1255 Local
[1] = DST_S_C_LINE_NUM
;
1256 Local
[2] = DST_S_C_TERM_L
;
1257 COPY_LONG (&Local
[3], Offset
);
1258 VMS_Store_Immediate_Data (Local
, 7, OBJ_S_C_TBT
);
1265 * Do a PC/Line delta
1268 *cp
++ = DST_S_C_LINE_NUM
;
1269 if (Line_Number
> 1)
1272 * We need to increment the line number
1274 if (Line_Number
- 1 <= 255)
1276 *cp
++ = DST_S_C_INCR_LINUM
;
1277 *cp
++ = Line_Number
- 1;
1281 *cp
++ = DST_S_C_INCR_LINUM_W
;
1282 COPY_SHORT (cp
, Line_Number
- 1);
1295 if (Offset
< 0x10000)
1297 *cp
++ = DST_S_C_DELTA_PC_W
;
1298 COPY_SHORT (cp
, Offset
);
1303 *cp
++ = DST_S_C_DELTA_PC_L
;
1304 COPY_LONG (cp
, Offset
);
1308 Local
[0] = cp
- (Local
+ 1);
1309 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1315 * Describe a source file to the debugger
1318 VMS_TBT_Source_File (Filename
, ID_Number
)
1322 register char *cp
, *cp1
;
1325 #ifndef VMS /* Used for cross-assembly */
1326 i
= strlen (Filename
);
1328 static struct FAB Fab
;
1329 static struct NAM Nam
;
1330 static struct XABDAT Date_Xab
;
1331 static struct XABFHC File_Header_Xab
;
1332 char Es_String
[255], Rs_String
[255];
1337 Fab
.fab$b_bid
= FAB$C_BID
;
1338 Fab
.fab$b_bln
= sizeof (Fab
);
1339 Fab
.fab$l_nam
= (&Nam
);
1340 Fab
.fab$l_xab
= (char *) &Date_Xab
;
1342 * Setup the Nam block so we can find out the FULL name
1343 * of the source file.
1345 Nam
.nam$b_bid
= NAM$C_BID
;
1346 Nam
.nam$b_bln
= sizeof (Nam
);
1347 Nam
.nam$l_rsa
= Rs_String
;
1348 Nam
.nam$b_rss
= sizeof (Rs_String
);
1349 Nam
.nam$l_esa
= Es_String
;
1350 Nam
.nam$b_ess
= sizeof (Es_String
);
1352 * Setup the Date and File Header Xabs
1354 Date_Xab
.xab$b_cod
= XAB$C_DAT
;
1355 Date_Xab
.xab$b_bln
= sizeof (Date_Xab
);
1356 Date_Xab
.xab$l_nxt
= (char *) &File_Header_Xab
;
1357 File_Header_Xab
.xab$b_cod
= XAB$C_FHC
;
1358 File_Header_Xab
.xab$b_bln
= sizeof (File_Header_Xab
);
1360 * Get the file information
1362 Fab
.fab$l_fna
= Filename
;
1363 Fab
.fab$b_fns
= strlen (Filename
);
1364 Status
= sys$
open (&Fab
);
1367 as_tsktsk ("Couldn't find source file \"%s\", status=%%X%x",
1373 * Calculate the size of the resultant string
1380 Local
[0] = 1 + 1 + 1 + 1 + 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1382 * Source declaration
1384 Local
[1] = DST_S_C_SOURCE
;
1386 * Make formfeeds count as source records
1388 Local
[2] = DST_S_C_SRC_FORMFEED
;
1390 * Declare source file
1392 Local
[3] = DST_S_C_SRC_DECLFILE
;
1393 Local
[4] = 1 + 2 + 8 + 4 + 2 + 1 + 1 + i
+ 1;
1402 COPY_SHORT (cp
, ID_Number
);
1406 * Creation Date. Unknown, so we fill with zeroes.
1431 #else /* Use this code when assembling for VMS on a VMS system */
1435 memcpy (cp
, (char *) &Date_Xab
.xab$q_cdt
, 8);
1440 COPY_LONG (cp
, File_Header_Xab
.xab$l_ebk
);
1445 COPY_SHORT (cp
, File_Header_Xab
.xab$w_ffb
);
1450 *cp
++ = File_Header_Xab
.xab$b_rfo
;
1460 * Library module name (none)
1466 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1472 * Give the number of source lines to the debugger
1475 VMS_TBT_Source_Lines (ID_Number
, Starting_Line_Number
, Number_Of_Lines
)
1477 int Starting_Line_Number
;
1478 int Number_Of_Lines
;
1486 Local
[0] = 1 + 1 + 2 + 1 + 4 + 1 + 2;
1488 * Source declaration
1490 Local
[1] = DST_S_C_SOURCE
;
1495 *cp
++ = DST_S_C_SRC_SETFILE
;
1499 COPY_SHORT (cp
, ID_Number
);
1504 *cp
++ = DST_S_C_SRC_SETREC_L
;
1505 COPY_LONG (cp
, Starting_Line_Number
);
1510 *cp
++ = DST_S_C_SRC_DEFLINES_W
;
1511 COPY_SHORT (cp
, Number_Of_Lines
);
1516 VMS_Store_Immediate_Data (Local
, cp
- Local
, OBJ_S_C_TBT
);
1522 * This routine locates a file in the list of files. If an entry does not
1523 * exist, one is created. For include files, a new entry is always created
1524 * such that inline functions can be properly debugged.
1526 static struct input_file
*
1530 struct input_file
*same_file
= 0;
1531 struct input_file
*fpnt
, *last
= 0;
1534 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1536 if (fpnt
->spnt
== sp
)
1540 sp_name
= S_GET_NAME (sp
);
1541 for (fpnt
= file_root
; fpnt
; fpnt
= fpnt
->next
)
1543 if (strcmp (sp_name
, fpnt
->name
) == 0)
1545 if (fpnt
->flag
== 1)
1551 fpnt
= (struct input_file
*) xmalloc (sizeof (struct input_file
));
1557 fpnt
->name
= sp_name
;
1558 fpnt
->min_line
= 0x7fffffff;
1562 fpnt
->file_number
= 0;
1564 fpnt
->same_file_fpnt
= same_file
;
1569 * The following functions and definitions are used to generate object records
1570 * that will describe program variables to the VMS debugger.
1572 * This file contains many of the routines needed to output debugging info into
1573 * the object file that the VMS debugger needs to understand symbols. These
1574 * routines are called very late in the assembly process, and thus we can be
1575 * fairly lax about changing things, since the GSD and the TIR sections have
1576 * already been output.
1580 /* This routine converts a number string into an integer, and stops when it
1581 * sees an invalid character. The return value is the address of the character
1582 * just past the last character read. No error is generated.
1585 cvt_integer (str
, rtn
)
1590 neg
= *str
== '-' ? ++str
, -1 : 1;
1592 while ((*str
<= '9') && (*str
>= '0'))
1593 ival
= 10 * ival
+ *str
++ - '0';
1598 /* this routine fixes the names that are generated by C++, ".this" is a good
1599 * example. The period does not work for the debugger, since it looks like
1600 * the syntax for a structure element, and thus it gets mightily confused
1602 * We also use this to strip the PsectAttribute hack from the name before we
1603 * write a debugger record */
1611 * Kill any leading "_"
1616 * Is there a Psect Attribute to skip??
1618 if (HAS_PSECT_ATTRIBUTES (pnt
))
1623 pnt
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
1626 if ((pnt
[0] == '$') && (pnt
[1] == '$'))
1634 /* Here we fix the .this -> $this conversion */
1635 for (pnt1
= pnt
; *pnt1
!= 0; pnt1
++)
1643 /* When defining a structure, this routine is called to find the name of
1644 * the actual structure. It is assumed that str points to the equal sign
1645 * in the definition, and it moves backward until it finds the start of the
1646 * name. If it finds a 0, then it knows that this structure def is in the
1647 * outermost level, and thus symbol_name points to the symbol name.
1650 get_struct_name (str
)
1655 while ((*pnt
!= ':') && (*pnt
!= '\0'))
1658 return (char *) symbol_name
;
1660 while ((*pnt
!= ';') && (*pnt
!= '='))
1664 while ((*pnt
< '0') || (*pnt
> '9'))
1666 while ((*pnt
>= '0') && (*pnt
<= '9'))
1671 /* search symbol list for type number dbx_type. Return a pointer to struct */
1672 static struct VMS_DBG_Symbol
*
1673 find_symbol (dbx_type
)
1676 struct VMS_DBG_Symbol
*spnt
;
1678 spnt
= VMS_Symbol_type_list
[SYMTYP_HASH(dbx_type
)];
1679 while (spnt
!= (struct VMS_DBG_Symbol
*) NULL
)
1681 if (spnt
->dbx_type
== dbx_type
)
1685 if (!spnt
|| spnt
->advanced
!= ALIAS
)
1687 return find_symbol(spnt
->type2
);
1691 #if 0 /* obsolete */
1692 /* this routine puts info into either Local or Asuffix, depending on the sign
1693 * of size. The reason is that it is easier to build the variable descriptor
1694 * backwards, while the array descriptor is best built forwards. In the end
1695 * they get put together, if there is not a struct/union/enum along the way
1711 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size1
);
1715 if (Apoint
+ size1
>= MAX_DEBUG_RECORD
)
1718 Apoint
= MAX_DEBUG_RECORD
- 1;
1721 md_number_to_chars (&Asuffix
[Apoint
], value
, size1
);
1732 if (Apoint
+ size
>= MAX_DEBUG_RECORD
)
1735 Apoint
= MAX_DEBUG_RECORD
- 1;
1739 Asuffix
[Apoint
++] = (char) value
;
1742 md_number_to_chars (&Asuffix
[Apoint
], value
, size
);
1758 Local
[Lpnt
--] = (char) value
;
1762 md_number_to_chars (&Local
[Lpnt
+ 1], value
, size
);
1766 /* this routine generates the array descriptor for a given array */
1768 array_suffix (spnt2
)
1769 struct VMS_DBG_Symbol
*spnt2
;
1771 struct VMS_DBG_Symbol
*spnt
;
1772 struct VMS_DBG_Symbol
*spnt1
;
1778 while (spnt
->advanced
!= ARRAY
)
1780 spnt
= find_symbol (spnt
->type2
);
1781 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
1786 while (spnt1
->advanced
== ARRAY
)
1789 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+ 1);
1790 spnt1
= find_symbol (spnt1
->type2
);
1792 total_size
= total_size
* spnt1
->data_size
;
1793 fpush (spnt1
->data_size
, 2); /* element size */
1794 if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
1797 fpush (spnt1
->VMS_type
, 1); /* element type */
1798 fpush (DSC_K_CLASS_A
, 1); /* descriptor class */
1799 fpush (0, 4); /* base address */
1800 fpush (0, 1); /* scale factor -- not applicable */
1801 fpush (0, 1); /* digit count -- not applicable */
1802 fpush (0xc0, 1); /* flags: multiplier block & bounds present */
1803 fpush (rank
, 1); /* number of dimensions */
1804 fpush (total_size
, 4);
1805 fpush (0, 4); /* pointer to element [0][0]...[0] */
1807 while (spnt1
->advanced
== ARRAY
)
1809 fpush (spnt1
->index_max
- spnt1
->index_min
+ 1, 4);
1810 spnt1
= find_symbol (spnt1
->type2
);
1813 while (spnt1
->advanced
== ARRAY
)
1815 fpush (spnt1
->index_min
, 4);
1816 fpush (spnt1
->index_max
, 4);
1817 spnt1
= find_symbol (spnt1
->type2
);
1821 /* this routine generates the start of a variable descriptor based upon
1822 * a struct/union/enum that has yet to be defined. We define this spot as
1823 * a new location, and save four bytes for the address. When the struct is
1824 * finally defined, then we can go back and plug in the correct address.
1827 new_forward_ref (dbx_type
)
1830 struct forward_ref
*fpnt
;
1831 fpnt
= (struct forward_ref
*) xmalloc (sizeof (struct forward_ref
));
1832 fpnt
->next
= f_ref_root
;
1834 fpnt
->dbx_type
= dbx_type
;
1835 fpnt
->struc_numb
= ++structure_count
;
1836 fpnt
->resolved
= 'N';
1837 rpush (DST_K_TS_IND
, 1); /* indirect type specification */
1839 rpush (total_len
, 2);
1840 struct_number
= -fpnt
->struc_numb
;
1843 /* this routine generates the variable descriptor used to describe non-basic
1844 * variables. It calls itself recursively until it gets to the bottom of it
1845 * all, and then builds the descriptor backwards. It is easiest to do it this
1846 *way since we must periodically write length bytes, and it is easiest if we know
1847 *the value when it is time to write it.
1850 gen1 (spnt
, array_suffix_len
)
1851 struct VMS_DBG_Symbol
*spnt
;
1852 int array_suffix_len
;
1854 struct VMS_DBG_Symbol
*spnt1
;
1857 switch (spnt
->advanced
)
1860 rpush (DBG_S_C_VOID
, 1);
1862 rpush (total_len
, 2);
1866 if (array_suffix_len
== 0)
1868 rpush (spnt
->VMS_type
, 1);
1869 rpush (DBG_S_C_BASIC
, 1);
1871 rpush (total_len
, 2);
1875 rpush (DST_K_VFLAGS_DSC
, 1);
1876 rpush (DST_K_TS_DSC
, 1); /* descriptor type specification */
1882 struct_number
= spnt
->struc_numb
;
1883 if (struct_number
< 0)
1885 new_forward_ref (spnt
->dbx_type
);
1888 rpush (DBG_S_C_STRUCT
, 1);
1890 rpush (total_len
, 2);
1893 spnt1
= find_symbol (spnt
->type2
);
1896 new_forward_ref (spnt
->type2
);
1898 i
= gen1 (spnt1
, 0);
1900 { /* (*void) is a special case, do not put pointer suffix */
1901 rpush (DBG_S_C_POINTER
, 1);
1903 rpush (total_len
, 2);
1908 while (spnt1
->advanced
== ARRAY
)
1910 spnt1
= find_symbol (spnt1
->type2
);
1913 as_tsktsk ("debugger forward reference error, dbx type %d",
1918 /* It is too late to generate forward references, so the user gets a message.
1919 * This should only happen on a compiler error */
1920 (void) gen1 (spnt1
, 1);
1922 array_suffix (spnt
);
1923 array_suffix_len
= Apoint
- i
;
1924 switch (spnt1
->advanced
)
1932 rpush (total_len
, 2);
1933 rpush (DST_K_VFLAGS_DSC
, 1);
1934 rpush (1, 1); /* flags: element value spec included */
1935 rpush (1, 1); /* one dimension */
1936 rpush (DBG_S_C_COMPLEX_ARRAY
, 1);
1938 total_len
+= array_suffix_len
+ 8;
1939 rpush (total_len
, 2);
1941 default: /* lint suppression */
1947 /* This generates a suffix for a variable. If it is not a defined type yet,
1948 * then dbx_type contains the type we are expecting so we can generate a
1949 * forward reference. This calls gen1 to build most of the descriptor, and
1950 * then it puts the icing on at the end. It then dumps whatever is needed
1951 * to get a complete descriptor (i.e. struct reference, array suffix ).
1954 generate_suffix (spnt
, dbx_type
)
1955 struct VMS_DBG_Symbol
*spnt
;
1958 static const char pvoid
[6] = {
1959 5, /* record.length == 5 */
1960 DST_K_TYPSPEC
, /* record.type == 1 (type specification) */
1961 0, /* name.length == 0, no name follows */
1962 1, 0, /* type.length == 1 {2 bytes, little endian} */
1963 DBG_S_C_VOID
/* type.type == 5 (pointer to unspecified) */
1968 Lpnt
= MAX_DEBUG_RECORD
- 1;
1973 new_forward_ref (dbx_type
);
1976 if (spnt
->VMS_type
!= DBG_S_C_ADVANCED_TYPE
)
1977 return; /* no suffix needed */
1980 rpush (0, 1); /* no name (len==0) */
1981 rpush (DST_K_TYPSPEC
, 1);
1983 rpush (total_len
, 1);
1984 /* if the variable descriptor overflows the record, output a descriptor for
1985 * a pointer to void.
1987 if ((total_len
>= MAX_DEBUG_RECORD
) || overflow
)
1989 as_warn ("Variable descriptor %d too complicated. Defined as `void *'.",
1991 VMS_Store_Immediate_Data (pvoid
, 6, OBJ_S_C_DBG
);
1995 while (Lpnt
< MAX_DEBUG_RECORD
- 1)
1996 Local
[i
++] = Local
[++Lpnt
];
1998 /* we use this for a reference to a structure that has already been defined */
1999 if (struct_number
> 0)
2001 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2003 VMS_Store_Struct (struct_number
);
2005 /* We use this for a forward reference to a structure that has yet to be
2006 * defined. We store four bytes of zero to make room for the actual address
2009 if (struct_number
< 0)
2011 struct_number
= -struct_number
;
2012 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2014 VMS_Def_Struct (struct_number
);
2015 COPY_LONG(&Local
[Lpnt
], 0L);
2017 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2022 Local
[Lpnt
++] = Asuffix
[i
++];
2024 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2028 /* "novel length" type doesn't work for simple atomic types */
2029 #define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
2030 #undef SETUP_BASIC_TYPES
2033 bitfield_suffix (spnt
, width
)
2034 struct VMS_DBG_Symbol
*spnt
;
2037 Local
[Lpnt
++] = 13; /* rec.len==13 */
2038 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* a type specification record */
2039 Local
[Lpnt
++] = 0; /* not named */
2040 COPY_SHORT(&Local
[Lpnt
], 9); /* typ.len==9 */
2042 Local
[Lpnt
++] = DST_K_TS_NOV_LENG
; /* This type is a "novel length"
2043 incarnation of some other type. */
2044 COPY_LONG(&Local
[Lpnt
], width
); /* size in bits == novel length */
2046 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2048 /* assert( spnt->struc_numb > 0 ); */
2049 VMS_Store_Struct (spnt
->struc_numb
); /* output 4 more bytes */
2052 /* Formally define a builtin type, so that it can serve as the target of
2053 an indirect reference. It makes bitfield_suffix() easier by avoiding
2054 the need to use a forward reference for the first occurrence of each
2055 type used in a bitfield. */
2057 setup_basic_type (spnt
)
2058 struct VMS_DBG_Symbol
*spnt
;
2060 #ifdef SETUP_BASIC_TYPES
2061 /* This would be very useful if "novel length" fields actually worked
2062 with basic types like they do with enumerated types. However,
2063 they do not, so this isn't worth doing just so that you can use
2064 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
2066 #ifndef SETUP_SYNONYM_TYPES
2067 /* This determines whether compatible things like `int' and `long int'
2068 ought to have distinct type records rather than sharing one. */
2069 struct VMS_DBG_Symbol
*spnt2
;
2071 /* first check whether this type has already been seen by another name */
2072 for (spnt2
= VMS_Symbol_type_list
[SYMTYP_HASH(spnt
->VMS_type
)];
2074 spnt2
= spnt2
->next
)
2075 if (spnt2
!= spnt
&& spnt2
->VMS_type
== spnt
->VMS_type
)
2077 spnt
->struc_numb
= spnt2
->struc_numb
;
2082 /* `structure number' doesn't really mean `structure'; it means an index
2083 into a linker maintained set of saved locations which can be referenced
2085 spnt
->struc_numb
= ++structure_count
;
2086 VMS_Def_Struct (spnt
->struc_numb
); /* remember where this type lives */
2087 /* define the simple scalar type */
2088 Local
[Lpnt
++] = 6 + strlen (symbol_name
) + 2; /* rec.len */
2089 Local
[Lpnt
++] = DST_K_TYPSPEC
; /* rec.typ==type specification */
2090 Local
[Lpnt
++] = strlen (symbol_name
) + 2;
2091 Local
[Lpnt
++] = '_'; /* prefix name with "__" */
2092 Local
[Lpnt
++] = '_';
2093 for (p
= symbol_name
; *p
; p
++)
2094 Local
[Lpnt
++] = *p
== ' ' ? '_' : *p
;
2095 COPY_SHORT(&Local
[Lpnt
], 2); /* typ.len==2 */
2097 Local
[Lpnt
++] = DST_K_TS_ATOM
; /* typ.kind is simple type */
2098 Local
[Lpnt
++] = spnt
->VMS_type
; /* typ.type */
2099 VMS_Store_Immediate_Data (Local
, Lpnt
, OBJ_S_C_DBG
);
2101 #endif /* SETUP_BASIC_TYPES */
2105 /* This routine generates a symbol definition for a C symbol for the debugger.
2106 * It takes a psect and offset for global symbols; if psect < 0, then this is
2107 * a local variable and the offset is relative to FP. In this case it can
2108 * be either a variable (Offset < 0) or a parameter (Offset > 0).
2111 VMS_DBG_record (spnt
, Psect
, Offset
, Name
)
2112 struct VMS_DBG_Symbol
*spnt
;
2121 /* if there are bad characters in name, convert them */
2122 Name_pnt
= fix_name (Name
);
2124 len
= strlen(Name_pnt
);
2126 { /* this is a local variable, referenced to SP */
2127 Local
[i
++] = 7 + len
;
2128 Local
[i
++] = spnt
->VMS_type
;
2129 Local
[i
++] = (Offset
> 0) ? DBG_C_FUNCTION_PARAM
: DBG_C_LOCAL_SYM
;
2130 COPY_LONG (&Local
[i
], Offset
);
2135 Local
[i
++] = 7 + len
;
2136 Local
[i
++] = spnt
->VMS_type
;
2137 Local
[i
++] = DST_K_VALKIND_ADDR
;
2138 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2140 VMS_Set_Data (Psect
, Offset
, OBJ_S_C_DBG
, 0);
2143 while (*Name_pnt
!= '\0')
2144 Local
[i
++] = *Name_pnt
++;
2145 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2146 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2147 generate_suffix (spnt
, 0);
2151 /* This routine parses the stabs entries in order to make the definition
2152 * for the debugger of local symbols and function parameters
2155 VMS_local_stab_Parse (sp
)
2161 struct VMS_DBG_Symbol
*spnt
;
2165 str
= S_GET_NAME (sp
);
2166 pnt
= (char *) strchr (str
, ':');
2167 if (pnt
== (char *) NULL
)
2168 return; /* no colon present */
2169 pnt1
= pnt
++; /* save this for later, and skip colon */
2171 return; /* ignore static constants */
2173 /* there is one little catch that we must be aware of. Sometimes function
2174 * parameters are optimized into registers, and the compiler, in its infiite
2175 * wisdom outputs stabs records for *both*. In general we want to use the
2176 * register if it is present, so we must search the rest of the symbols for
2177 * this function to see if this parameter is assigned to a register.
2185 for (sp1
= symbol_next (sp
); sp1
; sp1
= symbol_next (sp1
))
2187 if (!S_IS_DEBUG (sp1
))
2189 if (S_GET_RAW_TYPE (sp1
) == N_FUN
)
2191 char * pnt3
=(char*) strchr (S_GET_NAME (sp1
), ':') + 1;
2192 if (*pnt3
== 'F' || *pnt3
== 'f') break;
2194 if (S_GET_RAW_TYPE (sp1
) != N_RSYM
)
2196 str1
= S_GET_NAME (sp1
); /* and get the name */
2198 while (*pnt2
!= ':')
2205 if ((*str1
!= ':') || (*pnt2
!= ':'))
2207 return; /* they are the same! lets skip this one */
2209 /* first find the dbx symbol type from list, and then find VMS type */
2210 pnt
++; /* skip p in case no register */
2213 pnt
= cvt_integer (pnt
, &dbx_type
);
2214 spnt
= find_symbol (dbx_type
);
2216 return; /*Dunno what this is*/
2218 VMS_DBG_record (spnt
, -1, S_GET_VALUE (sp
), str
);
2219 *pnt1
= ':'; /* and restore the string */
2223 /* This routine parses a stabs entry to find the information required to define
2224 * a variable. It is used for global and static variables.
2225 * Basically we need to know the address of the symbol. With older versions
2226 * of the compiler, const symbols are
2227 * treated differently, in that if they are global they are written into the
2228 * text psect. The global symbol entry for such a const is actually written
2229 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
2230 * of psects, we must search the entry points as well. static consts are even
2231 * harder, since they are never assigned a memory address. The compiler passes
2232 * a stab to tell us the value, but I am not sure what to do with it.
2236 VMS_stab_parse (sp
, expected_type
, type1
, type2
, Text_Psect
)
2238 int expected_type
; /* char */
2239 int type1
, type2
, Text_Psect
;
2245 struct VMS_DBG_Symbol
*spnt
;
2246 struct VMS_Symbol
*vsp
;
2250 str
= S_GET_NAME (sp
);
2251 pnt
= (char *) strchr (str
, ':');
2252 if (pnt
== (char *) NULL
)
2253 return; /* no colon present */
2254 pnt1
= pnt
; /* save this for later*/
2256 if (*pnt
== expected_type
)
2258 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2259 spnt
= find_symbol (dbx_type
);
2260 if (spnt
== (struct VMS_DBG_Symbol
*) NULL
)
2261 return; /*Dunno what this is*/
2262 /* now we need to search the symbol table to find the psect and offset for
2267 while (vsp
!= (struct VMS_Symbol
*) NULL
)
2269 pnt
= S_GET_NAME (vsp
->Symbol
);
2270 if (pnt
!= (char *) NULL
)
2272 /* make sure name is the same, and make sure correct symbol type */
2273 if ((strlen (pnt
) == strlen (str
)) && (strcmp (pnt
, str
) == 0)
2274 && ((S_GET_RAW_TYPE (vsp
->Symbol
) == type1
) ||
2275 (S_GET_RAW_TYPE (vsp
->Symbol
) == type2
)))
2279 if (vsp
!= (struct VMS_Symbol
*) NULL
)
2281 VMS_DBG_record (spnt
, vsp
->Psect_Index
, vsp
->Psect_Offset
, str
);
2282 *pnt1
= ':'; /* and restore the string */
2285 /* the symbol was not in the symbol list, but it may be an "entry point"
2286 if it was a constant */
2287 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
2290 * Dispatch on STAB type
2292 if (S_IS_DEBUG (sp1
) || (S_GET_TYPE (sp1
) != N_TEXT
))
2294 pnt
= S_GET_NAME (sp1
);
2297 if (strcmp (pnt
, str
) == 0)
2299 if (!gave_compiler_message
&& expected_type
== 'G')
2301 static const char long_const_msg
[] = "\
2302 ***Warning - the assembly code generated by the compiler has placed \n\
2303 global constant(s) in the text psect. These will not be available to \n\
2304 other modules, since this is not the correct way to handle this. You \n\
2305 have two options: 1) get a patched compiler that does not put global \n\
2306 constants in the text psect, or 2) remove the 'const' keyword from \n\
2307 definitions of global variables in your source module(s). Don't say \n\
2308 I didn't warn you! \n";
2310 as_tsktsk (long_const_msg
);
2311 gave_compiler_message
= 1;
2313 VMS_DBG_record (spnt
,
2318 *S_GET_NAME (sp1
) = 'L';
2319 /* fool assembler to not output this
2320 * as a routine in the TBT */
2325 *pnt1
= ':'; /* and restore the string */
2330 VMS_GSYM_Parse (sp
, Text_Psect
)
2333 { /* Global variables */
2334 VMS_stab_parse (sp
, 'G', (N_UNDF
| N_EXT
), (N_DATA
| N_EXT
), Text_Psect
);
2339 VMS_LCSYM_Parse (sp
, Text_Psect
)
2342 { /* Static symbols - uninitialized */
2343 VMS_stab_parse (sp
, 'S', N_BSS
, -1, Text_Psect
);
2347 VMS_STSYM_Parse (sp
, Text_Psect
)
2350 { /* Static symbols - initialized */
2351 VMS_stab_parse (sp
, 'S', N_DATA
, -1, Text_Psect
);
2355 /* for register symbols, we must figure out what range of addresses within the
2356 * psect are valid. We will use the brackets in the stab directives to give us
2357 * guidance as to the PC range that this variable is in scope. I am still not
2358 * completely comfortable with this but as I learn more, I seem to get a better
2359 * handle on what is going on.
2363 VMS_RSYM_Parse (sp
, Current_Routine
, Text_Psect
)
2364 symbolS
*sp
, *Current_Routine
;
2371 struct VMS_DBG_Symbol
*spnt
;
2375 int Min_Offset
= -1; /* min PC of validity */
2376 int Max_Offset
= 0; /* max PC of validity */
2379 for (symbolP
= sp
; symbolP
; symbolP
= symbol_next (symbolP
))
2382 * Dispatch on STAB type
2384 switch (S_GET_RAW_TYPE (symbolP
))
2388 Min_Offset
= S_GET_VALUE (symbolP
);
2392 Max_Offset
= S_GET_VALUE (symbolP
) - 1;
2395 if ((Min_Offset
!= -1) && (bcnt
== 0))
2397 if (S_GET_RAW_TYPE (symbolP
) == N_FUN
)
2399 pnt
=(char*) strchr (S_GET_NAME (symbolP
), ':') + 1;
2400 if (*pnt
== 'F' || *pnt
== 'f') break;
2404 /* Check to see that the addresses were defined. If not, then there were no
2405 * brackets in the function, and we must try to search for the next function.
2406 * Since functions can be in any order, we should search all of the symbol
2407 * list to find the correct ending address. */
2408 if (Min_Offset
== -1)
2410 int Max_Source_Offset
;
2412 Min_Offset
= S_GET_VALUE (sp
);
2413 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
2416 * Dispatch on STAB type
2418 switch (S_GET_RAW_TYPE (symbolP
))
2420 case N_TEXT
| N_EXT
:
2421 This_Offset
= S_GET_VALUE (symbolP
);
2422 if ((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
2423 Max_Offset
= This_Offset
;
2426 This_Offset
= S_GET_VALUE (symbolP
);
2427 if (This_Offset
> Max_Source_Offset
)
2428 Max_Source_Offset
= This_Offset
;
2432 /* if this is the last routine, then we use the PC of the last source line
2433 * as a marker of the max PC for which this reg is valid */
2434 if (Max_Offset
== 0x7fffffff)
2435 Max_Offset
= Max_Source_Offset
;
2438 str
= S_GET_NAME (sp
);
2439 pnt
= (char *) strchr (str
, ':');
2440 if (pnt
== (char *) NULL
)
2441 return; /* no colon present */
2442 pnt1
= pnt
; /* save this for later*/
2446 pnt
= cvt_integer (pnt
+ 1, &dbx_type
);
2447 spnt
= find_symbol (dbx_type
);
2449 return; /*Dunno what this is yet*/
2451 pnt
= fix_name (S_GET_NAME (sp
)); /* if there are bad characters in name, convert them */
2453 Local
[i
++] = 25 + len
;
2454 Local
[i
++] = spnt
->VMS_type
;
2455 Local
[i
++] = DST_K_VFLAGS_TVS
; /* trailing value specified */
2456 COPY_LONG(&Local
[i
], 1 + len
); /* relative offset, beyond name */
2458 Local
[i
++] = len
; /* name length (ascic prefix) */
2459 while (*pnt
!= '\0')
2460 Local
[i
++] = *pnt
++;
2461 Local
[i
++] = DST_K_VS_FOLLOWS
; /* value specification follows */
2462 COPY_SHORT(&Local
[i
], 15); /* length of rest of record */
2464 Local
[i
++] = DST_K_VS_ALLOC_SPLIT
; /* split lifetime */
2465 Local
[i
++] = 1; /* one binding follows */
2466 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2468 VMS_Set_Data (Text_Psect
, Min_Offset
, OBJ_S_C_DBG
, 1);
2469 VMS_Set_Data (Text_Psect
, Max_Offset
, OBJ_S_C_DBG
, 1);
2470 Local
[i
++] = DST_K_VALKIND_REG
; /* nested value spec */
2471 COPY_LONG(&Local
[i
], S_GET_VALUE (sp
));
2473 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2475 if (spnt
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2476 generate_suffix (spnt
, 0);
2479 /* this function examines a structure definition, checking all of the elements
2480 * to make sure that all of them are fully defined. The only thing that we
2481 * kick out are arrays of undefined structs, since we do not know how big
2482 * they are. All others we can handle with a normal forward reference.
2485 forward_reference (pnt
)
2489 struct VMS_DBG_Symbol
*spnt
;
2490 struct VMS_DBG_Symbol
*spnt1
;
2491 pnt
= cvt_integer (pnt
+ 1, &i
);
2493 return 0; /* no forward references */
2496 pnt
= (char *) strchr (pnt
, ':');
2497 pnt
= cvt_integer (pnt
+ 1, &i
);
2498 spnt
= find_symbol (i
);
2499 if(spnt
!= (struct VMS_DBG_Symbol
*) NULL
) {
2500 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
))
2503 spnt1
= find_symbol (spnt
->type2
);
2504 if ((spnt
->advanced
== ARRAY
) &&
2505 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))
2507 if (spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
2512 pnt
= cvt_integer (pnt
+ 1, &i
);
2513 pnt
= cvt_integer (pnt
+ 1, &i
);
2514 } while (*++pnt
!= ';');
2515 return 0; /* no forward refences found */
2518 /* Used to check a single element of a structure on the final pass*/
2521 final_forward_reference (spnt
)
2522 struct VMS_DBG_Symbol
*spnt
;
2524 struct VMS_DBG_Symbol
*spnt1
;
2526 while (spnt
&& (spnt
->advanced
== POINTER
|| spnt
->advanced
== ARRAY
))
2528 spnt1
= find_symbol(spnt
->type2
);
2529 if (spnt
->advanced
== ARRAY
&& !spnt1
) return 1;
2532 return 0; /* no forward refences found */
2535 /* This routine parses the stabs directives to find any definitions of dbx type
2536 * numbers. It makes a note of all of them, creating a structure element
2537 * of VMS_DBG_Symbol that describes it. This also generates the info for the
2538 * debugger that describes the struct/union/enum, so that further references
2539 * to these data types will be by number
2540 * We have to process pointers right away, since there can be references
2541 * to them later in the same stabs directive. We cannot have forward
2542 * references to pointers, (but we can have a forward reference to a pointer to
2543 * a structure/enum/union) and this is why we process them immediately.
2544 * After we process the pointer, then we search for defs that are nested even
2546 * 8/15/92: We have to process arrays right away too, because there can
2547 * be multiple references to identical array types in one structure
2548 * definition, and only the first one has the definition. (We tend to
2549 * parse from the back going forward.
2552 VMS_typedef_parse (str
)
2560 struct forward_ref
*fpnt
;
2561 int i1
, i2
, i3
, len
;
2562 struct VMS_DBG_Symbol
*spnt
;
2563 struct VMS_DBG_Symbol
*spnt1
;
2565 /* check for any nested def's */
2566 pnt
= (char *) strchr (str
+ 1, '=');
2567 if ((pnt
!= (char *) NULL
) && (*(str
+ 1) != '*')
2568 && (str
[1] != 'a' || str
[2] != 'r'))
2569 if (VMS_typedef_parse (pnt
) == 1)
2571 /* now find dbx_type of entry */
2574 { /* check for static constants */
2575 *str
= '\0'; /* for now we ignore them */
2578 while ((*pnt
<= '9') && (*pnt
>= '0'))
2580 pnt
++; /* and get back to the number */
2581 cvt_integer (pnt
, &i1
);
2582 spnt
= find_symbol (i1
);
2583 /* first we see if this has been defined already, due to a forward reference*/
2586 i2
= SYMTYP_HASH(i1
);
2587 spnt
= (struct VMS_DBG_Symbol
*) xmalloc (sizeof (struct VMS_DBG_Symbol
));
2588 spnt
->next
= VMS_Symbol_type_list
[i2
];
2589 VMS_Symbol_type_list
[i2
] = spnt
;
2590 spnt
->dbx_type
= i1
; /* and save the type */
2591 spnt
->type2
= spnt
->VMS_type
= spnt
->data_size
= 0;
2592 spnt
->index_min
= spnt
->index_max
= spnt
->struc_numb
= 0;
2594 /* for structs and unions, do a partial parse, otherwise we sometimes get
2595 * circular definitions that are impossible to resolve. We read enough info
2596 * so that any reference to this type has enough info to be resolved
2598 pnt
= str
+ 1; /* point to character past equal sign */
2599 if ((*pnt
== 'u') || (*pnt
== 's'))
2602 if ((*pnt
<= '9') && (*pnt
>= '0'))
2604 if (type_check ("void"))
2605 { /* this is the void symbol */
2607 spnt
->advanced
= VOID
;
2610 if (type_check ("unknown type"))
2613 spnt
->advanced
= UNKNOWN
;
2616 pnt1
= cvt_integer(pnt
,&i1
);
2617 if(i1
!= spnt
->dbx_type
)
2619 spnt
->advanced
= ALIAS
;
2624 as_tsktsk ("debugginer output: %d is an unknown untyped variable.",
2626 return 1; /* do not know what this is */
2628 /* now define this module*/
2629 pnt
= str
+ 1; /* point to character past equal sign */
2633 spnt
->advanced
= BASIC
;
2634 if (type_check ("int"))
2636 spnt
->VMS_type
= DBG_S_C_SLINT
;
2637 spnt
->data_size
= 4;
2639 else if (type_check ("long int"))
2641 spnt
->VMS_type
= DBG_S_C_SLINT
;
2642 spnt
->data_size
= 4;
2644 else if (type_check ("unsigned int"))
2646 spnt
->VMS_type
= DBG_S_C_ULINT
;
2647 spnt
->data_size
= 4;
2649 else if (type_check ("long unsigned int"))
2651 spnt
->VMS_type
= DBG_S_C_ULINT
;
2652 spnt
->data_size
= 4;
2654 else if (type_check ("short int"))
2656 spnt
->VMS_type
= DBG_S_C_SSINT
;
2657 spnt
->data_size
= 2;
2659 else if (type_check ("short unsigned int"))
2661 spnt
->VMS_type
= DBG_S_C_USINT
;
2662 spnt
->data_size
= 2;
2664 else if (type_check ("char"))
2666 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2667 spnt
->data_size
= 1;
2669 else if (type_check ("signed char"))
2671 spnt
->VMS_type
= DBG_S_C_SCHAR
;
2672 spnt
->data_size
= 1;
2674 else if (type_check ("unsigned char"))
2676 spnt
->VMS_type
= DBG_S_C_UCHAR
;
2677 spnt
->data_size
= 1;
2679 else if (type_check ("float"))
2681 spnt
->VMS_type
= DBG_S_C_REAL4
;
2682 spnt
->data_size
= 4;
2684 else if (type_check ("double"))
2686 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2687 spnt
->data_size
= 8;
2689 else if (type_check ("long double"))
2691 /* same as double, at least for now */
2692 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_REAL8_G
: DBG_S_C_REAL8
;
2693 spnt
->data_size
= 8;
2695 else if (type_check ("long long int"))
2697 spnt
->VMS_type
= DBG_S_C_SQUAD
; /* signed quadword */
2698 spnt
->data_size
= 8;
2700 else if (type_check ("long long unsigned int"))
2702 spnt
->VMS_type
= DBG_S_C_UQUAD
; /* unsigned quadword */
2703 spnt
->data_size
= 8;
2705 else if (type_check ("complex float"))
2707 spnt
->VMS_type
= DBG_S_C_COMPLX4
;
2708 spnt
->data_size
= 2 * 4;
2710 else if (type_check ("complex double"))
2712 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2713 spnt
->data_size
= 2 * 8;
2715 else if (type_check ("complex long double"))
2717 /* same as complex double, at least for now */
2718 spnt
->VMS_type
= vax_g_doubles
? DBG_S_C_COMPLX8_G
: DBG_S_C_COMPLX8
;
2719 spnt
->data_size
= 2 * 8;
2724 * Shouldn't get here, but if we do, something
2725 * more substantial ought to be done...
2728 spnt
->data_size
= 0;
2730 if (spnt
->VMS_type
!= 0)
2731 setup_basic_type(spnt
);
2732 pnt1
= (char *) strchr (str
, ';') + 1;
2736 spnt
->advanced
= (*pnt
== 's') ? STRUCT
: UNION
;
2737 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2738 pnt1
= cvt_integer (pnt
+ 1, &spnt
->data_size
);
2739 if (!final_pass
&& forward_reference(pnt
))
2741 spnt
->struc_numb
= -1;
2744 spnt
->struc_numb
= ++structure_count
;
2746 pnt
= get_struct_name (str
);
2747 VMS_Def_Struct (spnt
->struc_numb
);
2749 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2750 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2752 fpnt
->resolved
= 'Y';
2753 VMS_Set_Struct (fpnt
->struc_numb
);
2754 VMS_Store_Struct (spnt
->struc_numb
);
2758 VMS_Set_Struct (spnt
->struc_numb
);
2760 Local
[i
++] = 11 + strlen (pnt
);
2761 Local
[i
++] = DBG_S_C_STRUCT_START
;
2762 Local
[i
++] = DST_K_VFLAGS_NOVAL
; /* structure definition only */
2763 COPY_LONG(&Local
[i
], 0L); /* hence value is unused */
2765 Local
[i
++] = strlen (pnt
);
2767 while (*pnt2
!= '\0')
2768 Local
[i
++] = *pnt2
++;
2769 i2
= spnt
->data_size
* 8; /* number of bits */
2770 COPY_LONG(&Local
[i
], i2
);
2772 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2774 if (pnt
!= symbol_name
)
2776 pnt
+= strlen (pnt
);
2778 } /* replace colon for later */
2779 while (*++pnt1
!= ';')
2781 pnt
= (char *) strchr (pnt1
, ':');
2784 pnt1
= cvt_integer (pnt
+ 1, &dtype
);
2785 pnt1
= cvt_integer (pnt1
+ 1, &i2
);
2786 pnt1
= cvt_integer (pnt1
+ 1, &i3
);
2787 spnt1
= find_symbol (dtype
);
2788 len
= strlen (pnt2
);
2789 if (spnt1
&& (spnt1
->advanced
== BASIC
|| spnt1
->advanced
== ENUM
)
2790 && ((i3
!= spnt1
->data_size
* 8) || (i2
% 8 != 0)))
2792 if (USE_BITSTRING_DESCRIPTOR (spnt1
))
2794 /* This uses a type descriptor, which doesn't work if
2795 the enclosing structure has been placed in a register.
2796 Also, enum bitfields degenerate to simple integers. */
2797 int unsigned_type
= (spnt1
->VMS_type
== DBG_S_C_ULINT
2798 || spnt1
->VMS_type
== DBG_S_C_USINT
2799 || spnt1
->VMS_type
== DBG_S_C_UCHAR
2800 || spnt1
->VMS_type
== DBG_S_C_UQUAD
2801 || spnt1
->advanced
== ENUM
); /* (approximate) */
2803 fpush (19 + len
, 1);
2804 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2805 fpush (DST_K_VFLAGS_DSC
, 1); /* specified by descriptor */
2806 fpush (1 + len
, 4); /* relative offset to descriptor */
2807 fpush (len
, 1); /* length byte (ascic prefix) */
2808 while (*pnt2
!= '\0') /* name bytes */
2810 fpush (i3
, 2); /* dsc length == size of bitfield */
2811 /* dsc type == un?signed bitfield */
2812 fpush (unsigned_type
? DBG_S_C_UBITU
: DBG_S_C_SBITU
, 1);
2813 fpush (DSC_K_CLASS_UBS
, 1); /* dsc class == unaligned bitstring */
2814 fpush (0x00, 4); /* dsc pointer == zeroes */
2815 fpush (i2
, 4); /* start position */
2816 VMS_Store_Immediate_Data (Asuffix
, Apoint
, OBJ_S_C_DBG
);
2821 /* Use a "novel length" type specification, which works
2822 right for register structures and for enum bitfields
2823 but results in larger object modules. */
2824 Local
[i
++] = 7 + len
;
2825 Local
[i
++] = DBG_S_C_ADVANCED_TYPE
; /* type spec follows */
2826 Local
[i
++] = DBG_S_C_STRUCT_ITEM
; /* value is a bit offset */
2827 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2829 Local
[i
++] = strlen (pnt2
);
2830 while (*pnt2
!= '\0')
2831 Local
[i
++] = *pnt2
++;
2832 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2834 bitfield_suffix (spnt1
, i3
);
2838 { /* not a bitfield */
2839 /* check if this is a forward reference */
2840 if(final_pass
&& final_forward_reference(spnt1
))
2842 as_tsktsk ("debugger output: structure element `%s' has undefined type",
2846 Local
[i
++] = 7 + len
;
2847 Local
[i
++] = spnt1
? spnt1
->VMS_type
: DBG_S_C_ADVANCED_TYPE
;
2848 Local
[i
++] = DBG_S_C_STRUCT_ITEM
;
2849 COPY_LONG (&Local
[i
], i2
); /* bit offset */
2851 Local
[i
++] = strlen (pnt2
);
2852 while (*pnt2
!= '\0')
2853 Local
[i
++] = *pnt2
++;
2854 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2857 generate_suffix (spnt1
, dtype
);
2858 else if (spnt1
->VMS_type
== DBG_S_C_ADVANCED_TYPE
)
2859 generate_suffix (spnt1
, 0);
2863 Local
[i
++] = 0x01; /* length byte */
2864 Local
[i
++] = DBG_S_C_STRUCT_END
;
2865 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2869 spnt
->advanced
= ENUM
;
2870 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2871 spnt
->struc_numb
= ++structure_count
;
2872 spnt
->data_size
= 4;
2873 VMS_Def_Struct (spnt
->struc_numb
);
2875 for (fpnt
= f_ref_root
; fpnt
; fpnt
= fpnt
->next
)
2876 if (fpnt
->dbx_type
== spnt
->dbx_type
)
2878 fpnt
->resolved
= 'Y';
2879 VMS_Set_Struct (fpnt
->struc_numb
);
2880 VMS_Store_Struct (spnt
->struc_numb
);
2884 VMS_Set_Struct (spnt
->struc_numb
);
2886 len
= strlen (symbol_name
);
2887 Local
[i
++] = 3 + len
;
2888 Local
[i
++] = DBG_S_C_ENUM_START
;
2889 Local
[i
++] = 4 * 8; /* enum values are 32 bits */
2892 while (*pnt2
!= '\0')
2893 Local
[i
++] = *pnt2
++;
2894 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2896 while (*++pnt
!= ';')
2898 pnt1
= (char *) strchr (pnt
, ':');
2900 pnt1
= cvt_integer (pnt1
, &i1
);
2902 Local
[i
++] = 7 + len
;
2903 Local
[i
++] = DBG_S_C_ENUM_ITEM
;
2904 Local
[i
++] = DST_K_VALKIND_LITERAL
;
2905 COPY_LONG (&Local
[i
], i1
);
2909 while (*pnt
!= '\0')
2910 Local
[i
++] = *pnt
++;
2911 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2913 pnt
= pnt1
; /* Skip final semicolon */
2915 Local
[i
++] = 0x01; /* len byte */
2916 Local
[i
++] = DBG_S_C_ENUM_END
;
2917 VMS_Store_Immediate_Data (Local
, i
, OBJ_S_C_DBG
);
2922 spnt
->advanced
= ARRAY
;
2923 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2924 pnt
= (char *) strchr (pnt
, ';');
2927 pnt1
= cvt_integer (pnt
+ 1, &spnt
->index_min
);
2928 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->index_max
);
2929 pnt1
= cvt_integer (pnt1
+ 1, &spnt
->type2
);
2930 pnt
= (char *) strchr (str
+ 1, '=');
2931 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2935 spnt
->advanced
= FUNCTION
;
2936 spnt
->VMS_type
= DBG_S_C_FUNCTION_ADDR
;
2937 /* this masquerades as a basic type*/
2938 spnt
->data_size
= 4;
2939 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2942 spnt
->advanced
= POINTER
;
2943 spnt
->VMS_type
= DBG_S_C_ADVANCED_TYPE
;
2944 spnt
->data_size
= 4;
2945 pnt1
= cvt_integer (pnt
+ 1, &spnt
->type2
);
2946 pnt
= (char *) strchr (str
+ 1, '=');
2947 if (pnt
&& VMS_typedef_parse (pnt
) == 1)
2951 spnt
->advanced
= UNKNOWN
;
2953 as_tsktsk ("debugger output: %d is an unknown type of variable.",
2955 return 1; /* unable to decipher */
2957 /* this removes the evidence of the definition so that the outer levels of
2958 parsing do not have to worry about it */
2960 while (*pnt1
!= '\0')
2968 * This is the root routine that parses the stabs entries for definitions.
2969 * it calls VMS_typedef_parse, which can in turn call itself.
2970 * We need to be careful, since sometimes there are forward references to
2971 * other symbol types, and these cannot be resolved until we have completed
2974 * Also check and see if we are using continuation stabs, if we are, then
2975 * paste together the entire contents of the stab before we pass it to
2976 * VMS_typedef_parse.
2985 char *parse_buffer
= 0;
2987 int incomplete
, pass
, incom1
;
2988 struct forward_ref
*fpnt
;
2996 incom1
= incomplete
;
2998 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
3001 * Deal with STAB symbols
3003 if (S_IS_DEBUG (sp
))
3006 * Dispatch on STAB type
3008 switch (S_GET_RAW_TYPE (sp
))
3016 case N_FUN
: /*sometimes these contain typedefs*/
3017 str
= S_GET_NAME (sp
);
3019 pnt
= str
+ strlen(str
) -1;
3020 if (*pnt
== '?') /* Continuation stab. */
3027 tlen
+= strlen(str
) - 1;
3028 spnext
= symbol_next (spnext
);
3029 str
= S_GET_NAME (spnext
);
3030 pnt
= str
+ strlen(str
) - 1;
3031 } while (*pnt
== '?');
3032 tlen
+= strlen(str
);
3033 parse_buffer
= (char *) xmalloc (tlen
+ 1);
3034 strcpy(parse_buffer
, S_GET_NAME (sp
));
3035 pnt2
= parse_buffer
+ strlen(S_GET_NAME (sp
)) - 1;
3039 spnext
= symbol_next (spnext
);
3040 str
= S_GET_NAME (spnext
);
3041 strcat (pnt2
, S_GET_NAME (spnext
));
3042 pnt2
+= strlen(str
) - 1;
3043 *str
= '\0'; /* Erase this string */
3044 if (*pnt2
!= '?') break;
3050 pnt
= (char *) strchr (str
, ':');
3051 if (pnt
!= (char *) NULL
)
3055 pnt2
= (char *) strchr (pnt1
, '=');
3056 if (pnt2
!= (char *) NULL
)
3057 incomplete
+= VMS_typedef_parse (pnt2
);
3060 /* At this point the parse buffer should just
3061 contain name:nn. If it does not, then we
3062 are in real trouble. Anyway, this is always
3063 shorter than the original line. */
3064 strcpy (S_GET_NAME (sp
), parse_buffer
);
3065 free (parse_buffer
);
3068 *pnt
= ':'; /* put back colon to restore dbx_type */
3075 /* Make one last pass, if needed, and define whatever we can that is left */
3076 if(final_pass
== 0 && incomplete
== incom1
)
3079 incom1
++; /* Force one last pass through */
3081 } while ((incomplete
!= 0) && (incomplete
!= incom1
));
3082 /* repeat until all refs resolved if possible */
3083 /* if (pass > 1) printf(" Required %d passes\n",pass);*/
3084 if (incomplete
!= 0)
3086 as_tsktsk ("debugger output: Unable to resolve %d circular references.",
3091 while (fpnt
!= (struct forward_ref
*) NULL
)
3093 if (fpnt
->resolved
!= 'Y')
3095 if (find_symbol (fpnt
->dbx_type
) !=
3096 (struct VMS_DBG_Symbol
*) NULL
)
3098 as_tsktsk ("debugger forward reference error, dbx type %d",
3103 sprintf (&fixit
[1], "%d=s4;", fpnt
->dbx_type
);
3104 pnt2
= (char *) strchr (&fixit
[1], '=');
3105 VMS_typedef_parse (pnt2
);
3112 Define_Local_Symbols (s0P
, s2P
, Current_Routine
, Text_Psect
)
3114 symbolS
*Current_Routine
;
3117 symbolS
*s1P
; /* each symbol from s0P .. s2P (exclusive) */
3119 for (s1P
= symbol_next (s0P
); s1P
!= s2P
; s1P
= symbol_next (s1P
))
3122 break; /* and return */
3123 if (S_GET_RAW_TYPE (s1P
) == N_FUN
)
3125 char *pnt
= (char *) strchr (S_GET_NAME (s1P
), ':') + 1;
3126 if (*pnt
== 'F' || *pnt
== 'f') break;
3128 if (!S_IS_DEBUG (s1P
))
3131 * Dispatch on STAB type
3133 switch (S_GET_RAW_TYPE (s1P
))
3136 continue; /* not left or right brace */
3140 VMS_local_stab_Parse (s1P
);
3144 VMS_RSYM_Parse (s1P
, Current_Routine
, Text_Psect
);
3151 /* This function crawls the symbol chain searching for local symbols that need
3152 * to be described to the debugger. When we enter a new scope with a "{", it
3153 * creates a new "block", which helps the debugger keep track of which scope
3154 * we are currently in.
3158 Define_Routine (s0P
, Level
, Current_Routine
, Text_Psect
)
3161 symbolS
*Current_Routine
;
3168 for (s1P
= symbol_next (s0P
); s1P
!= 0; s1P
= symbol_next (s1P
))
3170 if (S_GET_RAW_TYPE (s1P
) == N_FUN
)
3172 char *pnt
= (char *) strchr (S_GET_NAME (s1P
), ':') + 1;
3173 if (*pnt
== 'F' || *pnt
== 'f') break;
3175 if (!S_IS_DEBUG (s1P
))
3178 * Dispatch on STAB type
3180 switch (S_GET_RAW_TYPE (s1P
))
3183 continue; /* not left or right brace */
3189 sprintf (str
, "$%d", rcount
++);
3190 VMS_TBT_Block_Begin (s1P
, Text_Psect
, str
);
3192 Offset
= S_GET_VALUE (s1P
); /* side-effect: fully resolve symbol */
3193 Define_Local_Symbols (s0P
, s1P
, Current_Routine
, Text_Psect
);
3194 s1P
= Define_Routine (s1P
, Level
+ 1, Current_Routine
, Text_Psect
);
3196 VMS_TBT_Block_End (S_GET_VALUE (s1P
) - Offset
);
3205 /* We end up here if there were no brackets in this function.
3206 Define everything. */
3207 Define_Local_Symbols (s0P
, (symbolS
*)0, Current_Routine
, Text_Psect
);
3213 #include <sys/types.h>
3215 static void get_VMS_time_on_unix
PARAMS ((char *));
3217 /* Manufacture a VMS-like time string on a Unix based system. */
3219 get_VMS_time_on_unix (Now
)
3226 pnt
= ctime (&timeb
);
3232 sprintf (Now
, "%2s-%3s-%s %s", pnt
+ 8, pnt
+ 4, pnt
+ 20, pnt
+ 11);
3234 #endif /* not VMS */
3237 * Write the MHD (Module Header) records
3240 Write_VMS_MHD_Records ()
3242 register const char *cp
;
3246 struct { unsigned short len
, mbz
; char *ptr
; } Descriptor
;
3248 char Module_Name
[255+1];
3252 * We are writing a module header record
3254 Set_VMS_Object_File_Record (OBJ_S_C_HDR
);
3256 * ***************************
3257 * *MAIN MODULE HEADER RECORD*
3258 * ***************************
3260 * Store record type and header type
3262 PUT_CHAR (OBJ_S_C_HDR
);
3263 PUT_CHAR (MHD_S_C_MHD
);
3265 * Structure level is 0
3267 PUT_CHAR (OBJ_S_C_STRLVL
);
3269 * Maximum record size is size of the object record buffer
3271 PUT_SHORT (sizeof (Object_Record_Buffer
));
3274 * FIXME: module name and version should be user
3275 * specifiable via `.ident' and/or `#pragma ident'.
3279 * Get module name (the FILENAME part of the object file)
3285 if ((*cp
== ']') || (*cp
== '>') ||
3286 (*cp
== ':') || (*cp
== '/'))
3292 *cp1
++ = islower (*cp
) ? toupper (*cp
++) : *cp
++;
3296 * Limit it to 31 characters and store in the object record
3298 while (--cp1
>= Module_Name
)
3301 if (strlen (Module_Name
) > 31)
3303 if (flag_hash_long_names
)
3304 as_tsktsk ("Module name truncated: %s\n", Module_Name
);
3305 Module_Name
[31] = 0;
3307 PUT_COUNTED_STRING (Module_Name
);
3309 * Module Version is "V1.0"
3311 PUT_COUNTED_STRING ("V1.0");
3313 * Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm".
3316 get_VMS_time_on_unix (Now
);
3318 Descriptor
.len
= sizeof Now
- 1;
3319 Descriptor
.mbz
= 0; /* type & class unspecified */
3320 Descriptor
.ptr
= Now
;
3321 (void) sys$
asctim ((unsigned short *)0, &Descriptor
, (long *)0, 0);
3323 for (i
= 0; i
< 17; i
++)
3326 * Patch time is "never" (17 zeros)
3328 for (i
= 0; i
< 17; i
++)
3333 Flush_VMS_Object_Record_Buffer ();
3335 * *************************
3336 * *LANGUAGE PROCESSOR NAME*
3337 * *************************
3339 * Store record type and header type
3341 PUT_CHAR (OBJ_S_C_HDR
);
3342 PUT_CHAR (MHD_S_C_LNM
);
3344 * Store language processor name and version
3345 * (not a counted string!)
3347 * This is normally supplied by the gcc driver for the command line
3348 * which invokes gas. If absent, we fall back to gas's version.
3350 cp
= compiler_version_string
;
3363 Flush_VMS_Object_Record_Buffer ();
3368 * Write the EOM (End Of Module) record
3371 Write_VMS_EOM_Record (Psect
, Offset
)
3376 * We are writing an end-of-module record
3377 * (this assumes that the entry point will always be in a psect
3378 * represented by a single byte, which is the case for code in
3381 Set_VMS_Object_File_Record (OBJ_S_C_EOM
);
3382 PUT_CHAR (OBJ_S_C_EOM
); /* Record type. */
3383 PUT_CHAR (0); /* Error severity level (we ignore it). */
3385 * Store the entry point, if it exists
3395 Flush_VMS_Object_Record_Buffer ();
3399 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3405 register const unsigned char *p
= (unsigned char *) ptr
;
3406 register const unsigned char *end
= p
+ strlen (ptr
);
3407 register unsigned char c
;
3408 register int hash
= 0;
3413 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
3419 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3422 VMS_Case_Hack_Symbol (In
, Out
)
3423 register const char *In
;
3430 const char *old_name
;
3432 int destructor
= 0; /*hack to allow for case sens in a destructor*/
3434 int Case_Hack_Bits
= 0;
3436 static char Hex_Table
[16] =
3437 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3440 * Kill any leading "_"
3442 if ((In
[0] == '_') && ((In
[1] > '9') || (In
[1] < '0')))
3445 new_name
= Out
; /* save this for later*/
3447 #if barfoo /* Dead code */
3448 if ((In
[0] == '_') && (In
[1] == '$') && (In
[2] == '_'))
3452 /* We may need to truncate the symbol, save the hash for later*/
3453 result
= (strlen (In
) > 23) ? hash_string (In
) : 0;
3455 * Is there a Psect Attribute to skip??
3457 if (HAS_PSECT_ATTRIBUTES (In
))
3462 In
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3465 if ((In
[0] == '$') && (In
[1] == '$'))
3475 /* if (strlen(In) > 31 && flag_hash_long_names)
3476 as_tsktsk("Symbol name truncated: %s\n", In); */
3478 * Do the case conversion
3480 i
= 23; /* Maximum of 23 chars */
3481 while (*In
&& (--i
>= 0))
3483 Case_Hack_Bits
<<= 1;
3486 if ((destructor
== 1) && (i
== 21))
3488 switch (vms_name_mapping
)
3493 Case_Hack_Bits
|= 1;
3495 *Out
++ = islower(*In
) ? toupper(*In
++) : *In
++;
3498 case 3: *Out
++ = *In
++;
3504 *Out
++ = isupper(*In
) ? tolower(*In
++) : *In
++;
3510 * If we saw a dollar sign, we don't do case hacking
3512 if (flag_no_hash_mixed_case
|| Saw_Dollar
)
3516 * If we have more than 23 characters and everything is lowercase
3517 * we can insert the full 31 characters
3522 * We have more than 23 characters
3523 * If we must add the case hack, then we have truncated the str
3527 if (Case_Hack_Bits
== 0)
3530 * And so far they are all lower case:
3531 * Check up to 8 more characters
3532 * and ensure that they are lowercase
3534 for (i
= 0; (In
[i
] != 0) && (i
< 8); i
++)
3535 if (isupper(In
[i
]) && !Saw_Dollar
&& !flag_no_hash_mixed_case
)
3541 if ((i
== 8) || (In
[i
] == 0))
3544 * They are: Copy up to 31 characters
3545 * to the output string
3548 while ((--i
>= 0) && (*In
))
3549 switch (vms_name_mapping
){
3550 case 0: *Out
++ = islower(*In
) ?
3554 case 3: *Out
++ = *In
++;
3556 case 2: *Out
++ = isupper(*In
) ?
3565 * If there were any uppercase characters in the name we
3566 * take on the case hacking string
3569 /* Old behavior for regular GNU-C compiler */
3570 if (!flag_hash_long_names
)
3572 if ((Case_Hack_Bits
!= 0) || (truncate
== 1))
3577 for (i
= 0; i
< 6; i
++)
3579 *Out
++ = Hex_Table
[Case_Hack_Bits
& 0xf];
3580 Case_Hack_Bits
>>= 4;
3586 Out
= pnt
; /*Cut back to 23 characters maximum */
3588 for (i
= 0; i
< 7; i
++)
3590 init
= result
& 0x01f;
3591 *Out
++ = (init
< 10) ? ('0' + init
) : ('A' + init
- 10);
3592 result
= result
>> 5;
3600 if (truncate
== 1 && flag_hash_long_names
&& flag_show_after_trunc
)
3601 as_tsktsk ("Symbol %s replaced by %s\n", old_name
, new_name
);
3606 * Scan a symbol name for a psect attribute specification
3608 #define GLOBALSYMBOL_BIT 0x10000
3609 #define GLOBALVALUE_BIT 0x20000
3613 VMS_Modify_Psect_Attributes (Name
, Attribute_Pointer
)
3615 int *Attribute_Pointer
;
3618 register const char *cp
;
3626 {"PIC", GPS_S_M_PIC
},
3627 {"LIB", GPS_S_M_LIB
},
3628 {"OVR", GPS_S_M_OVR
},
3629 {"REL", GPS_S_M_REL
},
3630 {"GBL", GPS_S_M_GBL
},
3631 {"SHR", GPS_S_M_SHR
},
3632 {"EXE", GPS_S_M_EXE
},
3634 {"WRT", GPS_S_M_WRT
},
3635 {"VEC", GPS_S_M_VEC
},
3636 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT
},
3637 {"GLOBALVALUE", GLOBALVALUE_BIT
},
3647 * Check for a PSECT attribute list
3649 if (!HAS_PSECT_ATTRIBUTES (Name
))
3650 return; /* If not, return */
3652 * Skip the attribute list indicator
3654 Name
+= PSECT_ATTRIBUTES_STRING_LENGTH
;
3656 * Process the attributes ("_" separated, "$" terminated)
3658 while (*Name
!= '$')
3661 * Assume not negating
3667 if ((Name
[0] == 'N') && (Name
[1] == 'O'))
3670 * We are negating (and skip the NO)
3676 * Find the token delimiter
3679 while (*cp
&& (*cp
!= '_') && (*cp
!= '$'))
3682 * Look for the token in the attribute list
3684 for (i
= 0; Attributes
[i
].Name
; i
++)
3687 * If the strings match, set/clear the attr.
3689 if (strncmp (Name
, Attributes
[i
].Name
, cp
- Name
) == 0)
3695 *Attribute_Pointer
&=
3696 ~Attributes
[i
].Value
;
3698 *Attribute_Pointer
|=
3699 Attributes
[i
].Value
;
3707 * Now skip the attribute
3716 #define GBLSYM_REF 0
3717 #define GBLSYM_DEF 1
3718 #define GBLSYM_VAL 2
3719 #define GBLSYM_LCL 4 /* not GBL after all... */
3722 * Define a global symbol (or possibly a local one).
3725 VMS_Global_Symbol_Spec (Name
, Psect_Number
, Psect_Offset
, Flags
)
3734 * We are writing a GSD record
3736 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3738 * If the buffer is empty we must insert the GSD record type
3740 if (Object_Record_Offset
== 0)
3741 PUT_CHAR (OBJ_S_C_GSD
);
3743 * We are writing a Global (or local) symbol definition subrecord.
3745 PUT_CHAR ((Flags
& GBLSYM_LCL
) != 0 ? GSD_S_C_LSY
:
3746 ((unsigned) Psect_Number
<= 255) ? GSD_S_C_SYM
: GSD_S_C_SYMW
);
3748 * Data type is undefined
3752 * Switch on Definition/Reference
3754 if ((Flags
& GBLSYM_DEF
) == 0)
3759 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ? GSY_S_M_REL
: 0);
3760 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3761 PUT_SHORT (Current_Environment
);
3767 *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
3769 PUT_SHORT (((Flags
& GBLSYM_VAL
) == 0) ?
3770 GSY_S_M_DEF
| GSY_S_M_REL
: GSY_S_M_DEF
);
3771 if ((Flags
& GBLSYM_LCL
) != 0) /* local symbols have extra field */
3772 PUT_SHORT (Current_Environment
);
3776 if ((Flags
& GBLSYM_LCL
) == 0 && (unsigned) Psect_Number
<= 255)
3777 PUT_CHAR (Psect_Number
);
3779 PUT_SHORT (Psect_Number
);
3783 PUT_LONG (Psect_Offset
);
3786 * Finally, the global symbol name
3788 VMS_Case_Hack_Symbol (Name
, Local
);
3789 PUT_COUNTED_STRING (Local
);
3791 * Flush the buffer if it is more than 75% full
3793 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3794 Flush_VMS_Object_Record_Buffer ();
3798 * Define an environment to support local symbol references.
3799 * This is just to mollify the linker; we don't actually do
3800 * anything useful with it.
3803 VMS_Local_Environment_Setup (Env_Name
)
3804 const char *Env_Name
;
3806 /* We are writing a GSD record. */
3807 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3808 /* If the buffer is empty we must insert the GSD record type. */
3809 if (Object_Record_Offset
== 0)
3810 PUT_CHAR (OBJ_S_C_GSD
);
3811 /* We are writing an ENV subrecord. */
3812 PUT_CHAR (GSD_S_C_ENV
);
3814 ++Current_Environment
; /* index of environment being defined */
3816 /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
3817 PUT_SHORT (ENV_S_M_DEF
);
3818 /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
3821 /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
3822 if (!Env_Name
) Env_Name
= "";
3823 PUT_COUNTED_STRING ((char *)Env_Name
);
3825 /* Flush the buffer if it is more than 75% full. */
3826 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3827 Flush_VMS_Object_Record_Buffer ();
3835 VMS_Psect_Spec (Name
, Size
, Type
, vsp
)
3839 struct VMS_Symbol
*vsp
;
3842 int Psect_Attributes
;
3845 * Generate the appropriate PSECT flags given the PSECT type
3847 if (strcmp (Type
, "COMMON") == 0)
3850 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT
3852 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3853 GPS_S_M_SHR
| GPS_S_M_RD
| GPS_S_M_WRT
);
3855 else if (strcmp (Type
, "CONST") == 0)
3858 * Common block psects are: PIC,OVR,REL,GBL,SHR,RD
3860 Psect_Attributes
= (GPS_S_M_PIC
| GPS_S_M_OVR
| GPS_S_M_REL
| GPS_S_M_GBL
|
3861 GPS_S_M_SHR
| GPS_S_M_RD
);
3863 else if (strcmp (Type
, "DATA") == 0)
3866 * The Data psects are PIC,REL,RD,WRT
3869 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_RD
| GPS_S_M_WRT
);
3871 else if (strcmp (Type
, "TEXT") == 0)
3874 * The Text psects are PIC,REL,SHR,EXE,RD
3877 (GPS_S_M_PIC
| GPS_S_M_REL
| GPS_S_M_SHR
|
3878 GPS_S_M_EXE
| GPS_S_M_RD
);
3883 * Error: Unknown psect type
3885 error ("Unknown VMS psect type");
3888 * Modify the psect attributes according to any attribute string
3890 if (vsp
&& S_GET_TYPE (vsp
->Symbol
) == N_ABS
)
3891 Psect_Attributes
|= GLOBALVALUE_BIT
;
3892 else if (HAS_PSECT_ATTRIBUTES (Name
))
3893 VMS_Modify_Psect_Attributes (Name
, &Psect_Attributes
);
3895 * Check for globalref/def/val.
3897 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
3900 * globalvalue symbols were generated before. This code
3901 * prevents unsightly psect buildup, and makes sure that
3902 * fixup references are emitted correctly.
3904 vsp
->Psect_Index
= -1; /* to catch errors */
3905 S_SET_TYPE (vsp
->Symbol
, N_UNDF
); /* make refs work */
3906 return 1; /* decrement psect counter */
3909 if ((Psect_Attributes
& GLOBALSYMBOL_BIT
) != 0)
3911 switch (S_GET_RAW_TYPE (vsp
->Symbol
))
3913 case N_UNDF
| N_EXT
:
3914 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3915 vsp
->Psect_Offset
, GBLSYM_REF
);
3916 vsp
->Psect_Index
= -1;
3917 S_SET_TYPE (vsp
->Symbol
, N_UNDF
);
3918 return 1; /* return and indicate no psect */
3919 case N_DATA
| N_EXT
:
3920 VMS_Global_Symbol_Spec (Name
, vsp
->Psect_Index
,
3921 vsp
->Psect_Offset
, GBLSYM_DEF
);
3922 /* In this case we still generate the psect */
3925 as_fatal ("Globalsymbol attribute for symbol %s was unexpected.",
3931 Psect_Attributes
&= 0xffff; /* clear out the globalref/def stuff */
3933 * We are writing a GSD record
3935 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
3937 * If the buffer is empty we must insert the GSD record type
3939 if (Object_Record_Offset
== 0)
3940 PUT_CHAR (OBJ_S_C_GSD
);
3942 * We are writing a PSECT definition subrecord
3944 PUT_CHAR (GSD_S_C_PSC
);
3946 * Psects are always LONGWORD aligned
3950 * Specify the psect attributes
3952 PUT_SHORT (Psect_Attributes
);
3954 * Specify the allocation
3958 * Finally, the psect name
3960 VMS_Case_Hack_Symbol (Name
, Local
);
3961 PUT_COUNTED_STRING (Local
);
3963 * Flush the buffer if it is more than 75% full
3965 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
3966 Flush_VMS_Object_Record_Buffer ();
3972 * Given the pointer to a symbol we calculate how big the data at the
3973 * symbol is. We do this by looking for the next symbol (local or
3974 * global) which will indicate the start of another datum.
3977 VMS_Initialized_Data_Size (sp
, End_Of_Data
)
3978 register symbolS
*sp
;
3981 symbolS
*sp1
, *Next_Symbol
;
3982 /* Cache values to avoid extra lookups. */
3983 valueT sp_val
= S_GET_VALUE (sp
), sp1_val
, next_val
= 0;
3986 * Find the next symbol
3987 * it delimits this datum
3990 for (sp1
= symbol_rootP
; sp1
; sp1
= symbol_next (sp1
))
3993 * The data type must match
3995 if (S_GET_TYPE (sp1
) != N_DATA
)
3998 sp1_val
= S_GET_VALUE (sp1
);
4001 * The symbol must be AFTER this symbol
4003 if (sp1_val
<= sp_val
)
4006 * We ignore THIS symbol
4011 * If there is already a candidate selected for the
4012 * next symbol, see if we are a better candidate
4017 * We are a better candidate if we are "closer"
4020 if (sp1_val
> next_val
)
4024 * Make this the candidate
4030 * Calculate its size
4032 return Next_Symbol
? (next_val
- sp_val
) : (End_Of_Data
- sp_val
);
4037 * Check symbol names for the Psect hack with a globalvalue, and then
4038 * generate globalvalues for those that have it.
4041 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
)
4046 register symbolS
*sp
;
4047 char *stripped_name
, *Name
;
4049 int Psect_Attributes
;
4054 * Scan the symbol table for globalvalues, and emit def/ref when
4055 * required. These will be caught again later and converted to
4058 for (sp
= symbol_rootP
; sp
; sp
= sp
->sy_next
)
4060 typ
= S_GET_RAW_TYPE (sp
);
4061 abstyp
= ((typ
& ~N_EXT
) == N_ABS
);
4063 * See if this is something we want to look at.
4066 typ
!= (N_DATA
| N_EXT
) &&
4067 typ
!= (N_UNDF
| N_EXT
))
4070 * See if this has globalvalue specification.
4072 Name
= S_GET_NAME (sp
);
4077 Psect_Attributes
= GLOBALVALUE_BIT
;
4079 else if (HAS_PSECT_ATTRIBUTES (Name
))
4081 stripped_name
= (char *) xmalloc (strlen (Name
) + 1);
4082 strcpy (stripped_name
, Name
);
4083 Psect_Attributes
= 0;
4084 VMS_Modify_Psect_Attributes (stripped_name
, &Psect_Attributes
);
4089 if ((Psect_Attributes
& GLOBALVALUE_BIT
) != 0)
4094 /* Local symbol references will want
4095 to have an environment defined. */
4096 if (Current_Environment
< 0)
4097 VMS_Local_Environment_Setup (".N_ABS");
4098 VMS_Global_Symbol_Spec (Name
, 0,
4100 GBLSYM_DEF
|GBLSYM_VAL
|GBLSYM_LCL
);
4103 VMS_Global_Symbol_Spec (Name
, 0,
4105 GBLSYM_DEF
|GBLSYM_VAL
);
4107 case N_UNDF
| N_EXT
:
4108 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
4110 case N_DATA
| N_EXT
:
4111 Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
4113 error ("Invalid data type for globalvalue");
4114 globalvalue
= md_chars_to_number (Data_Segment
+
4115 S_GET_VALUE (sp
) - text_siz
, Size
);
4116 /* Three times for good luck. The linker seems to get confused
4117 if there are fewer than three */
4118 VMS_Global_Symbol_Spec (stripped_name
, 0, 0, GBLSYM_VAL
);
4119 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
4120 GBLSYM_DEF
|GBLSYM_VAL
);
4121 VMS_Global_Symbol_Spec (stripped_name
, 0, globalvalue
,
4122 GBLSYM_DEF
|GBLSYM_VAL
);
4125 as_warn ("Invalid globalvalue of %s", stripped_name
);
4129 if (stripped_name
) free (stripped_name
); /* clean up */
4136 * Define a procedure entry pt/mask
4139 VMS_Procedure_Entry_Pt (Name
, Psect_Number
, Psect_Offset
, Entry_Mask
)
4148 * We are writing a GSD record
4150 Set_VMS_Object_File_Record (OBJ_S_C_GSD
);
4152 * If the buffer is empty we must insert the GSD record type
4154 if (Object_Record_Offset
== 0)
4155 PUT_CHAR (OBJ_S_C_GSD
);
4157 * We are writing a Procedure Entry Pt/Mask subrecord
4159 PUT_CHAR (((unsigned) Psect_Number
<= 255) ? GSD_S_C_EPM
: GSD_S_C_EPMW
);
4161 * Data type is undefined
4165 * Flags = "RELOCATABLE" and "DEFINED"
4167 PUT_SHORT (GSY_S_M_DEF
| GSY_S_M_REL
);
4171 if ((unsigned) Psect_Number
<= 255)
4172 PUT_CHAR (Psect_Number
);
4174 PUT_SHORT (Psect_Number
);
4178 PUT_LONG (Psect_Offset
);
4182 PUT_SHORT (Entry_Mask
);
4184 * Finally, the global symbol name
4186 VMS_Case_Hack_Symbol (Name
, Local
);
4187 PUT_COUNTED_STRING (Local
);
4189 * Flush the buffer if it is more than 75% full
4191 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4192 Flush_VMS_Object_Record_Buffer ();
4197 * Set the current location counter to a particular Psect and Offset
4200 VMS_Set_Psect (Psect_Index
, Offset
, Record_Type
)
4206 * We are writing a "Record_Type" record
4208 Set_VMS_Object_File_Record (Record_Type
);
4210 * If the buffer is empty we must insert the record type
4212 if (Object_Record_Offset
== 0)
4213 PUT_CHAR (Record_Type
);
4215 * Stack the Psect base + Offset
4217 vms_tir_stack_psect (Psect_Index
, Offset
, 0);
4219 * Set relocation base
4221 PUT_CHAR (TIR_S_C_CTL_SETRB
);
4223 * Flush the buffer if it is more than 75% full
4225 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4226 Flush_VMS_Object_Record_Buffer ();
4231 * Store repeated immediate data in current Psect
4234 VMS_Store_Repeated_Data (Repeat_Count
, Pointer
, Size
, Record_Type
)
4236 register char *Pointer
;
4242 * Ignore zero bytes/words/longwords
4247 if (Pointer
[3] != 0 || Pointer
[2] != 0) break;
4250 if (Pointer
[1] != 0) break;
4253 if (Pointer
[0] != 0) break;
4260 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4261 * then we do it manually
4265 while (--Repeat_Count
>= 0)
4266 VMS_Store_Immediate_Data (Pointer
, Size
, Record_Type
);
4270 * We are writing a "Record_Type" record
4272 Set_VMS_Object_File_Record (Record_Type
);
4274 * If the buffer is empty we must insert record type
4276 if (Object_Record_Offset
== 0)
4277 PUT_CHAR (Record_Type
);
4279 * Stack the repeat count
4281 PUT_CHAR (TIR_S_C_STA_LW
);
4282 PUT_LONG (Repeat_Count
);
4284 * And now the command and its data
4286 PUT_CHAR (TIR_S_C_STO_RIVB
);
4289 PUT_CHAR (*Pointer
++);
4291 * Flush the buffer if it is more than 75% full
4293 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4294 Flush_VMS_Object_Record_Buffer ();
4299 * Store a Position Independent Reference
4302 VMS_Store_PIC_Symbol_Reference (Symbol
, Offset
, PC_Relative
,
4303 Psect
, Psect_Offset
, Record_Type
)
4311 register struct VMS_Symbol
*vsp
= Symbol
->sy_obj
;
4316 * We are writing a "Record_Type" record
4318 Set_VMS_Object_File_Record (Record_Type
);
4320 * If the buffer is empty we must insert record type
4322 if (Object_Record_Offset
== 0)
4323 PUT_CHAR (Record_Type
);
4325 * Set to the appropriate offset in the Psect.
4326 * For a Code reference we need to fix the operand
4327 * specifier as well, so back up 1 byte;
4328 * for a Data reference we just store HERE.
4330 VMS_Set_Psect (Psect
,
4331 PC_Relative
? Psect_Offset
- 1 : Psect_Offset
,
4334 * Make sure we are still generating a "Record Type" record
4336 if (Object_Record_Offset
== 0)
4337 PUT_CHAR (Record_Type
);
4339 * Dispatch on symbol type (so we can stack its value)
4341 switch (S_GET_RAW_TYPE (Symbol
))
4350 #ifdef NOT_VAX_11_C_COMPATIBLE
4351 case N_UNDF
| N_EXT
:
4352 case N_DATA
| N_EXT
:
4353 #endif /* NOT_VAX_11_C_COMPATIBLE */
4355 case N_TEXT
| N_EXT
:
4357 * Get the symbol name (case hacked)
4359 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol
), Local
);
4361 * Stack the global symbol value
4365 PUT_CHAR (TIR_S_C_STA_GBL
);
4369 /* Local symbols have an extra field. */
4370 PUT_CHAR (TIR_S_C_STA_LSY
);
4371 PUT_SHORT (Current_Environment
);
4373 PUT_COUNTED_STRING (Local
);
4377 * Stack the longword offset
4379 PUT_CHAR (TIR_S_C_STA_LW
);
4382 * Add the two, leaving the result on the stack
4384 PUT_CHAR (TIR_S_C_OPR_ADD
);
4388 * Uninitialized local data
4392 * Stack the Psect (+offset)
4394 vms_tir_stack_psect (vsp
->Psect_Index
,
4395 vsp
->Psect_Offset
+ Offset
,
4403 * Stack the Psect (+offset)
4405 vms_tir_stack_psect (vsp
->Psect_Index
,
4406 S_GET_VALUE (Symbol
) + Offset
,
4410 * Initialized local or global data
4413 #ifndef NOT_VAX_11_C_COMPATIBLE
4414 case N_UNDF
| N_EXT
:
4415 case N_DATA
| N_EXT
:
4416 #endif /* NOT_VAX_11_C_COMPATIBLE */
4418 * Stack the Psect (+offset)
4420 vms_tir_stack_psect (vsp
->Psect_Index
,
4421 vsp
->Psect_Offset
+ Offset
,
4426 * Store either a code or data reference
4428 PUT_CHAR (PC_Relative
? TIR_S_C_STO_PICR
: TIR_S_C_STO_PIDR
);
4430 * Flush the buffer if it is more than 75% full
4432 if (Object_Record_Offset
> (sizeof (Object_Record_Buffer
) * 3 / 4))
4433 Flush_VMS_Object_Record_Buffer ();
4438 * Check in the text area for an indirect pc-relative reference
4439 * and fix it up with addressing mode 0xff [PC indirect]
4441 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4442 * PIC CODE GENERATING FIXUP ROUTINE.
4445 VMS_Fix_Indirect_Reference (Text_Psect
, Offset
, fragP
, text_frag_root
)
4448 register fragS
*fragP
;
4449 fragS
*text_frag_root
;
4452 * The addressing mode byte is 1 byte before the address
4456 * Is it in THIS frag??
4458 if ((Offset
< fragP
->fr_address
) ||
4459 (Offset
>= (fragP
->fr_address
+ fragP
->fr_fix
)))
4462 * We need to search for the fragment containing this
4465 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4467 if ((Offset
>= fragP
->fr_address
) &&
4468 (Offset
< (fragP
->fr_address
+ fragP
->fr_fix
)))
4472 * If we couldn't find the frag, things are BAD!!
4475 error ("Couldn't find fixup fragment when checking for indirect reference");
4478 * Check for indirect PC relative addressing mode
4480 if (fragP
->fr_literal
[Offset
- fragP
->fr_address
] == (char) 0xff)
4482 static char Address_Mode
= (char) 0xff;
4485 * Yes: Store the indirect mode back into the image
4486 * to fix up the damage done by STO_PICR
4488 VMS_Set_Psect (Text_Psect
, Offset
, OBJ_S_C_TIR
);
4489 VMS_Store_Immediate_Data (&Address_Mode
, 1, OBJ_S_C_TIR
);
4495 * If the procedure "main()" exists we have to add the instruction
4496 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4498 * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed
4499 * to `HACK_VAXCRTL_STARTUP' because Digital's compiler
4500 * named "DEC C" uses run-time library "DECC$SHR", but this
4501 * startup code is for "VAXCRTL", the library for Digital's
4502 * older "VAX C". Also, this extra code isn't needed for
4503 * supporting gcc because it already generates the VAXCRTL
4504 * startup call when compiling main(). The reference to
4505 * `flag_hash_long_names' looks very suspicious too;
4506 * probably an old-style command line option was inadvertently
4507 * overloaded here, then blindly converted into the new one.
4510 vms_check_for_main ()
4512 register symbolS
*symbolP
;
4513 #ifdef HACK_DEC_C_STARTUP /* JF */
4514 register struct frchain
*frchainP
;
4515 register fragS
*fragP
;
4516 register fragS
**prev_fragPP
;
4517 register struct fix
*fixP
;
4518 register fragS
*New_Frag
;
4520 #endif /* HACK_DEC_C_STARTUP */
4522 symbolP
= (symbolS
*) symbol_find ("_main");
4523 if (symbolP
&& !S_IS_DEBUG (symbolP
) &&
4524 S_IS_EXTERNAL (symbolP
) && (S_GET_TYPE (symbolP
) == N_TEXT
))
4526 #ifdef HACK_DEC_C_STARTUP
4527 if (!flag_hash_long_names
)
4531 * Remember the entry point symbol
4533 Entry_Point_Symbol
= symbolP
;
4534 #ifdef HACK_DEC_C_STARTUP
4539 * Scan all the fragment chains for the one with "_main"
4540 * (Actually we know the fragment from the symbol, but we need
4541 * the previous fragment so we can change its pointer)
4543 frchainP
= frchain_root
;
4547 * Scan all the fragments in this chain, remembering
4548 * the "previous fragment"
4550 prev_fragPP
= &frchainP
->frch_root
;
4551 fragP
= frchainP
->frch_root
;
4552 while (fragP
&& (fragP
!= frchainP
->frch_last
))
4555 * Is this the fragment?
4557 if (fragP
== symbolP
->sy_frag
)
4560 * Yes: Modify the fragment by replacing
4561 * it with a new fragment.
4563 New_Frag
= (fragS
*)
4564 xmalloc (sizeof (*New_Frag
) +
4569 * The fragments are the same except
4570 * that the "fixed" area is larger
4573 New_Frag
->fr_fix
+= 6;
4575 * Copy the literal data opening a hole
4576 * 2 bytes after "_main" (i.e. just after
4577 * the entry mask). Into which we place
4578 * the JSB instruction.
4580 New_Frag
->fr_literal
[0] = fragP
->fr_literal
[0];
4581 New_Frag
->fr_literal
[1] = fragP
->fr_literal
[1];
4582 New_Frag
->fr_literal
[2] = 0x16; /* Jsb */
4583 New_Frag
->fr_literal
[3] = 0xef;
4584 New_Frag
->fr_literal
[4] = 0;
4585 New_Frag
->fr_literal
[5] = 0;
4586 New_Frag
->fr_literal
[6] = 0;
4587 New_Frag
->fr_literal
[7] = 0;
4588 for (i
= 2; i
< fragP
->fr_fix
+ fragP
->fr_var
; i
++)
4589 New_Frag
->fr_literal
[i
+ 6] =
4590 fragP
->fr_literal
[i
];
4592 * Now replace the old fragment with the
4593 * newly generated one.
4595 *prev_fragPP
= New_Frag
;
4597 * Remember the entry point symbol
4599 Entry_Point_Symbol
= symbolP
;
4601 * Scan the text area fixup structures
4602 * as offsets in the fragment may have
4605 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4608 * Look for references to this
4611 if (fixP
->fx_frag
== fragP
)
4614 * Change the fragment
4617 fixP
->fx_frag
= New_Frag
;
4619 * If the offset is after
4620 * the entry mask we need
4621 * to account for the JSB
4622 * instruction we just
4625 if (fixP
->fx_where
>= 2)
4626 fixP
->fx_where
+= 6;
4630 * Scan the symbols as offsets in the
4631 * fragment may have changed
4633 for (symbolP
= symbol_rootP
;
4635 symbolP
= symbol_next (symbolP
))
4638 * Look for references to this
4641 if (symbolP
->sy_frag
== fragP
)
4644 * Change the fragment
4647 symbolP
->sy_frag
= New_Frag
;
4649 * If the offset is after
4650 * the entry mask we need
4651 * to account for the JSB
4652 * instruction we just
4655 if (S_GET_VALUE (symbolP
) >= 2)
4656 S_SET_VALUE (symbolP
,
4657 S_GET_VALUE (symbolP
) + 6);
4661 * Make a symbol reference to
4662 * "_c$main_args" so we can get
4663 * its address inserted into the
4666 symbolP
= (symbolS
*) xmalloc (sizeof (*symbolP
));
4667 S_SET_NAME (symbolP
, "_C$MAIN_ARGS");
4668 S_SET_TYPE (symbolP
, N_UNDF
);
4669 S_SET_OTHER (symbolP
, 0);
4670 S_SET_DESC (symbolP
, 0);
4671 S_SET_VALUE (symbolP
, 0);
4672 symbolP
->sy_name_offset
= 0;
4673 symbolP
->sy_number
= 0;
4674 symbolP
->sy_obj
= 0;
4675 symbolP
->sy_frag
= New_Frag
;
4676 symbolP
->sy_resolved
= 0;
4677 symbolP
->sy_resolving
= 0;
4678 /* this actually inserts at the beginning of the list */
4679 symbol_append (symbol_rootP
, symbolP
,
4680 &symbol_rootP
, &symbol_lastP
);
4682 symbol_rootP
= symbolP
;
4684 * Generate a text fixup structure
4685 * to get "_c$main_args" stored into the
4688 fixP
= (struct fix
*) xmalloc (sizeof (*fixP
));
4689 fixP
->fx_frag
= New_Frag
;
4691 fixP
->fx_addsy
= symbolP
;
4693 fixP
->fx_offset
= 0;
4696 fixP
->fx_next
= text_fix_root
;
4697 text_fix_root
= fixP
;
4699 * Now make sure we exit from the loop
4705 * Try the next fragment
4707 prev_fragPP
= &fragP
->fr_next
;
4708 fragP
= fragP
->fr_next
;
4711 * Try the next fragment chain
4714 frchainP
= frchainP
->frch_next
;
4717 #endif /* HACK_DEC_C_STARTUP */
4723 * Beginning of vms_write_object_file().
4727 struct vms_obj_state
{
4729 /* Next program section index to use. */
4732 /* Psect index for code. Always ends up #0. */
4735 /* Psect index for initialized static variables. */
4738 /* Psect index for uninitialized static variables. */
4741 /* Number of bytes used for local symbol data. */
4742 int local_initd_data_size
;
4744 /* Dynamic buffer for initialized data. */
4749 #define Psect_Number vms_obj_state.psect_number
4750 #define Text_Psect vms_obj_state.text_psect
4751 #define Data_Psect vms_obj_state.data_psect
4752 #define Bss_Psect vms_obj_state.bss_psect
4753 #define Local_Initd_Data_Size vms_obj_state.local_initd_data_size
4754 #define Data_Segment vms_obj_state.data_segment
4757 #define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
4761 * Perform text segment fixups.
4764 vms_fixup_text_section (text_siz
, text_frag_root
, data_frag_root
)
4766 struct frag
*text_frag_root
;
4767 struct frag
*data_frag_root
;
4769 register fragS
*fragP
;
4770 register struct fix
*fixP
;
4773 /* Scan the text fragments. */
4774 for (fragP
= text_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4776 /* Stop if we get to the data fragments. */
4777 if (fragP
== data_frag_root
)
4779 /* Ignore fragments with no data. */
4780 if ((fragP
->fr_fix
== 0) && (fragP
->fr_var
== 0))
4782 /* Go the the appropriate offset in the Text Psect. */
4783 VMS_Set_Psect (Text_Psect
, fragP
->fr_address
, OBJ_S_C_TIR
);
4784 /* Store the "fixed" part. */
4786 VMS_Store_Immediate_Data (fragP
->fr_literal
,
4789 /* Store the "variable" part. */
4790 if (fragP
->fr_var
&& fragP
->fr_offset
)
4791 VMS_Store_Repeated_Data (fragP
->fr_offset
,
4792 fragP
->fr_literal
+ fragP
->fr_fix
,
4795 } /* text frag loop */
4798 * Now we go through the text segment fixups and generate
4799 * TIR records to fix up addresses within the Text Psect.
4801 for (fixP
= text_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4803 /* We DO handle the case of "Symbol - Symbol" as
4804 long as it is in the same segment. */
4805 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4807 /* They need to be in the same segment. */
4808 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4809 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4810 error ("Fixup data addsy and subsy don't have the same type");
4811 /* And they need to be in one that we can check the psect on. */
4812 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4813 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4814 error ("Fixup data addsy and subsy don't have an appropriate type");
4815 /* This had better not be PC relative! */
4817 error ("Fixup data is erroneously \"pcrel\"");
4818 /* Subtract their values to get the difference. */
4819 dif
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
4820 md_number_to_chars (Local
, (valueT
)dif
, fixP
->fx_size
);
4821 /* Now generate the fixup object records;
4822 set the psect and store the data. */
4823 VMS_Set_Psect (Text_Psect
,
4824 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4826 VMS_Store_Immediate_Data (Local
,
4829 continue; /* done with this fixup */
4830 } /* if fx_subsy && fx_addsy */
4831 /* Size will HAVE to be "long". */
4832 if (fixP
->fx_size
!= 4)
4833 error ("Fixup datum is not a longword");
4834 /* Symbol must be "added" (if it is ever
4835 subtracted we can fix this assumption). */
4836 if (fixP
->fx_addsy
== 0)
4837 error ("Fixup datum is not \"fixP->fx_addsy\"");
4838 /* Store the symbol value in a PIC fashion. */
4839 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4843 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4846 * Check for indirect address reference, which has to be fixed up
4847 * (as the linker will screw it up with TIR_S_C_STO_PICR)...
4850 VMS_Fix_Indirect_Reference (Text_Psect
,
4851 fixP
->fx_where
+ fixP
->fx_frag
->fr_address
,
4854 } /* text fix loop */
4859 * Create a buffer holding the data segment.
4862 synthesize_data_segment(data_siz
, text_siz
, data_frag_root
)
4863 unsigned data_siz
, text_siz
;
4864 struct frag
*data_frag_root
;
4866 register fragS
*fragP
;
4868 long fill_size
, count
, i
;
4870 /* Allocate the data segment. */
4871 Data_Segment
= (char *) xmalloc (data_siz
);
4872 /* Run through the data fragments, filling in the segment. */
4873 for (fragP
= data_frag_root
; fragP
; fragP
= fragP
->fr_next
)
4875 i
= fragP
->fr_address
- text_siz
;
4877 memcpy (Data_Segment
+ i
, fragP
->fr_literal
, fragP
->fr_fix
);
4880 if ((fill_size
= fragP
->fr_var
) != 0)
4882 fill_literal
= fragP
->fr_literal
+ fragP
->fr_fix
;
4883 for (count
= fragP
->fr_offset
; count
; count
--)
4885 memcpy (Data_Segment
+ i
, fill_literal
, fill_size
);
4889 } /* data frag loop */
4895 * Perform data segment fixups.
4898 vms_fixup_data_section (data_siz
, text_siz
)
4899 unsigned data_siz
, text_siz
;
4901 register struct VMS_Symbol
*vsp
;
4902 register struct fix
*fixP
;
4903 register symbolS
*sp
;
4904 addressT fr_address
;
4908 /* Run through all the data symbols and store the data. */
4909 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4911 /* Ignore anything other than data symbols. */
4912 if (S_GET_TYPE (vsp
->Symbol
) != N_DATA
)
4914 /* Set the Psect + Offset. */
4915 VMS_Set_Psect (vsp
->Psect_Index
,
4918 /* Store the data. */
4919 val
= S_GET_VALUE (vsp
->Symbol
);
4920 VMS_Store_Immediate_Data (Data_Segment
+ val
- text_siz
,
4923 } /* N_DATA symbol loop */
4926 * Now we go through the data segment fixups and generate
4927 * TIR records to fix up addresses within the Data Psects.
4929 for (fixP
= data_fix_root
; fixP
; fixP
= fixP
->fx_next
)
4931 /* Find the symbol for the containing datum. */
4932 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
4934 /* Only bother with Data symbols. */
4936 if (S_GET_TYPE (sp
) != N_DATA
)
4938 /* Ignore symbol if After fixup. */
4939 val
= S_GET_VALUE (sp
);
4940 fr_address
= fixP
->fx_frag
->fr_address
;
4941 if (val
> fixP
->fx_where
+ fr_address
)
4943 /* See if the datum is here. */
4944 if (val
+ vsp
->Size
<= fixP
->fx_where
+ fr_address
)
4946 /* We DO handle the case of "Symbol - Symbol" as
4947 long as it is in the same segment. */
4948 if (fixP
->fx_subsy
&& fixP
->fx_addsy
)
4950 /* They need to be in the same segment. */
4951 if (S_GET_RAW_TYPE (fixP
->fx_subsy
) !=
4952 S_GET_RAW_TYPE (fixP
->fx_addsy
))
4953 error ("Fixup data addsy and subsy don't have the same type");
4954 /* And they need to be in one that we can check the psect on. */
4955 if ((S_GET_TYPE (fixP
->fx_addsy
) != N_DATA
) &&
4956 (S_GET_TYPE (fixP
->fx_addsy
) != N_TEXT
))
4957 error ("Fixup data addsy and subsy don't have an appropriate type");
4958 /* This had better not be PC relative! */
4960 error ("Fixup data is erroneously \"pcrel\"");
4961 /* Subtract their values to get the difference. */
4962 dif
= S_GET_VALUE (fixP
->fx_addsy
) - S_GET_VALUE (fixP
->fx_subsy
);
4963 md_number_to_chars (Local
, (valueT
)dif
, fixP
->fx_size
);
4965 * Now generate the fixup object records;
4966 * set the psect and store the data.
4968 VMS_Set_Psect (vsp
->Psect_Index
,
4969 fr_address
+ fixP
->fx_where
4970 - val
+ vsp
->Psect_Offset
,
4972 VMS_Store_Immediate_Data (Local
,
4975 break; /* done with this fixup */
4977 /* Size will HAVE to be "long". */
4978 if (fixP
->fx_size
!= 4)
4979 error ("Fixup datum is not a longword");
4980 /* Symbol must be "added" (if it is ever
4981 subtracted we can fix this assumption). */
4982 if (fixP
->fx_addsy
== 0)
4983 error ("Fixup datum is not \"fixP->fx_addsy\"");
4984 /* Store the symbol value in a PIC fashion. */
4985 VMS_Store_PIC_Symbol_Reference (fixP
->fx_addsy
,
4989 fr_address
+ fixP
->fx_where
4990 - val
+ vsp
->Psect_Offset
,
4992 /* Done with this fixup. */
4994 } /* vms_symbol loop */
4996 } /* data fix loop */
5001 * Define symbols for the linker.
5004 global_symbol_directory (text_siz
, data_siz
)
5005 unsigned text_siz
, data_siz
;
5007 register fragS
*fragP
;
5008 register symbolS
*sp
;
5009 register struct VMS_Symbol
*vsp
;
5010 int Globalref
, define_as_global_symbol
;
5012 #ifndef gxx_bug_fixed
5014 * The g++ compiler does not write out external references to vtables
5015 * correctly. Check for this and holler if we see it happening.
5016 * If that compiler bug is ever fixed we can remove this.
5017 * (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
5019 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
5020 if (S_GET_RAW_TYPE (sp
) == N_UNDF
&& IS_GXX_VTABLE (sp
))
5022 S_SET_TYPE (sp
, N_UNDF
| N_EXT
);
5023 S_SET_OTHER (sp
, 1);
5024 as_warn ("g++ wrote an extern reference to `%s' as a routine.\n%s",
5026 "I will fix it, but I hope that it was not really a routine.");
5028 #endif /* gxx_bug_fixed */
5031 * Now scan the symbols and emit the appropriate GSD records
5033 for (sp
= symbol_rootP
; sp
; sp
= symbol_next (sp
))
5035 define_as_global_symbol
= 0;
5036 /* Dispatch on symbol type. */
5037 switch (S_GET_RAW_TYPE (sp
))
5040 /* Global uninitialized data. */
5041 case N_UNDF
| N_EXT
:
5042 /* Make a VMS data symbol entry. */
5043 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5045 vsp
->Size
= S_GET_VALUE (sp
);
5046 vsp
->Psect_Index
= Psect_Number
++;
5047 vsp
->Psect_Offset
= 0;
5048 vsp
->Next
= VMS_Symbols
;
5051 /* Make the psect for this data. */
5052 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
5054 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
5058 #ifdef NOT_VAX_11_C_COMPATIBLE
5059 define_as_global_symbol
= 1;
5061 /* See if this is an external vtable. We want to help the
5062 linker find these things in libraries, so we make a symbol
5063 reference. This is not compatible with VAX-C usage for
5064 variables, but since vtables are only used internally by
5065 g++, we can get away with this hack. */
5066 define_as_global_symbol
= IS_GXX_VTABLE (sp
);
5070 /* Local uninitialized data. */
5072 /* Make a VMS data symbol entry. */
5073 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5076 vsp
->Psect_Index
= Bss_Psect
;
5077 vsp
->Psect_Offset
= S_GET_VALUE (sp
) - bss_address_frag
.fr_address
;
5078 vsp
->Next
= VMS_Symbols
;
5083 /* Global initialized data. */
5084 case N_DATA
| N_EXT
:
5085 /* Make a VMS data symbol entry. */
5086 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5088 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
5089 vsp
->Psect_Index
= Psect_Number
++;
5090 vsp
->Psect_Offset
= 0;
5091 vsp
->Next
= VMS_Symbols
;
5094 /* Make its psect. */
5095 Globalref
= VMS_Psect_Spec (S_GET_NAME (sp
),
5097 S_GET_OTHER (sp
) ? "CONST" : "COMMON",
5101 #ifdef NOT_VAX_11_C_COMPATIBLE
5102 define_as_global_symbol
= 1;
5104 /* See N_UNDF|N_EXT above for explanation. */
5105 define_as_global_symbol
= IS_GXX_VTABLE (sp
);
5109 /* Local initialized data. */
5112 char *sym_name
= S_GET_NAME (sp
);
5114 /* Always suppress local numeric labels. */
5115 if (!sym_name
|| strcmp (sym_name
, FAKE_LABEL_NAME
) != 0)
5117 /* Make a VMS data symbol entry. */
5118 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5120 vsp
->Size
= VMS_Initialized_Data_Size (sp
, text_siz
+ data_siz
);
5121 vsp
->Psect_Index
= Data_Psect
;
5122 vsp
->Psect_Offset
= Local_Initd_Data_Size
;
5123 Local_Initd_Data_Size
+= vsp
->Size
;
5124 vsp
->Next
= VMS_Symbols
;
5131 /* Global Text definition. */
5132 case N_TEXT
| N_EXT
:
5134 unsigned short Entry_Mask
;
5136 /* Get the entry mask. */
5137 fragP
= sp
->sy_frag
;
5138 /* First frag might be empty if we're generating listings.
5139 So skip empty rs_fill frags. */
5140 while (fragP
&& fragP
->fr_type
== rs_fill
&& fragP
->fr_fix
== 0)
5141 fragP
= fragP
->fr_next
;
5143 /* If first frag doesn't contain the data, what do we do?
5144 If it's possibly smaller than two bytes, that would
5145 imply that the entry mask is not stored where we're
5148 If you can find a test case that triggers this, report
5149 it (and tell me what the entry mask field ought to be),
5150 and I'll try to fix it. KR */
5151 if (fragP
->fr_fix
< 2)
5154 Entry_Mask
= (fragP
->fr_literal
[0] & 0x00ff) |
5155 ((fragP
->fr_literal
[1] & 0x00ff) << 8);
5156 /* Define the procedure entry point. */
5157 VMS_Procedure_Entry_Pt (S_GET_NAME (sp
),
5164 /* Local Text definition. */
5166 /* Make a VMS data symbol entry. */
5167 if (Text_Psect
!= -1)
5169 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5172 vsp
->Psect_Index
= Text_Psect
;
5173 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
5174 vsp
->Next
= VMS_Symbols
;
5180 /* Global Reference. */
5182 /* Make a GSD global symbol reference record. */
5183 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
5189 /* Absolute symbol. */
5192 /* gcc doesn't generate these;
5193 VMS_Emit_Globalvalue handles them though. */
5194 vsp
= (struct VMS_Symbol
*) xmalloc (sizeof *vsp
);
5196 vsp
->Size
= 4; /* always assume 32 bits */
5197 vsp
->Psect_Index
= 0;
5198 vsp
->Psect_Offset
= S_GET_VALUE (sp
);
5199 vsp
->Next
= VMS_Symbols
;
5204 /* Anything else. */
5206 /* Ignore STAB symbols, including .stabs emitted by g++. */
5207 if (S_IS_DEBUG (sp
) || (S_GET_TYPE (sp
) == 22))
5212 as_tsktsk ("unhandled stab type %d", S_GET_TYPE (sp
));
5216 /* Global symbols have different linkage than external variables. */
5217 if (define_as_global_symbol
)
5218 VMS_Global_Symbol_Spec (S_GET_NAME (sp
),
5229 * Output debugger symbol table information for symbols which
5230 * are local to a specific routine.
5233 local_symbols_DST (s0P
, Current_Routine
)
5234 symbolS
*s0P
, *Current_Routine
;
5237 char *s0P_name
, *pnt0
, *pnt1
;
5239 s0P_name
= S_GET_NAME (s0P
);
5240 if (*++s0P_name
!= '_')
5243 for (s1P
= Current_Routine
; s1P
; s1P
= symbol_next (s1P
))
5245 #if 0 /* redundant; RAW_TYPE != N_FUN suffices */
5246 if (!S_IS_DEBUG (s1P
))
5249 if (S_GET_RAW_TYPE (s1P
) != N_FUN
)
5252 pnt1
= S_GET_NAME (s1P
);
5253 /* We assume the two strings are never exactly equal... */
5254 while (*pnt0
++ == *pnt1
++)
5257 /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next.
5258 Note: both pointers have advanced one past the non-matching char. */
5259 if ((*pnt1
== 'F' || *pnt1
== 'f') && *--pnt1
== ':' && *--pnt0
== '\0')
5261 Define_Routine (s1P
, 0, Current_Routine
, Text_Psect
);
5268 * Construct and output the debug symbol table.
5271 vms_build_DST (text_siz
)
5274 register symbolS
*symbolP
;
5275 symbolS
*Current_Routine
= 0;
5276 struct input_file
*Cur_File
= 0;
5277 offsetT Cur_Offset
= -1;
5278 int Cur_Line_Number
= 0;
5279 int File_Number
= 0;
5280 int Debugger_Offset
= 0;
5286 * Write the Traceback Begin Module record
5288 VMS_TBT_Module_Begin ();
5291 * Output debugging info for global variables and static variables
5292 * that are not specific to one routine. We also need to examine
5293 * all stabs directives, to find the definitions to all of the
5294 * advanced data types, and this is done by VMS_LSYM_Parse. This
5295 * needs to be done before any definitions are output to the object
5296 * file, since there can be forward references in the stabs
5297 * directives. When through with parsing, the text of the stabs
5298 * directive is altered, with the definitions removed, so that later
5299 * passes will see directives as they would be written if the type
5300 * were already defined.
5302 * We also look for files and include files, and make a list of
5303 * them. We examine the source file numbers to establish the actual
5304 * lines that code was generated from, and then generate offsets.
5307 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5309 /* Only deal with STAB symbols here. */
5310 if (!S_IS_DEBUG (symbolP
))
5313 * Dispatch on STAB type.
5315 switch (S_GET_RAW_TYPE (symbolP
))
5318 dsc
= S_GET_DESC (symbolP
);
5319 if (dsc
> Cur_File
->max_line
)
5320 Cur_File
->max_line
= dsc
;
5321 if (dsc
< Cur_File
->min_line
)
5322 Cur_File
->min_line
= dsc
;
5325 Cur_File
= find_file (symbolP
);
5327 Cur_File
->min_line
= 1;
5330 Cur_File
= find_file (symbolP
);
5333 VMS_GSYM_Parse (symbolP
, Text_Psect
);
5336 VMS_LCSYM_Parse (symbolP
, Text_Psect
);
5338 case N_FUN
: /* For static constant symbols */
5340 VMS_STSYM_Parse (symbolP
, Text_Psect
);
5348 * Now we take a quick sweep through the files and assign offsets
5349 * to each one. This will essentially be the starting line number to
5350 * the debugger for each file. Output the info for the debugger to
5351 * specify the files, and then tell it how many lines to use.
5353 for (Cur_File
= file_root
; Cur_File
; Cur_File
= Cur_File
->next
)
5355 if (Cur_File
->max_line
== 0)
5357 if ((strncmp (Cur_File
->name
, "GNU_GXX_INCLUDE:", 16) == 0) &&
5360 if ((strncmp (Cur_File
->name
, "GNU_CC_INCLUDE:", 15) == 0) &&
5363 /* show a few extra lines at the start of the region selected */
5364 if (Cur_File
->min_line
> 2)
5365 Cur_File
->min_line
-= 2;
5366 Cur_File
->offset
= Debugger_Offset
- Cur_File
->min_line
+ 1;
5367 Debugger_Offset
+= Cur_File
->max_line
- Cur_File
->min_line
+ 1;
5368 if (Cur_File
->same_file_fpnt
)
5370 Cur_File
->file_number
= Cur_File
->same_file_fpnt
->file_number
;
5374 Cur_File
->file_number
= ++File_Number
;
5375 file_available
= VMS_TBT_Source_File (Cur_File
->name
,
5376 Cur_File
->file_number
);
5377 if (!file_available
)
5379 Cur_File
->file_number
= 0;
5384 VMS_TBT_Source_Lines (Cur_File
->file_number
,
5386 Cur_File
->max_line
- Cur_File
->min_line
+ 1);
5388 Cur_File
= (struct input_file
*) NULL
;
5391 * Scan the symbols and write out the routines
5392 * (this makes the assumption that symbols are in
5393 * order of ascending text segment offset)
5395 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
5398 * Deal with text symbols.
5400 if (!S_IS_DEBUG (symbolP
) && S_GET_TYPE (symbolP
) == N_TEXT
)
5403 * Ignore symbols starting with "L", as they are local symbols.
5405 if (*S_GET_NAME (symbolP
) == 'L')
5408 * If there is a routine start defined, terminate it.
5410 if (Current_Routine
)
5411 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5414 * Check for & skip dummy labels like "gcc_compiled.".
5415 * They're identified by the IN_DEFAULT_SECTION flag.
5417 if ((S_GET_OTHER (symbolP
) & IN_DEFAULT_SECTION
) != 0 &&
5418 S_GET_VALUE (symbolP
) == 0)
5421 * Store the routine begin traceback info.
5423 VMS_TBT_Routine_Begin (symbolP
, Text_Psect
);
5424 Current_Routine
= symbolP
;
5426 * Define symbols local to this routine.
5428 local_symbols_DST (symbolP
, Current_Routine
);
5436 * Deal with STAB symbols.
5438 else if (S_IS_DEBUG (symbolP
))
5441 * Dispatch on STAB type.
5443 switch (S_GET_RAW_TYPE (symbolP
))
5449 /* Offset the line into the correct portion of the file. */
5450 if (Cur_File
->file_number
== 0)
5452 val
= S_GET_VALUE (symbolP
);
5453 /* Sometimes the same offset gets several source lines
5454 assigned to it. We should be selective about which
5455 lines we allow, we should prefer lines that are in
5456 the main source file when debugging inline functions. */
5457 if (val
== Cur_Offset
&& Cur_File
->file_number
!= 1)
5460 /* calculate actual debugger source line */
5461 dsc
= S_GET_DESC (symbolP
) + Cur_File
->offset
;
5462 S_SET_DESC (symbolP
, dsc
);
5464 * Define PC/Line correlation.
5466 if (Cur_Offset
== -1)
5469 * First N_SLINE; set up initial correlation.
5471 VMS_TBT_Line_PC_Correlation (dsc
,
5476 else if ((dsc
- Cur_Line_Number
) <= 0)
5479 * Line delta is not +ve, we need to close the line and
5480 * start a new PC/Line correlation.
5482 VMS_TBT_Line_PC_Correlation (0,
5486 VMS_TBT_Line_PC_Correlation (dsc
,
5494 * Line delta is +ve, all is well.
5496 VMS_TBT_Line_PC_Correlation (dsc
- Cur_Line_Number
,
5501 /* Update the current line/PC info. */
5502 Cur_Line_Number
= dsc
;
5510 /* Remember that we had a source file and emit
5511 the source file debugger record. */
5512 Cur_File
= find_file (symbolP
);
5516 /* We need to make sure that we are really in the actual
5517 source file when we compute the maximum line number.
5518 Otherwise the debugger gets really confused. */
5519 Cur_File
= find_file (symbolP
);
5525 } /* if (IS_DEBUG) */
5529 * If there is a routine start defined, terminate it
5530 * (and the line numbers).
5532 if (Current_Routine
)
5534 /* Terminate the line numbers. */
5535 VMS_TBT_Line_PC_Correlation (0,
5536 text_siz
- S_GET_VALUE (Current_Routine
),
5539 /* Terminate the routine. */
5540 VMS_TBT_Routine_End (text_siz
, Current_Routine
);
5544 * Write the Traceback End Module TBT record
5546 VMS_TBT_Module_End ();
5551 * Write a VAX/VMS object file (everything else has been done!)
5554 vms_write_object_file (text_siz
, data_siz
, bss_siz
, text_frag_root
,
5559 fragS
*text_frag_root
;
5560 fragS
*data_frag_root
;
5562 register struct VMS_Symbol
*vsp
;
5565 * Initialize program section indices; values get updated later.
5567 Psect_Number
= 0; /* next Psect Index to use */
5568 Text_Psect
= -1; /* Text Psect Index */
5569 Data_Psect
= -2; /* Data Psect Index JF: Was -1 */
5570 Bss_Psect
= -3; /* Bss Psect Index JF: Was -1 */
5571 /* Initialize other state variables. */
5573 Local_Initd_Data_Size
= 0;
5576 * Create the actual output file and populate it with required
5577 * "module header" information.
5579 Create_VMS_Object_File ();
5580 Write_VMS_MHD_Records ();
5583 * Create the Data segment:
5585 * Since this is REALLY hard to do any other way,
5586 * we actually manufacture the data segment and
5587 * then store the appropriate values out of it.
5588 * We need to generate this early, so that globalvalues
5589 * can be properly emitted.
5592 synthesize_data_segment(data_siz
, text_siz
, data_frag_root
);
5595 /******* Global Symbol Directory *******/
5598 * Emit globalvalues now. We must do this before the text psect is
5599 * defined, or we will get linker warnings about multiply defined
5600 * symbols. All of the globalvalues "reference" psect 0, although
5601 * it really does not have anything to do with it.
5603 VMS_Emit_Globalvalues (text_siz
, data_siz
, Data_Segment
);
5605 * Define the Text Psect
5607 Text_Psect
= Psect_Number
++;
5608 VMS_Psect_Spec ("$code", text_siz
, "TEXT", 0);
5610 * Define the BSS Psect
5614 Bss_Psect
= Psect_Number
++;
5615 VMS_Psect_Spec ("$uninitialized_data", bss_siz
, "DATA", 0);
5618 * Define symbols to the linker.
5620 global_symbol_directory (text_siz
, data_siz
);
5622 * Define the Data Psect
5624 if (data_siz
> 0 && Local_Initd_Data_Size
> 0)
5626 Data_Psect
= Psect_Number
++;
5627 VMS_Psect_Spec ("$data", Local_Initd_Data_Size
, "DATA", 0);
5629 * Local initialized data (N_DATA) symbols need to be updated to the
5630 * proper value of Data_Psect now that it's actually been defined.
5631 * (A dummy value was used in global_symbol_directory() above.)
5633 for (vsp
= VMS_Symbols
; vsp
; vsp
= vsp
->Next
)
5634 if (vsp
->Psect_Index
< 0 && S_GET_RAW_TYPE (vsp
->Symbol
) == N_DATA
)
5635 vsp
->Psect_Index
= Data_Psect
;
5639 /******* Text Information and Relocation Records *******/
5642 * Write the text segment data
5645 vms_fixup_text_section (text_siz
, text_frag_root
, data_frag_root
);
5647 * Write the data segment data, then discard it.
5651 vms_fixup_data_section (data_siz
, text_siz
);
5652 free (Data_Segment
), Data_Segment
= 0;
5656 /******* Debugger Symbol Table Records *******/
5658 vms_build_DST (text_siz
);
5662 * Write the End Of Module record
5664 if (Entry_Point_Symbol
== 0)
5665 Write_VMS_EOM_Record (-1, 0);
5667 Write_VMS_EOM_Record (Text_Psect
,
5668 S_GET_VALUE (Entry_Point_Symbol
));
5671 * All done, close the object file
5673 Close_VMS_Object_File ();
5676 /* end of obj-vms.c */