source: trunk/binutils/gas/config/obj-vms.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 152.3 KB
Line 
1/* vms.c -- Write out a VAX/VMS object file
2 Copyright 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5This file is part of GAS, the GNU Assembler.
6
7GAS is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GAS is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GAS; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22/* Written by David L. Kashtan */
23/* Modified by Eric Youngdale to write VMS debug records for program
24 variables */
25
26/* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h). */
27#define WANT_VMS_OBJ_DEFS
28
29#include "as.h"
30#include "config.h"
31#include "safe-ctype.h"
32#include "subsegs.h"
33#include "obstack.h"
34#include <fcntl.h>
35
36/* What we do if there is a goof. */
37#define error as_fatal
38
39#ifdef VMS /* These are of no use if we are cross assembling. */
40#include <fab.h> /* Define File Access Block */
41#include <nam.h> /* Define NAM Block */
42#include <xab.h> /* Define XAB - all different types*/
43extern int sys$open(), sys$close(), sys$asctim();
44#endif
45
46/*
47 * Version string of the compiler that produced the code we are
48 * assembling. (And this assembler, if we do not have compiler info.)
49 */
50char *compiler_version_string;
51
52extern int flag_hash_long_names; /* -+ */
53extern int flag_one; /* -1; compatibility with gcc 1.x */
54extern int flag_show_after_trunc; /* -H */
55extern int flag_no_hash_mixed_case; /* -h NUM */
56
57/* Flag that determines how we map names. This takes several values, and
58 * is set with the -h switch. A value of zero implies names should be
59 * upper case, and the presence of the -h switch inhibits the case hack.
60 * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
61 * A value of 2 (set with -h2) implies names should be
62 * all lower case, with no case hack. A value of 3 (set with -h3) implies
63 * that case should be preserved. */
64
65/* If the -+ switch is given, then the hash is appended to any name that is
66 * longer than 31 characters, regardless of the setting of the -h switch.
67 */
68
69char vms_name_mapping = 0;
70
71static symbolS *Entry_Point_Symbol = 0; /* Pointer to "_main" */
72
73/*
74 * We augment the "gas" symbol structure with this
75 */
76struct VMS_Symbol
77{
78 struct VMS_Symbol *Next;
79 symbolS *Symbol;
80 int Size;
81 int Psect_Index;
82 int Psect_Offset;
83};
84
85struct VMS_Symbol *VMS_Symbols = 0;
86struct VMS_Symbol *Ctors_Symbols = 0;
87struct VMS_Symbol *Dtors_Symbols = 0;
88
89/* We need this to keep track of the various input files, so that we can
90 * give the debugger the correct source line.
91 */
92
93struct input_file
94{
95 struct input_file *next;
96 struct input_file *same_file_fpnt;
97 int file_number;
98 int max_line;
99 int min_line;
100 int offset;
101 char flag;
102 char *name;
103 symbolS *spnt;
104};
105
106static struct input_file *file_root = (struct input_file *) NULL;
107
108/*
109 * Styles of PSECTS (program sections) that we generate; just shorthand
110 * to avoid lists of section attributes. Used by VMS_Psect_Spec().
111 */
112enum ps_type
113{
114 ps_TEXT, ps_DATA, ps_COMMON, ps_CONST, ps_CTORS, ps_DTORS
115};
116
117/*
118 * This enum is used to keep track of the various types of variables that
119 * may be present.
120 */
121
122enum advanced_type
123{
124 BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN
125};
126
127/*
128 * This structure contains the information from the stabs directives, and the
129 * information is filled in by VMS_typedef_parse. Everything that is needed
130 * to generate the debugging record for a given symbol is present here.
131 * This could be done more efficiently, using nested struct/unions, but for now
132 * I am happy that it works.
133 */
134struct VMS_DBG_Symbol
135{
136 struct VMS_DBG_Symbol *next;
137 /* description of what this is */
138 enum advanced_type advanced;
139 /* this record is for this type */
140 int dbx_type;
141 /* For advanced types this is the type referred to. I.e., the type
142 a pointer points to, or the type of object that makes up an
143 array. */
144 int type2;
145 /* Use this type when generating a variable def */
146 int VMS_type;
147 /* used for arrays - this will be present for all */
148 int index_min;
149 /* entries, but will be meaningless for non-arrays */
150 int index_max;
151 /* Size in bytes of the data type. For an array, this is the size
152 of one element in the array */
153 int data_size;
154 /* Number of the structure/union/enum - used for ref */
155 int struc_numb;
156};
157
158#define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */
159#define SYMTYP_HASH(x) ((unsigned) (x) & (SYMTYPLST_SIZE-1))
160struct VMS_DBG_Symbol *VMS_Symbol_type_list[SYMTYPLST_SIZE];
161
162/*
163 * We need this structure to keep track of forward references to
164 * struct/union/enum that have not been defined yet. When they are ultimately
165 * defined, then we can go back and generate the TIR commands to make a back
166 * reference.
167 */
168
169struct forward_ref
170{
171 struct forward_ref *next;
172 int dbx_type;
173 int struc_numb;
174 char resolved;
175};
176
177struct forward_ref *f_ref_root = (struct forward_ref *) NULL;
178
179/*
180 * This routine is used to compare the names of certain types to various
181 * fixed types that are known by the debugger.
182 */
183#define type_check(X) !strcmp (symbol_name, X)
184
185/*
186 * This variable is used to keep track of the name of the symbol we are
187 * working on while we are parsing the stabs directives.
188 */
189static const char *symbol_name;
190
191/* We use this counter to assign numbers to all of the structures, unions
192 * and enums that we define. When we actually declare a variable to the
193 * debugger, we can simply do it by number, rather than describing the
194 * whole thing each time.
195 */
196
197static int structure_count = 0;
198
199/* This variable is used to indicate that we are making the last attempt to
200 parse the stabs, and that we should define as much as we can, and ignore
201 the rest */
202
203static int final_pass;
204
205/* This variable is used to keep track of the current structure number
206 * for a given variable. If this is < 0, that means that the structure
207 * has not yet been defined to the debugger. This is still cool, since
208 * the VMS object language has ways of fixing things up after the fact,
209 * so we just make a note of this, and generate fixups at the end.
210 */
211static int struct_number;
212
213/* This is used to distinguish between D_float and G_float for telling
214 the debugger about doubles. gcc outputs the same .stabs regardless
215 of whether -mg is used to select alternate doubles. */
216
217static int vax_g_doubles = 0;
218
219/* Local symbol references (used to handle N_ABS symbols; gcc does not
220 generate those, but they're possible with hand-coded assembler input)
221 are always made relative to some particular environment. If the current
222 input has any such symbols, then we expect this to get incremented
223 exactly once and end up having all of them be in environment #0. */
224
225static int Current_Environment = -1;
226
227/* Every object file must specify an module name, which is also used by
228 traceback records. Set in Write_VMS_MHD_Records(). */
229
230static char Module_Name[255+1];
231
232/*
233 * Variable descriptors are used tell the debugger the data types of certain
234 * more complicated variables (basically anything involving a structure,
235 * union, enum, array or pointer). Some non-pointer variables of the
236 * basic types that the debugger knows about do not require a variable
237 * descriptor.
238 *
239 * Since it is impossible to have a variable descriptor longer than 128
240 * bytes by virtue of the way that the VMS object language is set up,
241 * it makes not sense to make the arrays any longer than this, or worrying
242 * about dynamic sizing of the array.
243 *
244 * These are the arrays and counters that we use to build a variable
245 * descriptor.
246 */
247
248#define MAX_DEBUG_RECORD 128
249static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
250static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
251static int Lpnt; /* index into Local */
252static int Apoint; /* index into Asuffix */
253static char overflow; /* flag to indicate we have written too much*/
254static int total_len; /* used to calculate the total length of variable
255 descriptor plus array descriptor - used for len byte*/
256
257/* Flag if we have told user about finding global constants in the text
258 section. */
259static int gave_compiler_message = 0;
260
261/*
262 * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
263 */
264static int VMS_Object_File_FD; /* File Descriptor for object file */
265static char Object_Record_Buffer[512]; /* Buffer for object file records */
266static size_t Object_Record_Offset; /* Offset to end of data */
267static int Current_Object_Record_Type; /* Type of record in above */
268
269/*
270 * Macros for moving data around. Must work on big-endian systems.
271 */
272#ifdef VMS /* These are more efficient for VMS->VMS systems */
273#define COPY_LONG(dest,val) ( *(long *) (dest) = (val) )
274#define COPY_SHORT(dest,val) ( *(short *) (dest) = (val) )
275#else
276#define COPY_LONG(dest,val) md_number_to_chars ((dest), (val), 4)
277#define COPY_SHORT(dest,val) md_number_to_chars ((dest), (val), 2)
278#endif
279/*
280 * Macros for placing data into the object record buffer.
281 */
282#define PUT_LONG(val) \
283 ( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \
284 Object_Record_Offset += 4 )
285
286#define PUT_SHORT(val) \
287 ( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \
288 Object_Record_Offset += 2 )
289
290#define PUT_CHAR(val) ( Object_Record_Buffer[Object_Record_Offset++] = (val) )
291
292#define PUT_COUNTED_STRING(cp) do { \
293 register const char *p = (cp); \
294 PUT_CHAR ((char) strlen (p)); \
295 while (*p) PUT_CHAR (*p++); } while (0)
296
297/*
298 * Macro for determining if a Name has psect attributes attached
299 * to it.
300 */
301#define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
302#define PSECT_ATTRIBUTES_STRING_LENGTH 18
303
304#define HAS_PSECT_ATTRIBUTES(Name) \
305 (strncmp ((*Name == '_' ? Name + 1 : Name), \
306 PSECT_ATTRIBUTES_STRING, \
307 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
308
309
310
311 /* in: segT out: N_TYPE bits */
312const short seg_N_TYPE[] =
313{
314 N_ABS,
315 N_TEXT,
316 N_DATA,
317 N_BSS,
318 N_UNDF, /* unknown */
319 N_UNDF, /* error */
320 N_UNDF, /* expression */
321 N_UNDF, /* debug */
322 N_UNDF, /* ntv */
323 N_UNDF, /* ptv */
324 N_REGISTER, /* register */
325};
326
327const segT N_TYPE_seg[N_TYPE + 2] =
328{ /* N_TYPE == 0x1E = 32-2 */
329 SEG_UNKNOWN, /* N_UNDF == 0 */
330 SEG_GOOF,
331 SEG_ABSOLUTE, /* N_ABS == 2 */
332 SEG_GOOF,
333 SEG_TEXT, /* N_TEXT == 4 */
334 SEG_GOOF,
335 SEG_DATA, /* N_DATA == 6 */
336 SEG_GOOF,
337 SEG_BSS, /* N_BSS == 8 */
338 SEG_GOOF,
339 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
340 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
341 SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
342 SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
343 SEG_GOOF,
344};
345
346
347
348/* Local support routines which return a value. */
349
350static struct input_file *find_file
351 PARAMS ((symbolS *));
352static struct VMS_DBG_Symbol *find_symbol
353 PARAMS ((int));
354static symbolS *Define_Routine
355 PARAMS ((symbolS *, int, symbolS *, int));
356
357static char *cvt_integer
358 PARAMS ((char *, int *));
359static char *fix_name
360 PARAMS ((char *));
361static char *get_struct_name
362 PARAMS ((char *));
363
364static offsetT VMS_Initialized_Data_Size
365 PARAMS ((symbolS *, unsigned));
366
367static int VMS_TBT_Source_File
368 PARAMS ((char *, int));
369static int gen1
370 PARAMS ((struct VMS_DBG_Symbol *, int));
371static int forward_reference
372 PARAMS ((char *));
373static int final_forward_reference
374 PARAMS ((struct VMS_DBG_Symbol *));
375static int VMS_typedef_parse
376 PARAMS ((char *));
377static int hash_string
378 PARAMS ((const char *));
379static int VMS_Psect_Spec
380 PARAMS ((const char *, int, enum ps_type, struct VMS_Symbol *));
381
382/* Local support routines which don't directly return any value. */
383
384static void s_const
385 PARAMS ((int));
386static void Create_VMS_Object_File
387 PARAMS ((void));
388static void Flush_VMS_Object_Record_Buffer
389 PARAMS ((void));
390static void Set_VMS_Object_File_Record
391 PARAMS ((int));
392static void Close_VMS_Object_File
393 PARAMS ((void));
394static void vms_tir_stack_psect
395 PARAMS ((int, int, int));
396static void VMS_Store_Immediate_Data
397 PARAMS ((const char *, int, int));
398static void VMS_Set_Data
399 PARAMS ((int, int, int, int));
400static void VMS_Store_Struct
401 PARAMS ((int));
402static void VMS_Def_Struct
403 PARAMS ((int));
404static void VMS_Set_Struct
405 PARAMS ((int));
406static void VMS_TBT_Module_Begin
407 PARAMS ((void));
408static void VMS_TBT_Module_End
409 PARAMS ((void));
410static void VMS_TBT_Routine_Begin
411 PARAMS ((symbolS *, int));
412static void VMS_TBT_Routine_End
413 PARAMS ((int, symbolS *));
414static void VMS_TBT_Block_Begin
415 PARAMS ((symbolS *, int, char *));
416static void VMS_TBT_Block_End
417 PARAMS ((valueT));
418static void VMS_TBT_Line_PC_Correlation
419 PARAMS ((int, int, int, int));
420static void VMS_TBT_Source_Lines
421 PARAMS ((int, int, int));
422static void fpush
423 PARAMS ((int, int));
424static void rpush
425 PARAMS ((int, int));
426static void array_suffix
427 PARAMS ((struct VMS_DBG_Symbol *));
428static void new_forward_ref
429 PARAMS ((int));
430static void generate_suffix
431 PARAMS ((struct VMS_DBG_Symbol *, int));
432static void bitfield_suffix
433 PARAMS ((struct VMS_DBG_Symbol *, int));
434static void setup_basic_type
435 PARAMS ((struct VMS_DBG_Symbol *));
436static void VMS_DBG_record
437 PARAMS ((struct VMS_DBG_Symbol *, int, int, char *));
438static void VMS_local_stab_Parse
439 PARAMS ((symbolS *));
440static void VMS_stab_parse
441 PARAMS ((symbolS *, int, int, int, int));
442static void VMS_GSYM_Parse
443 PARAMS ((symbolS *, int));
444static void VMS_LCSYM_Parse
445 PARAMS ((symbolS *, int));
446static void VMS_STSYM_Parse
447 PARAMS ((symbolS *, int));
448static void VMS_RSYM_Parse
449 PARAMS ((symbolS *, symbolS *, int));
450static void VMS_LSYM_Parse
451 PARAMS ((void));
452static void Define_Local_Symbols
453 PARAMS ((symbolS *, symbolS *, symbolS *, int));
454static void Write_VMS_MHD_Records
455 PARAMS ((void));
456static void Write_VMS_EOM_Record
457 PARAMS ((int, valueT));
458static void VMS_Case_Hack_Symbol
459 PARAMS ((const char *, char *));
460static void VMS_Modify_Psect_Attributes
461 PARAMS ((const char *, int *));
462static void VMS_Global_Symbol_Spec
463 PARAMS ((const char *, int, int, int));
464static void VMS_Local_Environment_Setup
465 PARAMS ((const char *));
466static void VMS_Emit_Globalvalues
467 PARAMS ((unsigned, unsigned, char *));
468static void VMS_Procedure_Entry_Pt
469 PARAMS ((char *, int, int, int));
470static void VMS_Set_Psect
471 PARAMS ((int, int, int));
472static void VMS_Store_Repeated_Data
473 PARAMS ((int, char *, int, int));
474static void VMS_Store_PIC_Symbol_Reference
475 PARAMS ((symbolS *, int, int, int, int, int));
476static void VMS_Fix_Indirect_Reference
477 PARAMS ((int, addressT, fragS *, fragS *));
478
479/* Support code which used to be inline within vms_write_object_file. */
480static void vms_fixup_text_section
481 PARAMS ((unsigned, struct frag *, struct frag *));
482static void synthesize_data_segment
483 PARAMS ((unsigned, unsigned, struct frag *));
484static void vms_fixup_data_section
485 PARAMS ((unsigned, unsigned));
486static void global_symbol_directory
487 PARAMS ((unsigned, unsigned));
488static void local_symbols_DST
489 PARAMS ((symbolS *, symbolS *));
490static void vms_build_DST
491 PARAMS ((unsigned));
492static void vms_fixup_xtors_section
493 PARAMS ((struct VMS_Symbol *, int));
494
495
496
497/* The following code defines the special types of pseudo-ops that we
498 use with VMS. */
499
500unsigned char const_flag = IN_DEFAULT_SECTION;
501
502static void
503s_const (arg)
504 int arg; /* 3rd field from obj_pseudo_table[]; not needed here */
505{
506 /* Since we don't need `arg', use it as our scratch variable so that
507 we won't get any "not used" warnings about it. */
508 arg = get_absolute_expression ();
509 subseg_set (SEG_DATA, (subsegT) arg);
510 const_flag = 1;
511 demand_empty_rest_of_line ();
512}
513
514const pseudo_typeS obj_pseudo_table[] =
515{
516 {"const", s_const, 0},
517 {0, 0, 0},
518}; /* obj_pseudo_table */
519
520/* Routine to perform RESOLVE_SYMBOL_REDEFINITION(). */
521
522int
523vms_resolve_symbol_redef (sym)
524 symbolS *sym;
525{
526 /*
527 * If the new symbol is .comm AND it has a size of zero,
528 * we ignore it (i.e. the old symbol overrides it)
529 */
530 if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)
531 && frag_now_fix () == 0)
532 {
533 as_warn (_("compiler emitted zero-size common symbol `%s' already defined"),
534 S_GET_NAME (sym));
535 return 1;
536 }
537 /*
538 * If the old symbol is .comm and it has a size of zero,
539 * we override it with the new symbol value.
540 */
541 if (S_IS_EXTERNAL (sym) && S_IS_DEFINED (sym) && S_GET_VALUE (sym) == 0)
542 {
543 as_warn (_("compiler redefined zero-size common symbol `%s'"),
544 S_GET_NAME (sym));
545 sym->sy_frag = frag_now;
546 S_SET_OTHER (sym, const_flag);
547 S_SET_VALUE (sym, frag_now_fix ());
548 /* Keep N_EXT bit. */
549 sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg);
550 return 1;
551 }
552
553 return 0;
554}
555
556/* `tc_frob_label' handler for colon(symbols.c), used to examine the
557 dummy label(s) gcc inserts at the beginning of each file it generates.
558 gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.7) puts "gcc2_compiled."
559 and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
560
561void
562vms_check_for_special_label (symbolP)
563symbolS *symbolP;
564{
565 /* Special labels only occur prior to explicit section directives. */
566 if ((const_flag & IN_DEFAULT_SECTION) != 0)
567 {
568 char *sym_name = S_GET_NAME (symbolP);
569
570 if (*sym_name == '_')
571 ++sym_name;
572
573 if (!strcmp (sym_name, "__vax_g_doubles"))
574 vax_g_doubles = 1;
575#if 0 /* not necessary */
576 else if (!strcmp (sym_name, "__vax_d_doubles"))
577 vax_g_doubles = 0;
578#endif
579#if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
580 else if (!strcmp (sym_name, "gcc_compiled."))
581 flag_one = 1;
582 else if (!strcmp (sym_name, "__gnu_language_cplusplus"))
583 flag_hash_long_names = 1;
584#endif
585 }
586 return;
587}
588
589void
590obj_read_begin_hook ()
591{
592 return;
593}
594
595void
596obj_crawl_symbol_chain (headers)
597 object_headers *headers;
598{
599 symbolS *symbolP;
600 symbolS **symbolPP;
601 int symbol_number = 0;
602
603 symbolPP = &symbol_rootP; /* -> last symbol chain link. */
604 while ((symbolP = *symbolPP) != NULL)
605 {
606 resolve_symbol_value (symbolP);
607
608 /* OK, here is how we decide which symbols go out into the
609 brave new symtab. Symbols that do are:
610
611 * symbols with no name (stabd's?)
612 * symbols with debug info in their N_TYPE
613 * symbols with \1 as their 3rd character (numeric labels)
614 * "local labels" needed for PIC fixups
615
616 Symbols that don't are:
617 * symbols that are registers
618
619 All other symbols are output. We complain if a deleted
620 symbol was marked external. */
621
622 if (!S_IS_REGISTER (symbolP))
623 {
624 symbolP->sy_number = symbol_number++;
625 symbolP->sy_name_offset = 0;
626 symbolPP = &symbolP->sy_next;
627 }
628 else
629 {
630 if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
631 {
632 as_bad (_("Local symbol %s never defined"), S_GET_NAME (symbolP));
633 } /* oops. */
634
635 /* Unhook it from the chain. */
636 *symbolPP = symbol_next (symbolP);
637 } /* if this symbol should be in the output */
638
639 } /* for each symbol */
640
641 H_SET_STRING_SIZE (headers, string_byte_count);
642 H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
643} /* obj_crawl_symbol_chain() */
644
645
646
647 /****** VMS OBJECT FILE HACKING ROUTINES *******/
648
649/* Create the VMS object file. */
650
651static void
652Create_VMS_Object_File ()
653{
654#ifdef eunice
655 VMS_Object_File_FD = creat (out_file_name, 0777, "var");
656#else
657#ifndef VMS
658 VMS_Object_File_FD = creat (out_file_name, 0777);
659#else /* VMS */
660 VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var",
661 "ctx=bin", "mbc=16", "deq=64", "fop=tef",
662 "shr=nil");
663#endif /* !VMS */
664#endif /* !eunice */
665 /* Deal with errors. */
666 if (VMS_Object_File_FD < 0)
667 as_fatal (_("Couldn't create VMS object file \"%s\""), out_file_name);
668 /* Initialize object file hacking variables. */
669 Object_Record_Offset = 0;
670 Current_Object_Record_Type = -1;
671}
672
673/* Flush the object record buffer to the object file. */
674
675static void
676Flush_VMS_Object_Record_Buffer ()
677{
678 /* If the buffer is empty, there's nothing to do. */
679 if (Object_Record_Offset == 0)
680 return;
681
682#ifndef VMS /* For cross-assembly purposes. */
683 {
684 char RecLen[2];
685
686 /* "Variable-length record" files have a two byte length field
687 prepended to each record. It's normally out-of-band, and native
688 VMS output will insert it automatically for this type of file.
689 When cross-assembling, we must write it explicitly. */
690 md_number_to_chars (RecLen, Object_Record_Offset, 2);
691 if (write (VMS_Object_File_FD, RecLen, 2) != 2)
692 error (_("I/O error writing VMS object file (length prefix)"));
693 /* We also need to force the actual record to be an even number of
694 bytes. For native output, that's automatic; when cross-assembling,
695 pad with a NUL byte if length is odd. Do so _after_ writing the
696 pre-padded length. Since our buffer is defined with even size,
697 an odd offset implies that it has some room left. */
698 if ((Object_Record_Offset & 1) != 0)
699 Object_Record_Buffer[Object_Record_Offset++] = '\0';
700 }
701#endif /* not VMS */
702
703 /* Write the data to the file. */
704 if ((size_t) write (VMS_Object_File_FD, Object_Record_Buffer,
705 Object_Record_Offset) != Object_Record_Offset)
706 error (_("I/O error writing VMS object file"));
707
708 /* The buffer is now empty. */
709 Object_Record_Offset = 0;
710}
711
712/* Declare a particular type of object file record. */
713
714static void
715Set_VMS_Object_File_Record (Type)
716 int Type;
717{
718 /* If the type matches, we are done. */
719 if (Type == Current_Object_Record_Type)
720 return;
721 /* Otherwise: flush the buffer. */
722 Flush_VMS_Object_Record_Buffer ();
723 /* Remember the new type. */
724 Current_Object_Record_Type = Type;
725}
726
727/* Close the VMS Object file. */
728
729static void
730Close_VMS_Object_File ()
731{
732 /* Flush (should never be necessary) and reset saved record-type context. */
733 Set_VMS_Object_File_Record (-1);
734
735#ifndef VMS /* For cross-assembly purposes. */
736 {
737 char RecLen[2];
738 int minus_one = -1;
739
740 /* Write a 2 byte record-length field of -1 into the file, which
741 means end-of-block when read, hence end-of-file when occurring
742 in the file's last block. It is only needed for variable-length
743 record files transferred to VMS as fixed-length record files
744 (typical for binary FTP; NFS shouldn't need it, but it won't hurt). */
745 md_number_to_chars (RecLen, minus_one, 2);
746 write (VMS_Object_File_FD, RecLen, 2);
747 }
748#else
749 /* When written on a VMS system, the file header (cf inode) will record
750 the actual end-of-file position and no inline marker is needed. */
751#endif
752
753 close (VMS_Object_File_FD);
754}
755
756
757
758 /****** Text Information and Relocation routines ******/
759
760/* Stack Psect base followed by signed, varying-sized offset.
761 Common to several object records. */
762
763static void
764vms_tir_stack_psect (Psect_Index, Offset, Force)
765 int Psect_Index;
766 int Offset;
767 int Force;
768{
769 int psect_width, offset_width;
770
771 psect_width = ((unsigned) Psect_Index > 255) ? 2 : 1;
772 offset_width = (Force || Offset > 32767 || Offset < -32768) ? 4
773 : (Offset > 127 || Offset < -128) ? 2 : 1;
774#define Sta_P(p,o) (((o)<<1) | ((p)-1))
775 /* byte or word psect; byte, word, or longword offset */
776 switch (Sta_P(psect_width,offset_width))
777 {
778 case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB);
779 PUT_CHAR ((char) (unsigned char) Psect_Index);
780 PUT_CHAR ((char) Offset);
781 break;
782 case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW);
783 PUT_CHAR ((char) (unsigned char) Psect_Index);
784 PUT_SHORT (Offset);
785 break;
786 case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL);
787 PUT_CHAR ((char) (unsigned char) Psect_Index);
788 PUT_LONG (Offset);
789 break;
790 case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB);
791 PUT_SHORT (Psect_Index);
792 PUT_CHAR ((char) Offset);
793 break;
794 case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW);
795 PUT_SHORT (Psect_Index);
796 PUT_SHORT (Offset);
797 break;
798 case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL);
799 PUT_SHORT (Psect_Index);
800 PUT_LONG (Offset);
801 break;
802 }
803#undef Sta_P
804}
805
806/* Store immediate data in current Psect. */
807
808static void
809VMS_Store_Immediate_Data (Pointer, Size, Record_Type)
810 const char *Pointer;
811 int Size;
812 int Record_Type;
813{
814 register int i;
815
816 Set_VMS_Object_File_Record (Record_Type);
817 /* We can only store as most 128 bytes at a time due to the way that
818 TIR commands are encoded. */
819 while (Size > 0)
820 {
821 i = (Size > 128) ? 128 : Size;
822 Size -= i;
823 /* If we cannot accommodate this record, flush the buffer. */
824 if ((Object_Record_Offset + i + 1) >= sizeof Object_Record_Buffer)
825 Flush_VMS_Object_Record_Buffer ();
826 /* If the buffer is empty we must insert record type. */
827 if (Object_Record_Offset == 0)
828 PUT_CHAR (Record_Type);
829 /* Store the count. The Store Immediate TIR command is implied by
830 a negative command byte, and the length of the immediate data
831 is abs(command_byte). So, we write the negated length value. */
832 PUT_CHAR ((char) (-i & 0xff));
833 /* Now store the data. */
834 while (--i >= 0)
835 PUT_CHAR (*Pointer++);
836 }
837 /* Flush the buffer if it is more than 75% full. */
838 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
839 Flush_VMS_Object_Record_Buffer ();
840}
841
842/* Make a data reference. */
843
844static void
845VMS_Set_Data (Psect_Index, Offset, Record_Type, Force)
846 int Psect_Index;
847 int Offset;
848 int Record_Type;
849 int Force;
850{
851 Set_VMS_Object_File_Record (Record_Type);
852 /* If the buffer is empty we must insert the record type. */
853 if (Object_Record_Offset == 0)
854 PUT_CHAR (Record_Type);
855 /* Stack the Psect base with its offset. */
856 vms_tir_stack_psect (Psect_Index, Offset, Force);
857 /* Set relocation base. */
858 PUT_CHAR (TIR_S_C_STO_PIDR);
859 /* Flush the buffer if it is more than 75% full. */
860 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
861 Flush_VMS_Object_Record_Buffer ();
862}
863
864/* Make a debugger reference to a struct, union or enum. */
865
866static void
867VMS_Store_Struct (Struct_Index)
868 int Struct_Index;
869{
870 /* We are writing a debug record. */
871 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
872 /* If the buffer is empty we must insert the record type. */
873 if (Object_Record_Offset == 0)
874 PUT_CHAR (OBJ_S_C_DBG);
875 PUT_CHAR (TIR_S_C_STA_UW);
876 PUT_SHORT (Struct_Index);
877 PUT_CHAR (TIR_S_C_CTL_STKDL);
878 PUT_CHAR (TIR_S_C_STO_L);
879 /* Flush the buffer if it is more than 75% full. */
880 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
881 Flush_VMS_Object_Record_Buffer ();
882}
883
884/* Make a debugger reference to partially define a struct, union or enum. */
885
886static void
887VMS_Def_Struct (Struct_Index)
888 int Struct_Index;
889{
890 /* We are writing a debug record. */
891 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
892 /* If the buffer is empty we must insert the record type. */
893 if (Object_Record_Offset == 0)
894 PUT_CHAR (OBJ_S_C_DBG);
895 PUT_CHAR (TIR_S_C_STA_UW);
896 PUT_SHORT (Struct_Index);
897 PUT_CHAR (TIR_S_C_CTL_DFLOC);
898 /* Flush the buffer if it is more than 75% full. */
899 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
900 Flush_VMS_Object_Record_Buffer ();
901}
902
903static void
904VMS_Set_Struct (Struct_Index)
905 int Struct_Index;
906{ /* see previous functions for comments */
907 Set_VMS_Object_File_Record (OBJ_S_C_DBG);
908 if (Object_Record_Offset == 0)
909 PUT_CHAR (OBJ_S_C_DBG);
910 PUT_CHAR (TIR_S_C_STA_UW);
911 PUT_SHORT (Struct_Index);
912 PUT_CHAR (TIR_S_C_CTL_STLOC);
913 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
914 Flush_VMS_Object_Record_Buffer ();
915}
916
917
918
919 /****** Traceback Information routines ******/
920
921/* Write the Traceback Module Begin record. */
922
923static void
924VMS_TBT_Module_Begin ()
925{
926 register char *cp, *cp1;
927 int Size;
928 char Local[256];
929
930 /* Arrange to store the data locally (leave room for size byte). */
931 cp = &Local[1];
932 /* Begin module. */
933 *cp++ = DST_S_C_MODBEG;
934 *cp++ = 0; /* flags; not used */
935 /*
936 * Language type == "C"
937 *
938 * (FIXME: this should be based on the input...)
939 */
940 COPY_LONG (cp, DST_S_C_C);
941 cp += 4;
942 /* Store the module name. */
943 *cp++ = (char) strlen (Module_Name);
944 cp1 = Module_Name;
945 while (*cp1)
946 *cp++ = *cp1++;
947 /* Now we can store the record size. */
948 Size = (cp - Local);
949 Local[0] = Size - 1;
950 /* Put it into the object record. */
951 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
952}
953
954/* Write the Traceback Module End record. */
955
956static void
957VMS_TBT_Module_End ()
958{
959 char Local[2];
960
961 /* End module. */
962 Local[0] = 1;
963 Local[1] = DST_S_C_MODEND;
964 /* Put it into the object record. */
965 VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT);
966}
967
968/* Write a Traceback Routine Begin record. */
969
970static void
971VMS_TBT_Routine_Begin (symbolP, Psect)
972 symbolS *symbolP;
973 int Psect;
974{
975 register char *cp, *cp1;
976 char *Name;
977 int Offset;
978 int Size;
979 char Local[512];
980
981 /* Strip the leading "_" from the name. */
982 Name = S_GET_NAME (symbolP);
983 if (*Name == '_')
984 Name++;
985 /* Get the text psect offset. */
986 Offset = S_GET_VALUE (symbolP);
987 /* Set the record size. */
988 Size = 1 + 1 + 4 + 1 + strlen (Name);
989 Local[0] = Size;
990 /* DST type "routine begin". */
991 Local[1] = DST_S_C_RTNBEG;
992 /* Uses CallS/CallG. */
993 Local[2] = 0;
994 /* Store the data so far. */
995 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
996 /* Make sure we are still generating a OBJ_S_C_TBT record. */
997 if (Object_Record_Offset == 0)
998 PUT_CHAR (OBJ_S_C_TBT);
999 /* Stack the address. */
1000 vms_tir_stack_psect (Psect, Offset, 0);
1001 /* Store the data reference. */
1002 PUT_CHAR (TIR_S_C_STO_PIDR);
1003 /* Store the counted string as data. */
1004 cp = Local;
1005 cp1 = Name;
1006 Size = strlen (cp1) + 1;
1007 *cp++ = Size - 1;
1008 while (*cp1)
1009 *cp++ = *cp1++;
1010 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
1011}
1012
1013/* Write a Traceback Routine End record.
1014
1015 We *must* search the symbol table to find the next routine, since the
1016 assember has a way of reassembling the symbol table OUT OF ORDER Thus
1017 the next routine in the symbol list is not necessarily the next one in
1018 memory. For debugging to work correctly we must know the size of the
1019 routine. */
1020
1021static void
1022VMS_TBT_Routine_End (Max_Size, sp)
1023 int Max_Size;
1024 symbolS *sp;
1025{
1026 symbolS *symbolP;
1027 unsigned long Size = 0x7fffffff;
1028 char Local[16];
1029 valueT sym_value, sp_value = S_GET_VALUE (sp);
1030
1031 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1032 {
1033 if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
1034 {
1035 if (*S_GET_NAME (symbolP) == 'L')
1036 continue;
1037 sym_value = S_GET_VALUE (symbolP);
1038 if (sym_value > sp_value && sym_value < Size)
1039 Size = sym_value;
1040
1041 /*
1042 * Dummy labels like "gcc_compiled." should no longer reach here.
1043 */
1044#if 0
1045 else
1046 /* check if gcc_compiled. has size of zero */
1047 if (sym_value == sp_value &&
1048 sp != symbolP &&
1049 (!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
1050 !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
1051 Size = sym_value;
1052#endif
1053 }
1054 }
1055 if (Size == 0x7fffffff)
1056 Size = Max_Size;
1057 Size -= sp_value; /* and get the size of the routine */
1058 /* Record Size. */
1059 Local[0] = 6;
1060 /* DST type is "routine end". */
1061 Local[1] = DST_S_C_RTNEND;
1062 Local[2] = 0; /* unused */
1063 /* Size of routine. */
1064 COPY_LONG (&Local[3], Size);
1065 /* Store the record. */
1066 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
1067}
1068
1069/* Write a Traceback Block Begin record. */
1070
1071static void
1072VMS_TBT_Block_Begin (symbolP, Psect, Name)
1073 symbolS *symbolP;
1074 int Psect;
1075 char *Name;
1076{
1077 register char *cp, *cp1;
1078 int Offset;
1079 int Size;
1080 char Local[512];
1081
1082 /* Set the record size. */
1083 Size = 1 + 1 + 4 + 1 + strlen (Name);
1084 Local[0] = Size;
1085 /* DST type is "begin block"; we simulate with a phony routine. */
1086 Local[1] = DST_S_C_BLKBEG;
1087 /* Uses CallS/CallG. */
1088 Local[2] = 0;
1089 /* Store the data so far. */
1090 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG);
1091 /* Make sure we are still generating a debug record. */
1092 if (Object_Record_Offset == 0)
1093 PUT_CHAR (OBJ_S_C_DBG);
1094 /* Now get the symbol address. */
1095 PUT_CHAR (TIR_S_C_STA_WPL);
1096 PUT_SHORT (Psect);
1097 /* Get the text psect offset. */
1098 Offset = S_GET_VALUE (symbolP);
1099 PUT_LONG (Offset);
1100 /* Store the data reference. */
1101 PUT_CHAR (TIR_S_C_STO_PIDR);
1102 /* Store the counted string as data. */
1103 cp = Local;
1104 cp1 = Name;
1105 Size = strlen (cp1) + 1;
1106 *cp++ = Size - 1;
1107 while (*cp1)
1108 *cp++ = *cp1++;
1109 VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG);
1110}
1111
1112/* Write a Traceback Block End record. */
1113
1114static void
1115VMS_TBT_Block_End (Size)
1116 valueT Size;
1117{
1118 char Local[16];
1119
1120 Local[0] = 6; /* record length */
1121 /* DST type is "block end"; simulate with a phony end routine. */
1122 Local[1] = DST_S_C_BLKEND;
1123 Local[2] = 0; /* unused, must be zero */
1124 COPY_LONG (&Local[3], Size);
1125 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG);
1126}
1127
1128
1129
1130/* Write a Line number <-> Program Counter correlation record. */
1131
1132static void
1133VMS_TBT_Line_PC_Correlation (Line_Number, Offset, Psect, Do_Delta)
1134 int Line_Number;
1135 int Offset;
1136 int Psect;
1137 int Do_Delta;
1138{
1139 register char *cp;
1140 char Local[64];
1141
1142 if (Do_Delta == 0)
1143 {
1144 /*
1145 * If not delta, set our PC/Line number correlation.
1146 */
1147 cp = &Local[1]; /* Put size in Local[0] later. */
1148 /* DST type is "Line Number/PC correlation". */
1149 *cp++ = DST_S_C_LINE_NUM;
1150 /* Set Line number. */
1151 if (Line_Number - 1 <= 255)
1152 {
1153 *cp++ = DST_S_C_SET_LINUM_B;
1154 *cp++ = (char) (Line_Number - 1);
1155 }
1156 else if (Line_Number - 1 <= 65535)
1157 {
1158 *cp++ = DST_S_C_SET_LINE_NUM;
1159 COPY_SHORT (cp, Line_Number - 1), cp += 2;
1160 }
1161 else
1162 {
1163 *cp++ = DST_S_C_SET_LINUM_L;
1164 COPY_LONG (cp, Line_Number - 1), cp += 4;
1165 }
1166 /* Set PC. */
1167 *cp++ = DST_S_C_SET_ABS_PC;
1168 /* Store size now that we know it, then output the data. */
1169 Local[0] = cp - &Local[1];
1170 /* Account for the space that TIR_S_C_STO_PIDR will use for the PC. */
1171 Local[0] += 4; /* size includes length of another longword */
1172 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1173 /* Make sure we are still generating a OBJ_S_C_TBT record. */
1174 if (Object_Record_Offset == 0)
1175 PUT_CHAR (OBJ_S_C_TBT);
1176 vms_tir_stack_psect (Psect, Offset, 0);
1177 PUT_CHAR (TIR_S_C_STO_PIDR);
1178 /* Do a PC offset of 0 to register the line number. */
1179 Local[0] = 2;
1180 Local[1] = DST_S_C_LINE_NUM;
1181 Local[2] = 0; /* Increment PC by 0 and register line # */
1182 VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
1183 }
1184 else
1185 {
1186 if (Do_Delta < 0)
1187 {
1188 /*
1189 * When delta is negative, terminate the line numbers.
1190 */
1191 Local[0] = 1 + 1 + 4;
1192 Local[1] = DST_S_C_LINE_NUM;
1193 Local[2] = DST_S_C_TERM_L;
1194 COPY_LONG (&Local[3], Offset);
1195 VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
1196 return;
1197 }
1198 /*
1199 * Do a PC/Line delta.
1200 */
1201 cp = &Local[1];
1202 *cp++ = DST_S_C_LINE_NUM;
1203 if (Line_Number > 1)
1204 {
1205 /* We need to increment the line number. */
1206 if (Line_Number - 1 <= 255)
1207 {
1208 *cp++ = DST_S_C_INCR_LINUM;
1209 *cp++ = Line_Number - 1;
1210 }
1211 else if (Line_Number - 1 <= 65535)
1212 {
1213 *cp++ = DST_S_C_INCR_LINUM_W;
1214 COPY_SHORT (cp, Line_Number - 1), cp += 2;
1215 }
1216 else
1217 {
1218 *cp++ = DST_S_C_INCR_LINUM_L;
1219 COPY_LONG (cp, Line_Number - 1), cp += 4;
1220 }
1221 }
1222 /*
1223 * Increment the PC
1224 */
1225 if (Offset <= 128)
1226 {
1227 /* Small offsets are encoded as negative numbers, rather than the
1228 usual non-negative type code followed by another data field. */
1229 *cp++ = (char) -Offset;
1230 }
1231 else if (Offset <= 65535)
1232 {
1233 *cp++ = DST_S_C_DELTA_PC_W;
1234 COPY_SHORT (cp, Offset), cp += 2;
1235 }
1236 else
1237 {
1238 *cp++ = DST_S_C_DELTA_PC_L;
1239 COPY_LONG (cp, Offset), cp += 4;
1240 }
1241 /* Set size now that be know it, then output the data. */
1242 Local[0] = cp - &Local[1];
1243 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1244 }
1245}
1246
1247
1248
1249/* Describe a source file to the debugger. */
1250
1251static int
1252VMS_TBT_Source_File (Filename, ID_Number)
1253 char *Filename;
1254 int ID_Number;
1255{
1256 register char *cp;
1257 int len, rfo, ffb, ebk;
1258 char cdt[8];
1259 char Local[512];
1260#ifdef VMS /* Used for native assembly */
1261 unsigned Status;
1262 struct FAB fab; /* RMS file access block */
1263 struct NAM nam; /* file name information */
1264 struct XABDAT xabdat; /* date+time fields */
1265 struct XABFHC xabfhc; /* file header characteristics */
1266 char resultant_string_buffer[255 + 1];
1267
1268 /*
1269 * Set up RMS structures:
1270 */
1271 /* FAB -- file access block */
1272 memset ((char *) &fab, 0, sizeof fab);
1273 fab.fab$b_bid = FAB$C_BID;
1274 fab.fab$b_bln = (unsigned char) sizeof fab;
1275 fab.fab$l_fna = Filename;
1276 fab.fab$b_fns = (unsigned char) strlen (Filename);
1277 fab.fab$l_nam = (char *) &nam;
1278 fab.fab$l_xab = (char *) &xabdat;
1279 /* NAM -- file name block */
1280 memset ((char *) &nam, 0, sizeof nam);
1281 nam.nam$b_bid = NAM$C_BID;
1282 nam.nam$b_bln = (unsigned char) sizeof nam;
1283 nam.nam$l_rsa = resultant_string_buffer;
1284 nam.nam$b_rss = (unsigned char) (sizeof resultant_string_buffer - 1);
1285 /* XABs -- extended attributes blocks */
1286 memset ((char *) &xabdat, 0, sizeof xabdat);
1287 xabdat.xab$b_cod = XAB$C_DAT;
1288 xabdat.xab$b_bln = (unsigned char) sizeof xabdat;
1289 xabdat.xab$l_nxt = (char *) &xabfhc;
1290 memset ((char *) &xabfhc, 0, sizeof xabfhc);
1291 xabfhc.xab$b_cod = XAB$C_FHC;
1292 xabfhc.xab$b_bln = (unsigned char) sizeof xabfhc;
1293 xabfhc.xab$l_nxt = 0;
1294 /*
1295 * Get the file information
1296 */
1297 Status = sys$open (&fab);
1298 if (!(Status & 1))
1299 {
1300 as_tsktsk (_("Couldn't find source file \"%s\", status=%%X%x"),
1301 Filename, Status);
1302 return 0;
1303 }
1304 sys$close (&fab);
1305 /* Now extract fields of interest. */
1306 memcpy (cdt, (char *) &xabdat.xab$q_cdt, 8); /* creation date */
1307 ebk = xabfhc.xab$l_ebk; /* end-of-file block */
1308 ffb = xabfhc.xab$w_ffb; /* first free byte of last block */
1309 rfo = xabfhc.xab$b_rfo; /* record format */
1310 len = nam.nam$b_rsl; /* length of Filename */
1311 resultant_string_buffer[len] = '\0';
1312 Filename = resultant_string_buffer; /* full filename */
1313#else /* Cross-assembly */
1314 /* [Perhaps we ought to use actual values derived from stat() here?] */
1315 memset (cdt, 0, 8); /* null VMS quadword binary time */
1316 ebk = ffb = rfo = 0;
1317 len = strlen (Filename);
1318 if (len > 255) /* a single byte is used as count prefix */
1319 {
1320 Filename += (len - 255); /* tail end is more significant */
1321 len = 255;
1322 }
1323#endif /* VMS */
1324
1325 cp = &Local[1]; /* fill in record length later */
1326 *cp++ = DST_S_C_SOURCE; /* DST type is "source file" */
1327 *cp++ = DST_S_C_SRC_FORMFEED; /* formfeeds count as source records */
1328 *cp++ = DST_S_C_SRC_DECLFILE; /* declare source file */
1329 know (cp == &Local[4]);
1330 *cp++ = 0; /* fill in this length below */
1331 *cp++ = 0; /* flags; must be zero */
1332 COPY_SHORT (cp, ID_Number), cp += 2; /* file ID number */
1333 memcpy (cp, cdt, 8), cp += 8; /* creation date+time */
1334 COPY_LONG (cp, ebk), cp += 4; /* end-of-file block */
1335 COPY_SHORT (cp, ffb), cp += 2; /* first free byte of last block */
1336 *cp++ = (char) rfo; /* RMS record format */
1337 /* Filename. */
1338 *cp++ = (char) len;
1339 while (--len >= 0)
1340 *cp++ = *Filename++;
1341 /* Library module name (none). */
1342 *cp++ = 0;
1343 /* Now that size is known, fill it in and write out the record. */
1344 Local[4] = cp - &Local[5]; /* source file declaration size */
1345 Local[0] = cp - &Local[1]; /* TBT record size */
1346 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1347 return 1;
1348}
1349
1350/* Traceback information is described in terms of lines from compiler
1351 listing files, not lines from source files. We need to set up the
1352 correlation between listing line numbers and source line numbers.
1353 Since gcc's .stabn directives refer to the source lines, we just
1354 need to describe a one-to-one correspondence. */
1355
1356static void
1357VMS_TBT_Source_Lines (ID_Number, Starting_Line_Number, Number_Of_Lines)
1358 int ID_Number;
1359 int Starting_Line_Number;
1360 int Number_Of_Lines;
1361{
1362 char *cp;
1363 int chunk_limit;
1364 char Local[128]; /* room enough to describe 1310700 lines... */
1365
1366 cp = &Local[1]; /* Put size in Local[0] later. */
1367 *cp++ = DST_S_C_SOURCE; /* DST type is "source file". */
1368 *cp++ = DST_S_C_SRC_SETFILE; /* Set Source File. */
1369 COPY_SHORT (cp, ID_Number), cp += 2; /* File ID Number. */
1370 /* Set record number and define lines. Since no longword form of
1371 SRC_DEFLINES is available, we need to be able to cope with any huge
1372 files a chunk at a time. It doesn't matter for tracebacks, since
1373 unspecified lines are mapped one-to-one and work out right, but it
1374 does matter within the debugger. Without this explicit mapping,
1375 it will complain about lines not existing in the module. */
1376 chunk_limit = (sizeof Local - 5) / 6;
1377 if (Number_Of_Lines > 65535 * chunk_limit) /* avoid buffer overflow */
1378 Number_Of_Lines = 65535 * chunk_limit;
1379 while (Number_Of_Lines > 65535)
1380 {
1381 *cp++ = DST_S_C_SRC_SETREC_L;
1382 COPY_LONG (cp, Starting_Line_Number), cp += 4;
1383 *cp++ = DST_S_C_SRC_DEFLINES_W;
1384 COPY_SHORT (cp, 65535), cp += 2;
1385 Starting_Line_Number += 65535;
1386 Number_Of_Lines -= 65535;
1387 }
1388 /* Set record number and define lines, normal case. */
1389 if (Starting_Line_Number <= 65535)
1390 {
1391 *cp++ = DST_S_C_SRC_SETREC_W;
1392 COPY_SHORT (cp, Starting_Line_Number), cp += 2;
1393 }
1394 else
1395 {
1396 *cp++ = DST_S_C_SRC_SETREC_L;
1397 COPY_LONG (cp, Starting_Line_Number), cp += 4;
1398 }
1399 *cp++ = DST_S_C_SRC_DEFLINES_W;
1400 COPY_SHORT (cp, Number_Of_Lines), cp += 2;
1401 /* Set size now that be know it, then output the data. */
1402 Local[0] = cp - &Local[1];
1403 VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
1404}
1405
1406
1407
1408 /****** Debugger Information support routines ******/
1409
1410/* This routine locates a file in the list of files. If an entry does
1411 not exist, one is created. For include files, a new entry is always
1412 created such that inline functions can be properly debugged. */
1413
1414static struct input_file *
1415find_file (sp)
1416 symbolS *sp;
1417{
1418 struct input_file *same_file = 0;
1419 struct input_file *fpnt, *last = 0;
1420 char *sp_name;
1421
1422 for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1423 {
1424 if (fpnt->spnt == sp)
1425 return fpnt;
1426 last = fpnt;
1427 }
1428 sp_name = S_GET_NAME (sp);
1429 for (fpnt = file_root; fpnt; fpnt = fpnt->next)
1430 {
1431 if (strcmp (sp_name, fpnt->name) == 0)
1432 {
1433 if (fpnt->flag == 1)
1434 return fpnt;
1435 same_file = fpnt;
1436 break;
1437 }
1438 }
1439 fpnt = (struct input_file *) xmalloc (sizeof (struct input_file));
1440 if (!file_root)
1441 file_root = fpnt;
1442 else
1443 last->next = fpnt;
1444 fpnt->next = 0;
1445 fpnt->name = sp_name;
1446 fpnt->min_line = 0x7fffffff;
1447 fpnt->max_line = 0;
1448 fpnt->offset = 0;
1449 fpnt->flag = 0;
1450 fpnt->file_number = 0;
1451 fpnt->spnt = sp;
1452 fpnt->same_file_fpnt = same_file;
1453 return fpnt;
1454}
1455
1456/* This routine converts a number string into an integer, and stops when
1457 it sees an invalid character. The return value is the address of the
1458 character just past the last character read. No error is generated. */
1459
1460static char *
1461cvt_integer (str, rtn)
1462 char *str;
1463 int *rtn;
1464{
1465 int ival = 0, sgn = 1;
1466
1467 if (*str == '-')
1468 sgn = -1, ++str;
1469 while (*str >= '0' && *str <= '9')
1470 ival = 10 * ival + *str++ - '0';
1471 *rtn = sgn * ival;
1472 return str;
1473}
1474
1475
1476
1477/*
1478 * The following functions and definitions are used to generate object
1479 * records that will describe program variables to the VMS debugger.
1480 *
1481 * This file contains many of the routines needed to output debugging info
1482 * into the object file that the VMS debugger needs to understand symbols.
1483 * These routines are called very late in the assembly process, and thus
1484 * we can be fairly lax about changing things, since the GSD and the TIR
1485 * sections have already been output.
1486 */
1487
1488/* This routine fixes the names that are generated by C++, ".this" is a good
1489 example. The period does not work for the debugger, since it looks like
1490 the syntax for a structure element, and thus it gets mightily confused.
1491
1492 We also use this to strip the PsectAttribute hack from the name before we
1493 write a debugger record. */
1494
1495static char *
1496fix_name (pnt)
1497 char *pnt;
1498{
1499 char *pnt1;
1500
1501 /* Kill any leading "_". */
1502 if (*pnt == '_')
1503 pnt++;
1504
1505 /* Is there a Psect Attribute to skip?? */
1506 if (HAS_PSECT_ATTRIBUTES (pnt))
1507 {
1508 /* Yes: Skip it. */
1509 pnt += PSECT_ATTRIBUTES_STRING_LENGTH;
1510 while (*pnt)
1511 {
1512 if ((pnt[0] == '$') && (pnt[1] == '$'))
1513 {
1514 pnt += 2;
1515 break;
1516 }
1517 pnt++;
1518 }
1519 }
1520
1521 /* Here we fix the .this -> $this conversion. */
1522 for (pnt1 = pnt; *pnt1 != 0; pnt1++)
1523 if (*pnt1 == '.')
1524 *pnt1 = '$';
1525
1526 return pnt;
1527}
1528
1529/* When defining a structure, this routine is called to find the name of
1530 the actual structure. It is assumed that str points to the equal sign
1531 in the definition, and it moves backward until it finds the start of the
1532 name. If it finds a 0, then it knows that this structure def is in the
1533 outermost level, and thus symbol_name points to the symbol name. */
1534
1535static char *
1536get_struct_name (str)
1537 char *str;
1538{
1539 char *pnt;
1540 pnt = str;
1541 while ((*pnt != ':') && (*pnt != '\0'))
1542 pnt--;
1543 if (*pnt == '\0')
1544 return (char *) symbol_name;
1545 *pnt-- = '\0';
1546 while ((*pnt != ';') && (*pnt != '='))
1547 pnt--;
1548 if (*pnt == ';')
1549 return pnt + 1;
1550 while ((*pnt < '0') || (*pnt > '9'))
1551 pnt++;
1552 while ((*pnt >= '0') && (*pnt <= '9'))
1553 pnt++;
1554 return pnt;
1555}
1556
1557/* Search symbol list for type number dbx_type.
1558 Return a pointer to struct. */
1559
1560static struct VMS_DBG_Symbol *
1561find_symbol (dbx_type)
1562 int dbx_type;
1563{
1564 struct VMS_DBG_Symbol *spnt;
1565
1566 spnt = VMS_Symbol_type_list[SYMTYP_HASH (dbx_type)];
1567 while (spnt)
1568 {
1569 if (spnt->dbx_type == dbx_type)
1570 break;
1571 spnt = spnt->next;
1572 }
1573 if (!spnt || spnt->advanced != ALIAS)
1574 return spnt;
1575 return find_symbol (spnt->type2);
1576}
1577
1578#if 0 /* obsolete */
1579/* this routine puts info into either Local or Asuffix, depending on the sign
1580 * of size. The reason is that it is easier to build the variable descriptor
1581 * backwards, while the array descriptor is best built forwards. In the end
1582 * they get put together, if there is not a struct/union/enum along the way
1583 */
1584static void
1585push (value, size1)
1586 int value, size1;
1587{
1588 if (size1 < 0)
1589 {
1590 size1 = -size1;
1591 if (Lpnt < size1)
1592 {
1593 overflow = 1;
1594 Lpnt = 1;
1595 return;
1596 }
1597 Lpnt -= size1;
1598 md_number_to_chars (&Local[Lpnt + 1], value, size1);
1599 }
1600 else
1601 {
1602 if (Apoint + size1 >= MAX_DEBUG_RECORD)
1603 {
1604 overflow = 1;
1605 Apoint = MAX_DEBUG_RECORD - 1;
1606 return;
1607 }
1608 md_number_to_chars (&Asuffix[Apoint], value, size1);
1609 Apoint += size1;
1610 }
1611}
1612#endif
1613
1614static void
1615fpush (value, size)
1616 int value, size;
1617{
1618 if (Apoint + size >= MAX_DEBUG_RECORD)
1619 {
1620 overflow = 1;
1621 Apoint = MAX_DEBUG_RECORD - 1;
1622 return;
1623 }
1624 if (size == 1)
1625 Asuffix[Apoint++] = (char) value;
1626 else
1627 {
1628 md_number_to_chars (&Asuffix[Apoint], value, size);
1629 Apoint += size;
1630 }
1631}
1632
1633static void
1634rpush (value, size)
1635 int value, size;
1636{
1637 if (Lpnt < size)
1638 {
1639 overflow = 1;
1640 Lpnt = 1;
1641 return;
1642 }
1643 if (size == 1)
1644 Local[Lpnt--] = (char) value;
1645 else
1646 {
1647 Lpnt -= size;
1648 md_number_to_chars (&Local[Lpnt + 1], value, size);
1649 }
1650}
1651
1652/* This routine generates the array descriptor for a given array. */
1653
1654static void
1655array_suffix (spnt2)
1656 struct VMS_DBG_Symbol *spnt2;
1657{
1658 struct VMS_DBG_Symbol *spnt;
1659 struct VMS_DBG_Symbol *spnt1;
1660 int rank;
1661 int total_size;
1662
1663 rank = 0;
1664 spnt = spnt2;
1665 while (spnt->advanced != ARRAY)
1666 {
1667 spnt = find_symbol (spnt->type2);
1668 if (!spnt)
1669 return;
1670 }
1671 spnt1 = spnt;
1672 total_size = 1;
1673 while (spnt1->advanced == ARRAY)
1674 {
1675 rank++;
1676 total_size *= (spnt1->index_max - spnt1->index_min + 1);
1677 spnt1 = find_symbol (spnt1->type2);
1678 }
1679 total_size = total_size * spnt1->data_size;
1680 fpush (spnt1->data_size, 2); /* element size */
1681 if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
1682 fpush (0, 1);
1683 else
1684 fpush (spnt1->VMS_type, 1); /* element type */
1685 fpush (DSC_K_CLASS_A, 1); /* descriptor class */
1686 fpush (0, 4); /* base address */
1687 fpush (0, 1); /* scale factor -- not applicable */
1688 fpush (0, 1); /* digit count -- not applicable */
1689 fpush (0xc0, 1); /* flags: multiplier block & bounds present */
1690 fpush (rank, 1); /* number of dimensions */
1691 fpush (total_size, 4);
1692 fpush (0, 4); /* pointer to element [0][0]...[0] */
1693 spnt1 = spnt;
1694 while (spnt1->advanced == ARRAY)
1695 {
1696 fpush (spnt1->index_max - spnt1->index_min + 1, 4);
1697 spnt1 = find_symbol (spnt1->type2);
1698 }
1699 spnt1 = spnt;
1700 while (spnt1->advanced == ARRAY)
1701 {
1702 fpush (spnt1->index_min, 4);
1703 fpush (spnt1->index_max, 4);
1704 spnt1 = find_symbol (spnt1->type2);
1705 }
1706}
1707
1708/* This routine generates the start of a variable descriptor based upon
1709 a struct/union/enum that has yet to be defined. We define this spot as
1710 a new location, and save four bytes for the address. When the struct is
1711 finally defined, then we can go back and plug in the correct address. */
1712
1713static void
1714new_forward_ref (dbx_type)
1715 int dbx_type;
1716{
1717 struct forward_ref *fpnt;
1718 fpnt = (struct forward_ref *) xmalloc (sizeof (struct forward_ref));
1719 fpnt->next = f_ref_root;
1720 f_ref_root = fpnt;
1721 fpnt->dbx_type = dbx_type;
1722 fpnt->struc_numb = ++structure_count;
1723 fpnt->resolved = 'N';
1724 rpush (DST_K_TS_IND, 1); /* indirect type specification */
1725 total_len = 5;
1726 rpush (total_len, 2);
1727 struct_number = -fpnt->struc_numb;
1728}
1729
1730/* This routine generates the variable descriptor used to describe non-basic
1731 variables. It calls itself recursively until it gets to the bottom of it
1732 all, and then builds the descriptor backwards. It is easiest to do it
1733 this way since we must periodically write length bytes, and it is easiest
1734 if we know the value when it is time to write it. */
1735
1736static int
1737gen1 (spnt, array_suffix_len)
1738 struct VMS_DBG_Symbol *spnt;
1739 int array_suffix_len;
1740{
1741 struct VMS_DBG_Symbol *spnt1;
1742 int i;
1743
1744 switch (spnt->advanced)
1745 {
1746 case VOID:
1747 rpush (DBG_S_C_VOID, 1);
1748 total_len += 1;
1749 rpush (total_len, 2);
1750 return 0;
1751 case BASIC:
1752 case FUNCTION:
1753 if (array_suffix_len == 0)
1754 {
1755 rpush (spnt->VMS_type, 1);
1756 rpush (DBG_S_C_BASIC, 1);
1757 total_len = 2;
1758 rpush (total_len, 2);
1759 return 1;
1760 }
1761 rpush (0, 4);
1762 rpush (DST_K_VFLAGS_DSC, 1);
1763 rpush (DST_K_TS_DSC, 1); /* descriptor type specification */
1764 total_len = -2;
1765 return 1;
1766 case STRUCT:
1767 case UNION:
1768 case ENUM:
1769 struct_number = spnt->struc_numb;
1770 if (struct_number < 0)
1771 {
1772 new_forward_ref (spnt->dbx_type);
1773 return 1;
1774 }
1775 rpush (DBG_S_C_STRUCT, 1);
1776 total_len = 5;
1777 rpush (total_len, 2);
1778 return 1;
1779 case POINTER:
1780 spnt1 = find_symbol (spnt->type2);
1781 i = 1;
1782 if (!spnt1)
1783 new_forward_ref (spnt->type2);
1784 else
1785 i = gen1 (spnt1, 0);
1786 if (i)
1787 { /* (*void) is a special case, do not put pointer suffix */
1788 rpush (DBG_S_C_POINTER, 1);
1789 total_len += 3;
1790 rpush (total_len, 2);
1791 }
1792 return 1;
1793 case ARRAY:
1794 spnt1 = spnt;
1795 while (spnt1->advanced == ARRAY)
1796 {
1797 spnt1 = find_symbol (spnt1->type2);
1798 if (!spnt1)
1799 {
1800 as_tsktsk (_("debugger forward reference error, dbx type %d"),
1801 spnt->type2);
1802 return 0;
1803 }
1804 }
1805/* It is too late to generate forward references, so the user gets a message.
1806 * This should only happen on a compiler error */
1807 (void) gen1 (spnt1, 1);
1808 i = Apoint;
1809 array_suffix (spnt);
1810 array_suffix_len = Apoint - i;
1811 switch (spnt1->advanced)
1812 {
1813 case BASIC:
1814 case FUNCTION:
1815 break;
1816 default:
1817 rpush (0, 2);
1818 total_len += 2;
1819 rpush (total_len, 2);
1820 rpush (DST_K_VFLAGS_DSC, 1);
1821 rpush (1, 1); /* flags: element value spec included */
1822 rpush (1, 1); /* one dimension */
1823 rpush (DBG_S_C_COMPLEX_ARRAY, 1);
1824 }
1825 total_len += array_suffix_len + 8;
1826 rpush (total_len, 2);
1827 break;
1828 default: /* lint suppression */
1829 break;
1830 }
1831 return 0;
1832}
1833
1834/* This generates a suffix for a variable. If it is not a defined type yet,
1835 then dbx_type contains the type we are expecting so we can generate a
1836 forward reference. This calls gen1 to build most of the descriptor, and
1837 then it puts the icing on at the end. It then dumps whatever is needed
1838 to get a complete descriptor (i.e. struct reference, array suffix). */
1839
1840static void
1841generate_suffix (spnt, dbx_type)
1842 struct VMS_DBG_Symbol *spnt;
1843 int dbx_type;
1844{
1845 static const char pvoid[6] = {
1846 5, /* record.length == 5 */
1847 DST_K_TYPSPEC, /* record.type == 1 (type specification) */
1848 0, /* name.length == 0, no name follows */
1849 1, 0, /* type.length == 1 {2 bytes, little endian} */
1850 DBG_S_C_VOID /* type.type == 5 (pointer to unspecified) */
1851 };
1852 int i;
1853
1854 Apoint = 0;
1855 Lpnt = MAX_DEBUG_RECORD - 1;
1856 total_len = 0;
1857 struct_number = 0;
1858 overflow = 0;
1859 if (!spnt)
1860 new_forward_ref (dbx_type);
1861 else
1862 {
1863 if (spnt->VMS_type != DBG_S_C_ADVANCED_TYPE)
1864 return; /* no suffix needed */
1865 gen1 (spnt, 0);
1866 }
1867 rpush (0, 1); /* no name (len==0) */
1868 rpush (DST_K_TYPSPEC, 1);
1869 total_len += 4;
1870 rpush (total_len, 1);
1871 /* If the variable descriptor overflows the record, output a descriptor
1872 for a pointer to void. */
1873 if ((total_len >= MAX_DEBUG_RECORD) || overflow)
1874 {
1875 as_warn (_("Variable descriptor %d too complicated. Defined as `void *'."),
1876 spnt->dbx_type);
1877 VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG);
1878 return;
1879 }
1880 i = 0;
1881 while (Lpnt < MAX_DEBUG_RECORD - 1)
1882 Local[i++] = Local[++Lpnt];
1883 Lpnt = i;
1884 /* we use this for reference to structure that has already been defined */
1885 if (struct_number > 0)
1886 {
1887 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1888 Lpnt = 0;
1889 VMS_Store_Struct (struct_number);
1890 }
1891 /* We use this for a forward reference to a structure that has yet to
1892 be defined. We store four bytes of zero to make room for the actual
1893 address once it is known. */
1894 if (struct_number < 0)
1895 {
1896 struct_number = -struct_number;
1897 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1898 Lpnt = 0;
1899 VMS_Def_Struct (struct_number);
1900 COPY_LONG (&Local[Lpnt], 0L);
1901 Lpnt += 4;
1902 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1903 Lpnt = 0;
1904 }
1905 i = 0;
1906 while (i < Apoint)
1907 Local[Lpnt++] = Asuffix[i++];
1908 if (Lpnt != 0)
1909 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1910 Lpnt = 0;
1911}
1912
1913 /* "novel length" type doesn't work for simple atomic types */
1914#define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
1915#undef SETUP_BASIC_TYPES
1916
1917/* This routine generates a type description for a bitfield. */
1918
1919static void
1920bitfield_suffix (spnt, width)
1921 struct VMS_DBG_Symbol *spnt;
1922 int width;
1923{
1924 Local[Lpnt++] = 13; /* rec.len==13 */
1925 Local[Lpnt++] = DST_K_TYPSPEC; /* a type specification record */
1926 Local[Lpnt++] = 0; /* not named */
1927 COPY_SHORT (&Local[Lpnt], 9); /* typ.len==9 */
1928 Lpnt += 2;
1929 Local[Lpnt++] = DST_K_TS_NOV_LENG; /* This type is a "novel length"
1930 incarnation of some other type. */
1931 COPY_LONG (&Local[Lpnt], width); /* size in bits == novel length */
1932 Lpnt += 4;
1933 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1934 Lpnt = 0;
1935 /* assert( spnt->struc_numb > 0 ); */
1936 VMS_Store_Struct (spnt->struc_numb); /* output 4 more bytes */
1937}
1938
1939/* Formally define a builtin type, so that it can serve as the target of
1940 an indirect reference. It makes bitfield_suffix() easier by avoiding
1941 the need to use a forward reference for the first occurrence of each
1942 type used in a bitfield. */
1943
1944static void
1945setup_basic_type (spnt)
1946 struct VMS_DBG_Symbol *spnt ATTRIBUTE_UNUSED;
1947{
1948#ifdef SETUP_BASIC_TYPES
1949 /* This would be very useful if "novel length" fields actually worked
1950 with basic types like they do with enumerated types. However,
1951 they do not, so this isn't worth doing just so that you can use
1952 EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
1953 char *p;
1954#ifndef SETUP_SYNONYM_TYPES
1955 /* This determines whether compatible things like `int' and `long int'
1956 ought to have distinct type records rather than sharing one. */
1957 struct VMS_DBG_Symbol *spnt2;
1958
1959 /* first check whether this type has already been seen by another name */
1960 for (spnt2 = VMS_Symbol_type_list[SYMTYP_HASH (spnt->VMS_type)];
1961 spnt2;
1962 spnt2 = spnt2->next)
1963 if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type)
1964 {
1965 spnt->struc_numb = spnt2->struc_numb;
1966 return;
1967 }
1968#endif
1969
1970 /* `structure number' doesn't really mean `structure'; it means an index
1971 into a linker maintained set of saved locations which can be referenced
1972 again later. */
1973 spnt->struc_numb = ++structure_count;
1974 VMS_Def_Struct (spnt->struc_numb); /* remember where this type lives */
1975 /* define the simple scalar type */
1976 Local[Lpnt++] = 6 + strlen (symbol_name) + 2; /* rec.len */
1977 Local[Lpnt++] = DST_K_TYPSPEC; /* rec.typ==type specification */
1978 Local[Lpnt++] = strlen (symbol_name) + 2;
1979 Local[Lpnt++] = '_'; /* prefix name with "__" */
1980 Local[Lpnt++] = '_';
1981 for (p = symbol_name; *p; p++)
1982 Local[Lpnt++] = *p == ' ' ? '_' : *p;
1983 COPY_SHORT (&Local[Lpnt], 2); /* typ.len==2 */
1984 Lpnt += 2;
1985 Local[Lpnt++] = DST_K_TS_ATOM; /* typ.kind is simple type */
1986 Local[Lpnt++] = spnt->VMS_type; /* typ.type */
1987 VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
1988 Lpnt = 0;
1989#endif /* SETUP_BASIC_TYPES */
1990 return;
1991}
1992
1993/* This routine generates a symbol definition for a C symbol for the debugger.
1994 It takes a psect and offset for global symbols; if psect < 0, then this is
1995 a local variable and the offset is relative to FP. In this case it can
1996 be either a variable (Offset < 0) or a parameter (Offset > 0). */
1997
1998static void
1999VMS_DBG_record (spnt, Psect, Offset, Name)
2000 struct VMS_DBG_Symbol *spnt;
2001 int Psect;
2002 int Offset;
2003 char *Name;
2004{
2005 char *Name_pnt;
2006 int len;
2007 int i = 0;
2008
2009 /* if there are bad characters in name, convert them */
2010 Name_pnt = fix_name (Name);
2011
2012 len = strlen (Name_pnt);
2013 if (Psect < 0)
2014 { /* this is a local variable, referenced to SP */
2015 Local[i++] = 7 + len;
2016 Local[i++] = spnt->VMS_type;
2017 Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM;
2018 COPY_LONG (&Local[i], Offset);
2019 i += 4;
2020 }
2021 else
2022 {
2023 Local[i++] = 7 + len;
2024 Local[i++] = spnt->VMS_type;
2025 Local[i++] = DST_K_VALKIND_ADDR;
2026 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2027 i = 0;
2028 VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
2029 }
2030 Local[i++] = len;
2031 while (*Name_pnt != '\0')
2032 Local[i++] = *Name_pnt++;
2033 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2034 if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
2035 generate_suffix (spnt, 0);
2036}
2037
2038/* This routine parses the stabs entries in order to make the definition
2039 for the debugger of local symbols and function parameters. */
2040
2041static void
2042VMS_local_stab_Parse (sp)
2043 symbolS *sp;
2044{
2045 struct VMS_DBG_Symbol *spnt;
2046 char *pnt;
2047 char *pnt1;
2048 char *str;
2049 int dbx_type;
2050
2051 dbx_type = 0;
2052 str = S_GET_NAME (sp);
2053 pnt = (char *) strchr (str, ':');
2054 if (!pnt)
2055 return; /* no colon present */
2056 pnt1 = pnt++; /* save this for later, and skip colon */
2057 if (*pnt == 'c')
2058 return; /* ignore static constants */
2059
2060/* there is one little catch that we must be aware of. Sometimes function
2061 * parameters are optimized into registers, and the compiler, in its infiite
2062 * wisdom outputs stabs records for *both*. In general we want to use the
2063 * register if it is present, so we must search the rest of the symbols for
2064 * this function to see if this parameter is assigned to a register.
2065 */
2066 {
2067 symbolS *sp1;
2068 char *str1;
2069 char *pnt2;
2070
2071 if (*pnt == 'p')
2072 {
2073 for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1))
2074 {
2075 if (!S_IS_DEBUG (sp1))
2076 continue;
2077 if (S_GET_RAW_TYPE (sp1) == N_FUN)
2078 {
2079 pnt2 = (char *) strchr (S_GET_NAME (sp1), ':') + 1;
2080 if (*pnt2 == 'F' || *pnt2 == 'f')
2081 break;
2082 }
2083 if (S_GET_RAW_TYPE (sp1) != N_RSYM)
2084 continue;
2085 str1 = S_GET_NAME (sp1); /* and get the name */
2086 pnt2 = str;
2087 while (*pnt2 != ':')
2088 {
2089 if (*pnt2 != *str1)
2090 break;
2091 pnt2++;
2092 str1++;
2093 }
2094 if (*str1 == ':' && *pnt2 == ':')
2095 return; /* They are the same! Let's skip this one. */
2096 } /* for */
2097 pnt++; /* skip p in case no register */
2098 } /* if */
2099 } /* p block */
2100
2101 pnt = cvt_integer (pnt, &dbx_type);
2102 spnt = find_symbol (dbx_type);
2103 if (!spnt)
2104 return; /*Dunno what this is*/
2105 *pnt1 = '\0';
2106 VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
2107 *pnt1 = ':'; /* and restore the string */
2108 return;
2109}
2110
2111/* This routine parses a stabs entry to find the information required
2112 to define a variable. It is used for global and static variables.
2113 Basically we need to know the address of the symbol. With older
2114 versions of the compiler, const symbols are treated differently, in
2115 that if they are global they are written into the text psect. The
2116 global symbol entry for such a const is actually written as a program
2117 entry point (Yuk!!), so if we cannot find a symbol in the list of
2118 psects, we must search the entry points as well. static consts are
2119 even harder, since they are never assigned a memory address. The
2120 compiler passes a stab to tell us the value, but I am not sure what
2121 to do with it. */
2122
2123static void
2124VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect)
2125 symbolS *sp;
2126 int expected_type; /* char */
2127 int type1, type2, Text_Psect;
2128{
2129 char *pnt;
2130 char *pnt1;
2131 char *str;
2132 symbolS *sp1;
2133 struct VMS_DBG_Symbol *spnt;
2134 struct VMS_Symbol *vsp;
2135 int dbx_type;
2136
2137 dbx_type = 0;
2138 str = S_GET_NAME (sp);
2139 pnt = (char *) strchr (str, ':');
2140 if (!pnt)
2141 return; /* no colon present */
2142 pnt1 = pnt; /* save this for later*/
2143 pnt++;
2144 if (*pnt == expected_type)
2145 {
2146 pnt = cvt_integer (pnt + 1, &dbx_type);
2147 spnt = find_symbol (dbx_type);
2148 if (!spnt)
2149 return; /*Dunno what this is*/
2150 /*
2151 * Now we need to search the symbol table to find the psect and
2152 * offset for this variable.
2153 */
2154 *pnt1 = '\0';
2155 vsp = VMS_Symbols;
2156 while (vsp)
2157 {
2158 pnt = S_GET_NAME (vsp->Symbol);
2159 if (pnt && *pnt++ == '_'
2160 /* make sure name is the same and symbol type matches */
2161 && strcmp (pnt, str) == 0
2162 && (S_GET_RAW_TYPE (vsp->Symbol) == type1
2163 || S_GET_RAW_TYPE (vsp->Symbol) == type2))
2164 break;
2165 vsp = vsp->Next;
2166 }
2167 if (vsp)
2168 {
2169 VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str);
2170 *pnt1 = ':'; /* and restore the string */
2171 return;
2172 }
2173 /* The symbol was not in the symbol list, but it may be an
2174 "entry point" if it was a constant. */
2175 for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
2176 {
2177 /*
2178 * Dispatch on STAB type
2179 */
2180 if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT))
2181 continue;
2182 pnt = S_GET_NAME (sp1);
2183 if (*pnt == '_')
2184 pnt++;
2185 if (strcmp (pnt, str) == 0)
2186 {
2187 if (!gave_compiler_message && expected_type == 'G')
2188 {
2189 char *long_const_msg = _("\
2190***Warning - the assembly code generated by the compiler has placed \n\
2191 global constant(s) in the text psect. These will not be available to \n\
2192 other modules, since this is not the correct way to handle this. You \n\
2193 have two options: 1) get a patched compiler that does not put global \n\
2194 constants in the text psect, or 2) remove the 'const' keyword from \n\
2195 definitions of global variables in your source module(s). Don't say \n\
2196 I didn't warn you! \n");
2197
2198 as_tsktsk (long_const_msg);
2199 gave_compiler_message = 1;
2200 }
2201 VMS_DBG_record (spnt,
2202 Text_Psect,
2203 S_GET_VALUE (sp1),
2204 str);
2205 *pnt1 = ':';
2206 /* fool assembler to not output this as a routine in the TBT */
2207 pnt1 = S_GET_NAME (sp1);
2208 *pnt1 = 'L';
2209 S_SET_NAME (sp1, pnt1);
2210 return;
2211 }
2212 }
2213 }
2214 *pnt1 = ':'; /* and restore the string */
2215 return;
2216}
2217
2218/* Simpler interfaces into VMS_stab_parse(). */
2219
2220static void
2221VMS_GSYM_Parse (sp, Text_Psect)
2222 symbolS *sp;
2223 int Text_Psect;
2224{ /* Global variables */
2225 VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect);
2226}
2227
2228static void
2229VMS_LCSYM_Parse (sp, Text_Psect)
2230 symbolS *sp;
2231 int Text_Psect;
2232{ /* Static symbols - uninitialized */
2233 VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
2234}
2235
2236static void
2237VMS_STSYM_Parse (sp, Text_Psect)
2238 symbolS *sp;
2239 int Text_Psect;
2240{ /* Static symbols - initialized */
2241 VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect);
2242}
2243
2244/* For register symbols, we must figure out what range of addresses
2245 within the psect are valid. We will use the brackets in the stab
2246 directives to give us guidance as to the PC range that this variable
2247 is in scope. I am still not completely comfortable with this but
2248 as I learn more, I seem to get a better handle on what is going on.
2249 Caveat Emptor. */
2250
2251static void
2252VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
2253 symbolS *sp;
2254 symbolS *Current_Routine ATTRIBUTE_UNUSED;
2255 int Text_Psect;
2256{
2257 symbolS *symbolP;
2258 struct VMS_DBG_Symbol *spnt;
2259 char *pnt;
2260 char *pnt1;
2261 char *str;
2262 int dbx_type;
2263 int len;
2264 int i = 0;
2265 int bcnt = 0;
2266 int Min_Offset = -1; /* min PC of validity */
2267 int Max_Offset = 0; /* max PC of validity */
2268
2269 for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
2270 {
2271 /*
2272 * Dispatch on STAB type
2273 */
2274 switch (S_GET_RAW_TYPE (symbolP))
2275 {
2276 case N_LBRAC:
2277 if (bcnt++ == 0)
2278 Min_Offset = S_GET_VALUE (symbolP);
2279 break;
2280 case N_RBRAC:
2281 if (--bcnt == 0)
2282 Max_Offset = S_GET_VALUE (symbolP) - 1;
2283 break;
2284 }
2285 if ((Min_Offset != -1) && (bcnt == 0))
2286 break;
2287 if (S_GET_RAW_TYPE (symbolP) == N_FUN)
2288 {
2289 pnt = (char *) strchr (S_GET_NAME (symbolP), ':') + 1;
2290 if (*pnt == 'F' || *pnt == 'f') break;
2291 }
2292 }
2293
2294 /* Check to see that the addresses were defined. If not, then there
2295 were no brackets in the function, and we must try to search for
2296 the next function. Since functions can be in any order, we should
2297 search all of the symbol list to find the correct ending address. */
2298 if (Min_Offset == -1)
2299 {
2300 int Max_Source_Offset;
2301 int This_Offset;
2302
2303 Min_Offset = S_GET_VALUE (sp);
2304 Max_Source_Offset = Min_Offset; /* just in case no N_SLINEs found */
2305 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2306 switch (S_GET_RAW_TYPE (symbolP))
2307 {
2308 case N_TEXT | N_EXT:
2309 This_Offset = S_GET_VALUE (symbolP);
2310 if (This_Offset > Min_Offset && This_Offset < Max_Offset)
2311 Max_Offset = This_Offset;
2312 break;
2313 case N_SLINE:
2314 This_Offset = S_GET_VALUE (symbolP);
2315 if (This_Offset > Max_Source_Offset)
2316 Max_Source_Offset = This_Offset;
2317 break;
2318 }
2319 /* If this is the last routine, then we use the PC of the last source
2320 line as a marker of the max PC for which this reg is valid. */
2321 if (Max_Offset == 0x7fffffff)
2322 Max_Offset = Max_Source_Offset;
2323 }
2324
2325 dbx_type = 0;
2326 str = S_GET_NAME (sp);
2327 if ((pnt = (char *) strchr (str, ':')) == 0)
2328 return; /* no colon present */
2329 pnt1 = pnt; /* save this for later*/
2330 pnt++;
2331 if (*pnt != 'r')
2332 return;
2333 pnt = cvt_integer (pnt + 1, &dbx_type);
2334 spnt = find_symbol (dbx_type);
2335 if (!spnt)
2336 return; /*Dunno what this is yet*/
2337 *pnt1 = '\0';
2338 pnt = fix_name (S_GET_NAME (sp)); /* if there are bad characters in name, convert them */
2339 len = strlen (pnt);
2340 Local[i++] = 25 + len;
2341 Local[i++] = spnt->VMS_type;
2342 Local[i++] = DST_K_VFLAGS_TVS; /* trailing value specified */
2343 COPY_LONG (&Local[i], 1 + len); /* relative offset, beyond name */
2344 i += 4;
2345 Local[i++] = len; /* name length (ascic prefix) */
2346 while (*pnt != '\0')
2347 Local[i++] = *pnt++;
2348 Local[i++] = DST_K_VS_FOLLOWS; /* value specification follows */
2349 COPY_SHORT (&Local[i], 15); /* length of rest of record */
2350 i += 2;
2351 Local[i++] = DST_K_VS_ALLOC_SPLIT; /* split lifetime */
2352 Local[i++] = 1; /* one binding follows */
2353 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2354 i = 0;
2355 VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
2356 VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
2357 Local[i++] = DST_K_VALKIND_REG; /* nested value spec */
2358 COPY_LONG (&Local[i], S_GET_VALUE (sp));
2359 i += 4;
2360 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2361 *pnt1 = ':';
2362 if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
2363 generate_suffix (spnt, 0);
2364}
2365
2366/* This function examines a structure definition, checking all of the elements
2367 to make sure that all of them are fully defined. The only thing that we
2368 kick out are arrays of undefined structs, since we do not know how big
2369 they are. All others we can handle with a normal forward reference. */
2370
2371static int
2372forward_reference (pnt)
2373 char *pnt;
2374{
2375 struct VMS_DBG_Symbol *spnt, *spnt1;
2376 int i;
2377
2378 pnt = cvt_integer (pnt + 1, &i);
2379 if (*pnt == ';')
2380 return 0; /* no forward references */
2381 do
2382 {
2383 pnt = (char *) strchr (pnt, ':');
2384 pnt = cvt_integer (pnt + 1, &i);
2385 spnt = find_symbol (i);
2386 while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
2387 {
2388 spnt1 = find_symbol (spnt->type2);
2389 if (spnt->advanced == ARRAY && !spnt1)
2390 return 1;
2391 spnt = spnt1;
2392 }
2393 pnt = cvt_integer (pnt + 1, &i);
2394 pnt = cvt_integer (pnt + 1, &i);
2395 } while (*++pnt != ';');
2396 return 0; /* no forward refences found */
2397}
2398
2399/* Used to check a single element of a structure on the final pass. */
2400
2401static int
2402final_forward_reference (spnt)
2403 struct VMS_DBG_Symbol *spnt;
2404{
2405 struct VMS_DBG_Symbol *spnt1;
2406
2407 while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
2408 {
2409 spnt1 = find_symbol (spnt->type2);
2410 if (spnt->advanced == ARRAY && !spnt1)
2411 return 1;
2412 spnt = spnt1;
2413 }
2414 return 0; /* no forward refences found */
2415}
2416
2417/* This routine parses the stabs directives to find any definitions of dbx
2418 type numbers. It makes a note of all of them, creating a structure
2419 element of VMS_DBG_Symbol that describes it. This also generates the
2420 info for the debugger that describes the struct/union/enum, so that
2421 further references to these data types will be by number
2422
2423 We have to process pointers right away, since there can be references
2424 to them later in the same stabs directive. We cannot have forward
2425 references to pointers, (but we can have a forward reference to a
2426 pointer to a structure/enum/union) and this is why we process them
2427 immediately. After we process the pointer, then we search for defs
2428 that are nested even deeper.
2429
2430 8/15/92: We have to process arrays right away too, because there can
2431 be multiple references to identical array types in one structure
2432 definition, and only the first one has the definition. */
2433
2434static int
2435VMS_typedef_parse (str)
2436 char *str;
2437{
2438 char *pnt;
2439 char *pnt1;
2440 const char *pnt2;
2441 int i;
2442 int dtype;
2443 struct forward_ref *fpnt;
2444 int i1, i2, i3, len;
2445 struct VMS_DBG_Symbol *spnt;
2446 struct VMS_DBG_Symbol *spnt1;
2447
2448 /* check for any nested def's */
2449 pnt = (char *) strchr (str + 1, '=');
2450 if (pnt && str[1] != '*' && (str[1] != 'a' || str[2] != 'r')
2451 && VMS_typedef_parse (pnt) == 1)
2452 return 1;
2453 /* now find dbx_type of entry */
2454 pnt = str - 1;
2455 if (*pnt == 'c')
2456 { /* check for static constants */
2457 *str = '\0'; /* for now we ignore them */
2458 return 0;
2459 }
2460 while ((*pnt <= '9') && (*pnt >= '0'))
2461 pnt--;
2462 pnt++; /* and get back to the number */
2463 cvt_integer (pnt, &i1);
2464 spnt = find_symbol (i1);
2465 /* first see if this has been defined already, due to forward reference */
2466 if (!spnt)
2467 {
2468 i2 = SYMTYP_HASH (i1);
2469 spnt = (struct VMS_DBG_Symbol *) xmalloc (sizeof (struct VMS_DBG_Symbol));
2470 spnt->next = VMS_Symbol_type_list[i2];
2471 VMS_Symbol_type_list[i2] = spnt;
2472 spnt->dbx_type = i1; /* and save the type */
2473 spnt->type2 = spnt->VMS_type = spnt->data_size = 0;
2474 spnt->index_min = spnt->index_max = spnt->struc_numb = 0;
2475 }
2476 /*
2477 * For structs and unions, do a partial parse, otherwise we sometimes get
2478 * circular definitions that are impossible to resolve. We read enough
2479 * info so that any reference to this type has enough info to be resolved.
2480 */
2481 pnt = str + 1; /* point to character past equal sign */
2482 if (*pnt >= '0' && *pnt <= '9')
2483 {
2484 if (type_check ("void"))
2485 { /* this is the void symbol */
2486 *str = '\0';
2487 spnt->advanced = VOID;
2488 return 0;
2489 }
2490 if (type_check ("unknown type"))
2491 {
2492 *str = '\0';
2493 spnt->advanced = UNKNOWN;
2494 return 0;
2495 }
2496 pnt1 = cvt_integer (pnt, &i1);
2497 if (i1 != spnt->dbx_type)
2498 {
2499 spnt->advanced = ALIAS;
2500 spnt->type2 = i1;
2501 strcpy (str, pnt1);
2502 return 0;
2503 }
2504 as_tsktsk (_("debugginer output: %d is an unknown untyped variable."),
2505 spnt->dbx_type);
2506 return 1; /* do not know what this is */
2507 }
2508
2509 pnt = str + 1; /* point to character past equal sign */
2510 switch (*pnt)
2511 {
2512 case 'r':
2513 spnt->advanced = BASIC;
2514 if (type_check ("int"))
2515 {
2516 spnt->VMS_type = DBG_S_C_SLINT;
2517 spnt->data_size = 4;
2518 }
2519 else if (type_check ("long int"))
2520 {
2521 spnt->VMS_type = DBG_S_C_SLINT;
2522 spnt->data_size = 4;
2523 }
2524 else if (type_check ("unsigned int"))
2525 {
2526 spnt->VMS_type = DBG_S_C_ULINT;
2527 spnt->data_size = 4;
2528 }
2529 else if (type_check ("long unsigned int"))
2530 {
2531 spnt->VMS_type = DBG_S_C_ULINT;
2532 spnt->data_size = 4;
2533 }
2534 else if (type_check ("short int"))
2535 {
2536 spnt->VMS_type = DBG_S_C_SSINT;
2537 spnt->data_size = 2;
2538 }
2539 else if (type_check ("short unsigned int"))
2540 {
2541 spnt->VMS_type = DBG_S_C_USINT;
2542 spnt->data_size = 2;
2543 }
2544 else if (type_check ("char"))
2545 {
2546 spnt->VMS_type = DBG_S_C_SCHAR;
2547 spnt->data_size = 1;
2548 }
2549 else if (type_check ("signed char"))
2550 {
2551 spnt->VMS_type = DBG_S_C_SCHAR;
2552 spnt->data_size = 1;
2553 }
2554 else if (type_check ("unsigned char"))
2555 {
2556 spnt->VMS_type = DBG_S_C_UCHAR;
2557 spnt->data_size = 1;
2558 }
2559 else if (type_check ("float"))
2560 {
2561 spnt->VMS_type = DBG_S_C_REAL4;
2562 spnt->data_size = 4;
2563 }
2564 else if (type_check ("double"))
2565 {
2566 spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
2567 spnt->data_size = 8;
2568 }
2569 else if (type_check ("long double"))
2570 {
2571 /* same as double, at least for now */
2572 spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
2573 spnt->data_size = 8;
2574 }
2575 else if (type_check ("long long int"))
2576 {
2577 spnt->VMS_type = DBG_S_C_SQUAD; /* signed quadword */
2578 spnt->data_size = 8;
2579 }
2580 else if (type_check ("long long unsigned int"))
2581 {
2582 spnt->VMS_type = DBG_S_C_UQUAD; /* unsigned quadword */
2583 spnt->data_size = 8;
2584 }
2585 else if (type_check ("complex float"))
2586 {
2587 spnt->VMS_type = DBG_S_C_COMPLX4;
2588 spnt->data_size = 2 * 4;
2589 }
2590 else if (type_check ("complex double"))
2591 {
2592 spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
2593 spnt->data_size = 2 * 8;
2594 }
2595 else if (type_check ("complex long double"))
2596 {
2597 /* same as complex double, at least for now */
2598 spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
2599 spnt->data_size = 2 * 8;
2600 }
2601 else
2602 {
2603 /* [pr]
2604 * Shouldn't get here, but if we do, something
2605 * more substantial ought to be done...
2606 */
2607 spnt->VMS_type = 0;
2608 spnt->data_size = 0;
2609 }
2610 if (spnt->VMS_type != 0)
2611 setup_basic_type (spnt);
2612 pnt1 = (char *) strchr (str, ';') + 1;
2613 break;
2614 case 's':
2615 case 'u':
2616 spnt->advanced = (*pnt == 's') ? STRUCT : UNION;
2617 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2618 pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
2619 if (!final_pass && forward_reference (pnt))
2620 {
2621 spnt->struc_numb = -1;
2622 return 1;
2623 }
2624 spnt->struc_numb = ++structure_count;
2625 pnt1--;
2626 pnt = get_struct_name (str);
2627 VMS_Def_Struct (spnt->struc_numb);
2628 i = 0;
2629 for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
2630 if (fpnt->dbx_type == spnt->dbx_type)
2631 {
2632 fpnt->resolved = 'Y';
2633 VMS_Set_Struct (fpnt->struc_numb);
2634 VMS_Store_Struct (spnt->struc_numb);
2635 i++;
2636 }
2637 if (i > 0)
2638 VMS_Set_Struct (spnt->struc_numb);
2639 i = 0;
2640 Local[i++] = 11 + strlen (pnt);
2641 Local[i++] = DBG_S_C_STRUCT_START;
2642 Local[i++] = DST_K_VFLAGS_NOVAL; /* structure definition only */
2643 COPY_LONG (&Local[i], 0L); /* hence value is unused */
2644 i += 4;
2645 Local[i++] = strlen (pnt);
2646 pnt2 = pnt;
2647 while (*pnt2 != '\0')
2648 Local[i++] = *pnt2++;
2649 i2 = spnt->data_size * 8; /* number of bits */
2650 COPY_LONG (&Local[i], i2);
2651 i += 4;
2652 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2653 i = 0;
2654 if (pnt != symbol_name)
2655 {
2656 pnt += strlen (pnt);
2657 *pnt = ':';
2658 } /* replace colon for later */
2659 while (*++pnt1 != ';')
2660 {
2661 pnt = (char *) strchr (pnt1, ':');
2662 *pnt = '\0';
2663 pnt2 = pnt1;
2664 pnt1 = cvt_integer (pnt + 1, &dtype);
2665 pnt1 = cvt_integer (pnt1 + 1, &i2);
2666 pnt1 = cvt_integer (pnt1 + 1, &i3);
2667 spnt1 = find_symbol (dtype);
2668 len = strlen (pnt2);
2669 if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM)
2670 && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0)))
2671 { /* bitfield */
2672 if (USE_BITSTRING_DESCRIPTOR (spnt1))
2673 {
2674 /* This uses a type descriptor, which doesn't work if
2675 the enclosing structure has been placed in a register.
2676 Also, enum bitfields degenerate to simple integers. */
2677 int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT
2678 || spnt1->VMS_type == DBG_S_C_USINT
2679 || spnt1->VMS_type == DBG_S_C_UCHAR
2680 || spnt1->VMS_type == DBG_S_C_UQUAD
2681 || spnt1->advanced == ENUM); /* (approximate) */
2682 Apoint = 0;
2683 fpush (19 + len, 1);
2684 fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
2685 fpush (DST_K_VFLAGS_DSC, 1); /* specified by descriptor */
2686 fpush (1 + len, 4); /* relative offset to descriptor */
2687 fpush (len, 1); /* length byte (ascic prefix) */
2688 while (*pnt2 != '\0') /* name bytes */
2689 fpush (*pnt2++, 1);
2690 fpush (i3, 2); /* dsc length == size of bitfield */
2691 /* dsc type == un?signed bitfield */
2692 fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
2693 fpush (DSC_K_CLASS_UBS, 1); /* dsc class == unaligned bitstring */
2694 fpush (0x00, 4); /* dsc pointer == zeroes */
2695 fpush (i2, 4); /* start position */
2696 VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
2697 Apoint = 0;
2698 }
2699 else
2700 {
2701 /* Use a "novel length" type specification, which works
2702 right for register structures and for enum bitfields
2703 but results in larger object modules. */
2704 Local[i++] = 7 + len;
2705 Local[i++] = DBG_S_C_ADVANCED_TYPE; /* type spec follows */
2706 Local[i++] = DBG_S_C_STRUCT_ITEM; /* value is a bit offset */
2707 COPY_LONG (&Local[i], i2); /* bit offset */
2708 i += 4;
2709 Local[i++] = strlen (pnt2);
2710 while (*pnt2 != '\0')
2711 Local[i++] = *pnt2++;
2712 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2713 i = 0;
2714 bitfield_suffix (spnt1, i3);
2715 }
2716 }
2717 else
2718 { /* not a bitfield */
2719 /* check if this is a forward reference */
2720 if (final_pass && final_forward_reference (spnt1))
2721 {
2722 as_tsktsk (_("debugger output: structure element `%s' has undefined type"),
2723 pnt2);
2724 continue;
2725 }
2726 Local[i++] = 7 + len;
2727 Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE;
2728 Local[i++] = DBG_S_C_STRUCT_ITEM;
2729 COPY_LONG (&Local[i], i2); /* bit offset */
2730 i += 4;
2731 Local[i++] = strlen (pnt2);
2732 while (*pnt2 != '\0')
2733 Local[i++] = *pnt2++;
2734 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2735 i = 0;
2736 if (!spnt1)
2737 generate_suffix (spnt1, dtype);
2738 else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
2739 generate_suffix (spnt1, 0);
2740 }
2741 }
2742 pnt1++;
2743 Local[i++] = 0x01; /* length byte */
2744 Local[i++] = DBG_S_C_STRUCT_END;
2745 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2746 i = 0;
2747 break;
2748 case 'e':
2749 spnt->advanced = ENUM;
2750 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2751 spnt->struc_numb = ++structure_count;
2752 spnt->data_size = 4;
2753 VMS_Def_Struct (spnt->struc_numb);
2754 i = 0;
2755 for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
2756 if (fpnt->dbx_type == spnt->dbx_type)
2757 {
2758 fpnt->resolved = 'Y';
2759 VMS_Set_Struct (fpnt->struc_numb);
2760 VMS_Store_Struct (spnt->struc_numb);
2761 i++;
2762 }
2763 if (i > 0)
2764 VMS_Set_Struct (spnt->struc_numb);
2765 i = 0;
2766 len = strlen (symbol_name);
2767 Local[i++] = 3 + len;
2768 Local[i++] = DBG_S_C_ENUM_START;
2769 Local[i++] = 4 * 8; /* enum values are 32 bits */
2770 Local[i++] = len;
2771 pnt2 = symbol_name;
2772 while (*pnt2 != '\0')
2773 Local[i++] = *pnt2++;
2774 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2775 i = 0;
2776 while (*++pnt != ';')
2777 {
2778 pnt1 = (char *) strchr (pnt, ':');
2779 *pnt1++ = '\0';
2780 pnt1 = cvt_integer (pnt1, &i1);
2781 len = strlen (pnt);
2782 Local[i++] = 7 + len;
2783 Local[i++] = DBG_S_C_ENUM_ITEM;
2784 Local[i++] = DST_K_VALKIND_LITERAL;
2785 COPY_LONG (&Local[i], i1);
2786 i += 4;
2787 Local[i++] = len;
2788 pnt2 = pnt;
2789 while (*pnt != '\0')
2790 Local[i++] = *pnt++;
2791 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2792 i = 0;
2793 pnt = pnt1; /* Skip final semicolon */
2794 }
2795 Local[i++] = 0x01; /* len byte */
2796 Local[i++] = DBG_S_C_ENUM_END;
2797 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
2798 i = 0;
2799 pnt1 = pnt + 1;
2800 break;
2801 case 'a':
2802 spnt->advanced = ARRAY;
2803 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2804 pnt = (char *) strchr (pnt, ';');
2805 if (!pnt)
2806 return 1;
2807 pnt1 = cvt_integer (pnt + 1, &spnt->index_min);
2808 pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max);
2809 pnt1 = cvt_integer (pnt1 + 1, &spnt->type2);
2810 pnt = (char *) strchr (str + 1, '=');
2811 if (pnt && VMS_typedef_parse (pnt) == 1)
2812 return 1;
2813 break;
2814 case 'f':
2815 spnt->advanced = FUNCTION;
2816 spnt->VMS_type = DBG_S_C_FUNCTION_ADDR;
2817 /* this masquerades as a basic type*/
2818 spnt->data_size = 4;
2819 pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2820 break;
2821 case '*':
2822 spnt->advanced = POINTER;
2823 spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
2824 spnt->data_size = 4;
2825 pnt1 = cvt_integer (pnt + 1, &spnt->type2);
2826 pnt = (char *) strchr (str + 1, '=');
2827 if (pnt && VMS_typedef_parse (pnt) == 1)
2828 return 1;
2829 break;
2830 default:
2831 spnt->advanced = UNKNOWN;
2832 spnt->VMS_type = 0;
2833 as_tsktsk (_("debugger output: %d is an unknown type of variable."),
2834 spnt->dbx_type);
2835 return 1; /* unable to decipher */
2836 }
2837 /* This removes the evidence of the definition so that the outer levels
2838 of parsing do not have to worry about it. */
2839 pnt = str;
2840 while (*pnt1 != '\0')
2841 *pnt++ = *pnt1++;
2842 *pnt = '\0';
2843 return 0;
2844}
2845
2846/* This is the root routine that parses the stabs entries for definitions.
2847 it calls VMS_typedef_parse, which can in turn call itself. We need to
2848 be careful, since sometimes there are forward references to other symbol
2849 types, and these cannot be resolved until we have completed the parse.
2850
2851 Also check and see if we are using continuation stabs, if we are, then
2852 paste together the entire contents of the stab before we pass it to
2853 VMS_typedef_parse. */
2854
2855static void
2856VMS_LSYM_Parse ()
2857{
2858 char *pnt;
2859 char *pnt1;
2860 char *pnt2;
2861 char *str;
2862 char *parse_buffer = 0;
2863 char fixit[10];
2864 int incomplete, pass, incom1;
2865 struct forward_ref *fpnt;
2866 symbolS *sp;
2867
2868 pass = 0;
2869 final_pass = 0;
2870 incomplete = 0;
2871 do
2872 {
2873 incom1 = incomplete;
2874 incomplete = 0;
2875 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
2876 {
2877 /*
2878 * Deal with STAB symbols
2879 */
2880 if (S_IS_DEBUG (sp))
2881 {
2882 /*
2883 * Dispatch on STAB type
2884 */
2885 switch (S_GET_RAW_TYPE (sp))
2886 {
2887 case N_GSYM:
2888 case N_LCSYM:
2889 case N_STSYM:
2890 case N_PSYM:
2891 case N_RSYM:
2892 case N_LSYM:
2893 case N_FUN: /*sometimes these contain typedefs*/
2894 str = S_GET_NAME (sp);
2895 symbol_name = str;
2896 pnt = str + strlen (str) - 1;
2897 if (*pnt == '?') /* Continuation stab. */
2898 {
2899 symbolS *spnext;
2900 int tlen = 0;
2901
2902 spnext = sp;
2903 do {
2904 tlen += strlen (str) - 1;
2905 spnext = symbol_next (spnext);
2906 str = S_GET_NAME (spnext);
2907 pnt = str + strlen (str) - 1;
2908 } while (*pnt == '?');
2909 tlen += strlen (str);
2910 parse_buffer = (char *) xmalloc (tlen + 1);
2911 strcpy (parse_buffer, S_GET_NAME (sp));
2912 pnt2 = parse_buffer + strlen (parse_buffer) - 1;
2913 *pnt2 = '\0';
2914 spnext = sp;
2915 do {
2916 spnext = symbol_next (spnext);
2917 str = S_GET_NAME (spnext);
2918 strcat (pnt2, str);
2919 pnt2 += strlen (str) - 1;
2920 *str = '\0'; /* Erase this string */
2921 /* S_SET_NAME (spnext, str); */
2922 if (*pnt2 != '?') break;
2923 *pnt2 = '\0';
2924 } while (1);
2925 str = parse_buffer;
2926 symbol_name = str;
2927 }
2928 if ((pnt = (char *) strchr (str, ':')) != 0)
2929 {
2930 *pnt = '\0';
2931 pnt1 = pnt + 1;
2932 if ((pnt2 = (char *) strchr (pnt1, '=')) != 0)
2933 incomplete += VMS_typedef_parse (pnt2);
2934 if (parse_buffer)
2935 {
2936 /* At this point the parse buffer should just
2937 contain name:nn. If it does not, then we
2938 are in real trouble. Anyway, this is always
2939 shorter than the original line. */
2940 pnt2 = S_GET_NAME (sp);
2941 strcpy (pnt2, parse_buffer);
2942 /* S_SET_NAME (sp, pnt2); */
2943 free (parse_buffer), parse_buffer = 0;
2944 }
2945 *pnt = ':'; /* put back colon to restore dbx_type */
2946 }
2947 break;
2948 } /*switch*/
2949 } /* if */
2950 } /*for*/
2951 pass++;
2952 /*
2953 * Make one last pass, if needed, and define whatever we can
2954 * that is left.
2955 */
2956 if (final_pass == 0 && incomplete == incom1)
2957 {
2958 final_pass = 1;
2959 incom1++; /* Force one last pass through */
2960 }
2961 } while (incomplete != 0 && incomplete != incom1);
2962 /* repeat until all refs resolved if possible */
2963/* if (pass > 1) printf (" Required %d passes\n", pass); */
2964 if (incomplete != 0)
2965 {
2966 as_tsktsk (_("debugger output: Unable to resolve %d circular references."),
2967 incomplete);
2968 }
2969 fpnt = f_ref_root;
2970 symbol_name = "\0";
2971 while (fpnt)
2972 {
2973 if (fpnt->resolved != 'Y')
2974 {
2975 if (find_symbol (fpnt->dbx_type))
2976 {
2977 as_tsktsk (_("debugger forward reference error, dbx type %d"),
2978 fpnt->dbx_type);
2979 break;
2980 }
2981 fixit[0] = 0;
2982 sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type);
2983 pnt2 = (char *) strchr (&fixit[1], '=');
2984 VMS_typedef_parse (pnt2);
2985 }
2986 fpnt = fpnt->next;
2987 }
2988}
2989
2990static void
2991Define_Local_Symbols (s0P, s2P, Current_Routine, Text_Psect)
2992 symbolS *s0P, *s2P;
2993 symbolS *Current_Routine;
2994 int Text_Psect;
2995{
2996 symbolS *s1P; /* each symbol from s0P .. s2P (exclusive) */
2997
2998 for (s1P = symbol_next (s0P); s1P != s2P; s1P = symbol_next (s1P))
2999 {
3000 if (!s1P)
3001 break; /* and return */
3002 if (S_GET_RAW_TYPE (s1P) == N_FUN)
3003 {
3004 char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1;
3005 if (*pnt == 'F' || *pnt == 'f') break;
3006 }
3007 if (!S_IS_DEBUG (s1P))
3008 continue;
3009 /*
3010 * Dispatch on STAB type
3011 */
3012 switch (S_GET_RAW_TYPE (s1P))
3013 {
3014 default:
3015 continue; /* not left or right brace */
3016
3017 case N_LSYM:
3018 case N_PSYM:
3019 VMS_local_stab_Parse (s1P);
3020 break;
3021
3022 case N_RSYM:
3023 VMS_RSYM_Parse (s1P, Current_Routine, Text_Psect);
3024 break;
3025 } /*switch*/
3026 } /* for */
3027}
3028
3029/* This function crawls the symbol chain searching for local symbols that
3030 need to be described to the debugger. When we enter a new scope with
3031 a "{", it creates a new "block", which helps the debugger keep track
3032 of which scope we are currently in. */
3033
3034static symbolS *
3035Define_Routine (s0P, Level, Current_Routine, Text_Psect)
3036 symbolS *s0P;
3037 int Level;
3038 symbolS *Current_Routine;
3039 int Text_Psect;
3040{
3041 symbolS *s1P;
3042 valueT Offset;
3043 int rcount = 0;
3044
3045 for (s1P = symbol_next (s0P); s1P != 0; s1P = symbol_next (s1P))
3046 {
3047 if (S_GET_RAW_TYPE (s1P) == N_FUN)
3048 {
3049 char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1;
3050 if (*pnt == 'F' || *pnt == 'f') break;
3051 }
3052 if (!S_IS_DEBUG (s1P))
3053 continue;
3054 /*
3055 * Dispatch on STAB type
3056 */
3057 switch (S_GET_RAW_TYPE (s1P))
3058 {
3059 default:
3060 continue; /* not left or right brace */
3061
3062 case N_LBRAC:
3063 if (Level != 0)
3064 {
3065 char str[10];
3066 sprintf (str, "$%d", rcount++);
3067 VMS_TBT_Block_Begin (s1P, Text_Psect, str);
3068 }
3069 Offset = S_GET_VALUE (s1P); /* side-effect: fully resolve symbol */
3070 Define_Local_Symbols (s0P, s1P, Current_Routine, Text_Psect);
3071 s1P = Define_Routine (s1P, Level + 1, Current_Routine, Text_Psect);
3072 if (Level != 0)
3073 VMS_TBT_Block_End (S_GET_VALUE (s1P) - Offset);
3074 s0P = s1P;
3075 break;
3076
3077 case N_RBRAC:
3078 return s1P;
3079 } /*switch*/
3080 } /* for */
3081
3082 /* We end up here if there were no brackets in this function.
3083 Define everything. */
3084 Define_Local_Symbols (s0P, (symbolS *)0, Current_Routine, Text_Psect);
3085 return s1P;
3086}
3087
3088
3089
3090#ifndef VMS
3091#include <sys/types.h>
3092#include <time.h>
3093static void get_VMS_time_on_unix PARAMS ((char *));
3094
3095/* Manufacture a VMS-like time string on a Unix based system. */
3096static void
3097get_VMS_time_on_unix (Now)
3098 char *Now;
3099{
3100 char *pnt;
3101 time_t timeb;
3102
3103 time (&timeb);
3104 pnt = ctime (&timeb);
3105 pnt[3] = 0;
3106 pnt[7] = 0;
3107 pnt[10] = 0;
3108 pnt[16] = 0;
3109 pnt[24] = 0;
3110 sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
3111}
3112#endif /* not VMS */
3113
3114/* Write the MHD (Module Header) records. */
3115
3116static void
3117Write_VMS_MHD_Records ()
3118{
3119 register const char *cp;
3120 register char *cp1;
3121 register int i;
3122#ifdef VMS
3123 struct { unsigned short len, mbz; char *ptr; } Descriptor;
3124#endif
3125 char Now[17+1];
3126
3127 /* We are writing a module header record. */
3128 Set_VMS_Object_File_Record (OBJ_S_C_HDR);
3129 /*
3130 * ***************************
3131 * *MAIN MODULE HEADER RECORD*
3132 * ***************************
3133 */
3134 /* Store record type and header type. */
3135 PUT_CHAR (OBJ_S_C_HDR);
3136 PUT_CHAR (MHD_S_C_MHD);
3137 /* Structure level is 0. */
3138 PUT_CHAR (OBJ_S_C_STRLVL);
3139 /* Maximum record size is size of the object record buffer. */
3140 PUT_SHORT (sizeof (Object_Record_Buffer));
3141
3142 /*
3143 * FIXME: module name and version should be user
3144 * specifiable via `.ident' and/or `#pragma ident'.
3145 */
3146
3147 /* Get module name (the FILENAME part of the object file). */
3148 cp = out_file_name;
3149 cp1 = Module_Name;
3150 while (*cp)
3151 {
3152 if (*cp == ']' || *cp == '>' || *cp == ':' || *cp == '/')
3153 {
3154 cp1 = Module_Name;
3155 cp++;
3156 continue;
3157 }
3158 *cp1++ = TOUPPER (*cp++);
3159 }
3160 *cp1 = '\0';
3161
3162 /* Limit it to 31 characters and store in the object record. */
3163 while (--cp1 >= Module_Name)
3164 if (*cp1 == '.')
3165 *cp1 = '\0';
3166 if (strlen (Module_Name) > 31)
3167 {
3168 if (flag_hash_long_names)
3169 as_tsktsk (_("Module name truncated: %s\n"), Module_Name);
3170 Module_Name[31] = '\0';
3171 }
3172 PUT_COUNTED_STRING (Module_Name);
3173 /* Module Version is "V1.0". */
3174 PUT_COUNTED_STRING ("V1.0");
3175 /* Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm". */
3176#ifndef VMS
3177 get_VMS_time_on_unix (Now);
3178#else /* VMS */
3179 Descriptor.len = sizeof Now - 1;
3180 Descriptor.mbz = 0; /* type & class unspecified */
3181 Descriptor.ptr = Now;
3182 (void) sys$asctim ((unsigned short *)0, &Descriptor, (long *)0, 0);
3183#endif /* VMS */
3184 for (i = 0; i < 17; i++)
3185 PUT_CHAR (Now[i]);
3186 /* Patch time is "never" (17 zeros). */
3187 for (i = 0; i < 17; i++)
3188 PUT_CHAR (0);
3189 /* Force this to be a separate output record. */
3190 Flush_VMS_Object_Record_Buffer ();
3191
3192 /*
3193 * *************************
3194 * *LANGUAGE PROCESSOR NAME*
3195 * *************************
3196 */
3197 /* Store record type and header type. */
3198 PUT_CHAR (OBJ_S_C_HDR);
3199 PUT_CHAR (MHD_S_C_LNM);
3200 /*
3201 * Store language processor name and version (not a counted string!).
3202 *
3203 * This is normally supplied by the gcc driver for the command line
3204 * which invokes gas. If absent, we fall back to gas's version.
3205 */
3206 cp = compiler_version_string;
3207 if (cp == 0)
3208 {
3209 cp = "GNU AS V";
3210 while (*cp)
3211 PUT_CHAR (*cp++);
3212 cp = VERSION;
3213 }
3214 while (*cp >= ' ')
3215 PUT_CHAR (*cp++);
3216 /* Force this to be a separate output record. */
3217 Flush_VMS_Object_Record_Buffer ();
3218}
3219
3220/* Write the EOM (End Of Module) record. */
3221
3222static void
3223Write_VMS_EOM_Record (Psect, Offset)
3224 int Psect;
3225 valueT Offset;
3226{
3227 /*
3228 * We are writing an end-of-module record
3229 * (this assumes that the entry point will always be in a psect
3230 * represented by a single byte, which is the case for code in
3231 * Text_Psect==0)
3232 */
3233 Set_VMS_Object_File_Record (OBJ_S_C_EOM);
3234 PUT_CHAR (OBJ_S_C_EOM); /* Record type. */
3235 PUT_CHAR (0); /* Error severity level (we ignore it). */
3236 /*
3237 * Store the entry point, if it exists
3238 */
3239 if (Psect >= 0)
3240 {
3241 PUT_CHAR (Psect);
3242 PUT_LONG (Offset);
3243 }
3244 /* Flush the record; this will be our final output. */
3245 Flush_VMS_Object_Record_Buffer ();
3246}
3247
3248
3249
3250/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
3251
3252static int
3253hash_string (ptr)
3254 const char *ptr;
3255{
3256 register const unsigned char *p = (unsigned char *) ptr;
3257 register const unsigned char *end = p + strlen (ptr);
3258 register unsigned char c;
3259 register int hash = 0;
3260
3261 while (p != end)
3262 {
3263 c = *p++;
3264 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
3265 }
3266 return hash;
3267}
3268
3269/*
3270 * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
3271 */
3272static void
3273VMS_Case_Hack_Symbol (In, Out)
3274 register const char *In;
3275 register char *Out;
3276{
3277 long int init;
3278 long int result;
3279 char *pnt = 0;
3280 char *new_name;
3281 const char *old_name;
3282 register int i;
3283 int destructor = 0; /*hack to allow for case sens in a destructor*/
3284 int truncate = 0;
3285 int Case_Hack_Bits = 0;
3286 int Saw_Dollar = 0;
3287 static char Hex_Table[16] =
3288 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
3289
3290 /*
3291 * Kill any leading "_"
3292 */
3293 if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0')))
3294 In++;
3295
3296 new_name = Out; /* save this for later*/
3297
3298#if barfoo /* Dead code */
3299 if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_'))
3300 destructor = 1;
3301#endif
3302
3303 /* We may need to truncate the symbol, save the hash for later*/
3304 result = (strlen (In) > 23) ? hash_string (In) : 0;
3305 /*
3306 * Is there a Psect Attribute to skip??
3307 */
3308 if (HAS_PSECT_ATTRIBUTES (In))
3309 {
3310 /*
3311 * Yes: Skip it
3312 */
3313 In += PSECT_ATTRIBUTES_STRING_LENGTH;
3314 while (*In)
3315 {
3316 if ((In[0] == '$') && (In[1] == '$'))
3317 {
3318 In += 2;
3319 break;
3320 }
3321 In++;
3322 }
3323 }
3324
3325 old_name = In;
3326/* if (strlen (In) > 31 && flag_hash_long_names)
3327 as_tsktsk ("Symbol name truncated: %s\n", In); */
3328 /*
3329 * Do the case conversion
3330 */
3331 i = 23; /* Maximum of 23 chars */
3332 while (*In && (--i >= 0))
3333 {
3334 Case_Hack_Bits <<= 1;
3335 if (*In == '$')
3336 Saw_Dollar = 1;
3337 if ((destructor == 1) && (i == 21))
3338 Saw_Dollar = 0;
3339 switch (vms_name_mapping)
3340 {
3341 case 0:
3342 if (ISUPPER (*In)) {
3343 *Out++ = *In++;
3344 Case_Hack_Bits |= 1;
3345 } else {
3346 *Out++ = TOUPPER (*In++);
3347 }
3348 break;
3349 case 3: *Out++ = *In++;
3350 break;
3351 case 2:
3352 if (ISLOWER (*In)) {
3353 *Out++ = *In++;
3354 } else {
3355 *Out++ = TOLOWER (*In++);
3356 }
3357 break;
3358 }
3359 }
3360 /*
3361 * If we saw a dollar sign, we don't do case hacking
3362 */
3363 if (flag_no_hash_mixed_case || Saw_Dollar)
3364 Case_Hack_Bits = 0;
3365
3366 /*
3367 * If we have more than 23 characters and everything is lowercase
3368 * we can insert the full 31 characters
3369 */
3370 if (*In)
3371 {
3372 /*
3373 * We have more than 23 characters
3374 * If we must add the case hack, then we have truncated the str
3375 */
3376 pnt = Out;
3377 truncate = 1;
3378 if (Case_Hack_Bits == 0)
3379 {
3380 /*
3381 * And so far they are all lower case:
3382 * Check up to 8 more characters
3383 * and ensure that they are lowercase
3384 */
3385 for (i = 0; (In[i] != 0) && (i < 8); i++)
3386 if (ISUPPER (In[i]) && !Saw_Dollar && !flag_no_hash_mixed_case)
3387 break;
3388
3389 if (In[i] == 0)
3390 truncate = 0;
3391
3392 if ((i == 8) || (In[i] == 0))
3393 {
3394 /*
3395 * They are: Copy up to 31 characters
3396 * to the output string
3397 */
3398 i = 8;
3399 while ((--i >= 0) && (*In))
3400 switch (vms_name_mapping){
3401 case 0: *Out++ = TOUPPER (*In++);
3402 break;
3403 case 3: *Out++ = *In++;
3404 break;
3405 case 2: *Out++ = TOLOWER (*In++);
3406 break;
3407 }
3408 }
3409 }
3410 }
3411 /*
3412 * If there were any uppercase characters in the name we
3413 * take on the case hacking string
3414 */
3415
3416 /* Old behavior for regular GNU-C compiler */
3417 if (!flag_hash_long_names)
3418 truncate = 0;
3419 if ((Case_Hack_Bits != 0) || (truncate == 1))
3420 {
3421 if (truncate == 0)
3422 {
3423 *Out++ = '_';
3424 for (i = 0; i < 6; i++)
3425 {
3426 *Out++ = Hex_Table[Case_Hack_Bits & 0xf];
3427 Case_Hack_Bits >>= 4;
3428 }
3429 *Out++ = 'X';
3430 }
3431 else
3432 {
3433 Out = pnt; /*Cut back to 23 characters maximum */
3434 *Out++ = '_';
3435 for (i = 0; i < 7; i++)
3436 {
3437 init = result & 0x01f;
3438 *Out++ = (init < 10) ? ('0' + init) : ('A' + init - 10);
3439 result = result >> 5;
3440 }
3441 }
3442 } /*Case Hack */
3443 /*
3444 * Done
3445 */
3446 *Out = 0;
3447 if (truncate == 1 && flag_hash_long_names && flag_show_after_trunc)
3448 as_tsktsk (_("Symbol %s replaced by %s\n"), old_name, new_name);
3449}
3450
3451
3452
3453/*
3454 * Scan a symbol name for a psect attribute specification
3455 */
3456#define GLOBALSYMBOL_BIT 0x10000
3457#define GLOBALVALUE_BIT 0x20000
3458
3459static void
3460VMS_Modify_Psect_Attributes (Name, Attribute_Pointer)
3461 const char *Name;
3462 int *Attribute_Pointer;
3463{
3464 register int i;
3465 register const char *cp;
3466 int Negate;
3467 static const struct
3468 {
3469 const char *Name;
3470 int Value;
3471 } Attributes[] =
3472 {
3473 {"PIC", GPS_S_M_PIC},
3474 {"LIB", GPS_S_M_LIB},
3475 {"OVR", GPS_S_M_OVR},
3476 {"REL", GPS_S_M_REL},
3477 {"GBL", GPS_S_M_GBL},
3478 {"SHR", GPS_S_M_SHR},
3479 {"EXE", GPS_S_M_EXE},
3480 {"RD", GPS_S_M_RD},
3481 {"WRT", GPS_S_M_WRT},
3482 {"VEC", GPS_S_M_VEC},
3483 {"GLOBALSYMBOL", GLOBALSYMBOL_BIT},
3484 {"GLOBALVALUE", GLOBALVALUE_BIT},
3485 {0, 0}
3486 };
3487
3488 /*
3489 * Kill leading "_"
3490 */
3491 if (*Name == '_')
3492 Name++;
3493 /*
3494 * Check for a PSECT attribute list
3495 */
3496 if (!HAS_PSECT_ATTRIBUTES (Name))
3497 return; /* If not, return */
3498 /*
3499 * Skip the attribute list indicator
3500 */
3501 Name += PSECT_ATTRIBUTES_STRING_LENGTH;
3502 /*
3503 * Process the attributes ("_" separated, "$" terminated)
3504 */
3505 while (*Name != '$')
3506 {
3507 /*
3508 * Assume not negating
3509 */
3510 Negate = 0;
3511 /*
3512 * Check for "NO"
3513 */
3514 if ((Name[0] == 'N') && (Name[1] == 'O'))
3515 {
3516 /*
3517 * We are negating (and skip the NO)
3518 */
3519 Negate = 1;
3520 Name += 2;
3521 }
3522 /*
3523 * Find the token delimiter
3524 */
3525 cp = Name;
3526 while (*cp && (*cp != '_') && (*cp != '$'))
3527 cp++;
3528 /*
3529 * Look for the token in the attribute list
3530 */
3531 for (i = 0; Attributes[i].Name; i++)
3532 {
3533 /*
3534 * If the strings match, set/clear the attr.
3535 */
3536 if (strncmp (Name, Attributes[i].Name, cp - Name) == 0)
3537 {
3538 /*
3539 * Set or clear
3540 */
3541 if (Negate)
3542 *Attribute_Pointer &=
3543 ~Attributes[i].Value;
3544 else
3545 *Attribute_Pointer |=
3546 Attributes[i].Value;
3547 /*
3548 * Done
3549 */
3550 break;
3551 }
3552 }
3553 /*
3554 * Now skip the attribute
3555 */
3556 Name = cp;
3557 if (*Name == '_')
3558 Name++;
3559 }
3560}
3561
3562
3563
3564#define GBLSYM_REF 0
3565#define GBLSYM_DEF 1
3566#define GBLSYM_VAL 2
3567#define GBLSYM_LCL 4 /* not GBL after all... */
3568#define GBLSYM_WEAK 8
3569
3570/*
3571 * Define a global symbol (or possibly a local one).
3572 */
3573static void
3574VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags)
3575 const char *Name;
3576 int Psect_Number;
3577 int Psect_Offset;
3578 int Flags;
3579{
3580 char Local[32];
3581
3582 /*
3583 * We are writing a GSD record
3584 */
3585 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3586 /*
3587 * If the buffer is empty we must insert the GSD record type
3588 */
3589 if (Object_Record_Offset == 0)
3590 PUT_CHAR (OBJ_S_C_GSD);
3591 /*
3592 * We are writing a Global (or local) symbol definition subrecord.
3593 */
3594 PUT_CHAR ((Flags & GBLSYM_LCL) != 0 ? GSD_S_C_LSY :
3595 ((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW);
3596 /*
3597 * Data type is undefined
3598 */
3599 PUT_CHAR (0);
3600 /*
3601 * Switch on Definition/Reference
3602 */
3603 if ((Flags & GBLSYM_DEF) == 0)
3604 {
3605 /*
3606 * Reference
3607 */
3608 PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ? GSY_S_M_REL : 0);
3609 if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
3610 PUT_SHORT (Current_Environment);
3611 }
3612 else
3613 {
3614 int sym_flags;
3615
3616 /*
3617 * Definition
3618 *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
3619 */
3620 sym_flags = GSY_S_M_DEF;
3621 if (Flags & GBLSYM_WEAK)
3622 sym_flags |= GSY_S_M_WEAK;
3623 if ((Flags & GBLSYM_VAL) == 0)
3624 sym_flags |= GSY_S_M_REL;
3625 PUT_SHORT (sym_flags);
3626 if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
3627 PUT_SHORT (Current_Environment);
3628 /*
3629 * Psect Number
3630 */
3631 if ((Flags & GBLSYM_LCL) == 0 && (unsigned) Psect_Number <= 255)
3632 PUT_CHAR (Psect_Number);
3633 else
3634 PUT_SHORT (Psect_Number);
3635 /*
3636 * Offset
3637 */
3638 PUT_LONG (Psect_Offset);
3639 }
3640 /*
3641 * Finally, the global symbol name
3642 */
3643 VMS_Case_Hack_Symbol (Name, Local);
3644 PUT_COUNTED_STRING (Local);
3645 /*
3646 * Flush the buffer if it is more than 75% full
3647 */
3648 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3649 Flush_VMS_Object_Record_Buffer ();
3650}
3651
3652/*
3653 * Define an environment to support local symbol references.
3654 * This is just to mollify the linker; we don't actually do
3655 * anything useful with it.
3656 */
3657static void
3658VMS_Local_Environment_Setup (Env_Name)
3659 const char *Env_Name;
3660{
3661 /* We are writing a GSD record. */
3662 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3663 /* If the buffer is empty we must insert the GSD record type. */
3664 if (Object_Record_Offset == 0)
3665 PUT_CHAR (OBJ_S_C_GSD);
3666 /* We are writing an ENV subrecord. */
3667 PUT_CHAR (GSD_S_C_ENV);
3668
3669 ++Current_Environment; /* index of environment being defined */
3670
3671 /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
3672 PUT_SHORT (ENV_S_M_DEF);
3673 /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
3674 PUT_SHORT (0);
3675
3676 /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
3677 if (!Env_Name) Env_Name = "";
3678 PUT_COUNTED_STRING ((char *)Env_Name);
3679
3680 /* Flush the buffer if it is more than 75% full. */
3681 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3682 Flush_VMS_Object_Record_Buffer ();
3683}
3684
3685
3686
3687/*
3688 * Define a psect
3689 */
3690static int
3691VMS_Psect_Spec (Name, Size, Type, vsp)
3692 const char *Name;
3693 int Size;
3694 enum ps_type Type;
3695 struct VMS_Symbol *vsp;
3696{
3697 char Local[32];
3698 int Psect_Attributes;
3699
3700 /*
3701 * Generate the appropriate PSECT flags given the PSECT type
3702 */
3703 switch (Type)
3704 {
3705 case ps_TEXT:
3706 /* Text psects are PIC,noOVR,REL,noGBL,SHR,EXE,RD,noWRT. */
3707 Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE
3708 |GPS_S_M_RD);
3709 break;
3710 case ps_DATA:
3711 /* Data psects are PIC,noOVR,REL,noGBL,noSHR,noEXE,RD,WRT. */
3712 Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT);
3713 break;
3714 case ps_COMMON:
3715 /* Common block psects are: PIC,OVR,REL,GBL,noSHR,noEXE,RD,WRT. */
3716 Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL
3717 |GPS_S_M_RD|GPS_S_M_WRT);
3718 break;
3719 case ps_CONST:
3720 /* Const data psects are: PIC,OVR,REL,GBL,noSHR,noEXE,RD,noWRT. */
3721 Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL
3722 |GPS_S_M_RD);
3723 break;
3724 case ps_CTORS:
3725 /* Ctor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT. */
3726 Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD);
3727 break;
3728 case ps_DTORS:
3729 /* Dtor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT. */
3730 Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD);
3731 break;
3732 default:
3733 /* impossible */
3734 error (_("Unknown VMS psect type (%ld)"), (long) Type);
3735 break;
3736 }
3737 /*
3738 * Modify the psect attributes according to any attribute string
3739 */
3740 if (vsp && S_GET_TYPE (vsp->Symbol) == N_ABS)
3741 Psect_Attributes |= GLOBALVALUE_BIT;
3742 else if (HAS_PSECT_ATTRIBUTES (Name))
3743 VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
3744 /*
3745 * Check for globalref/def/val.
3746 */
3747 if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3748 {
3749 /*
3750 * globalvalue symbols were generated before. This code
3751 * prevents unsightly psect buildup, and makes sure that
3752 * fixup references are emitted correctly.
3753 */
3754 vsp->Psect_Index = -1; /* to catch errors */
3755 S_SET_TYPE (vsp->Symbol, N_UNDF); /* make refs work */
3756 return 1; /* decrement psect counter */
3757 }
3758
3759 if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0)
3760 {
3761 switch (S_GET_RAW_TYPE (vsp->Symbol))
3762 {
3763 case N_UNDF | N_EXT:
3764 VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3765 vsp->Psect_Offset, GBLSYM_REF);
3766 vsp->Psect_Index = -1;
3767 S_SET_TYPE (vsp->Symbol, N_UNDF);
3768 return 1; /* return and indicate no psect */
3769 case N_DATA | N_EXT:
3770 VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
3771 vsp->Psect_Offset, GBLSYM_DEF);
3772 /* In this case we still generate the psect */
3773 break;
3774 default:
3775 as_fatal (_("Globalsymbol attribute for symbol %s was unexpected."),
3776 Name);
3777 break;
3778 } /* switch */
3779 }
3780
3781 Psect_Attributes &= 0xffff; /* clear out the globalref/def stuff */
3782 /*
3783 * We are writing a GSD record
3784 */
3785 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3786 /*
3787 * If the buffer is empty we must insert the GSD record type
3788 */
3789 if (Object_Record_Offset == 0)
3790 PUT_CHAR (OBJ_S_C_GSD);
3791 /*
3792 * We are writing a PSECT definition subrecord
3793 */
3794 PUT_CHAR (GSD_S_C_PSC);
3795 /*
3796 * Psects are always LONGWORD aligned
3797 */
3798 PUT_CHAR (2);
3799 /*
3800 * Specify the psect attributes
3801 */
3802 PUT_SHORT (Psect_Attributes);
3803 /*
3804 * Specify the allocation
3805 */
3806 PUT_LONG (Size);
3807 /*
3808 * Finally, the psect name
3809 */
3810 VMS_Case_Hack_Symbol (Name, Local);
3811 PUT_COUNTED_STRING (Local);
3812 /*
3813 * Flush the buffer if it is more than 75% full
3814 */
3815 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
3816 Flush_VMS_Object_Record_Buffer ();
3817 return 0;
3818}
3819
3820
3821
3822/* Given the pointer to a symbol we calculate how big the data at the
3823 symbol is. We do this by looking for the next symbol (local or global)
3824 which will indicate the start of another datum. */
3825
3826static offsetT
3827VMS_Initialized_Data_Size (s0P, End_Of_Data)
3828 register symbolS *s0P;
3829 unsigned End_Of_Data;
3830{
3831 symbolS *s1P;
3832 valueT s0P_val = S_GET_VALUE (s0P), s1P_val,
3833 nearest_val = (valueT) End_Of_Data;
3834
3835 /* Find the nearest symbol what follows this one. */
3836 for (s1P = symbol_rootP; s1P; s1P = symbol_next (s1P))
3837 {
3838 /* The data type must match. */
3839 if (S_GET_TYPE (s1P) != N_DATA)
3840 continue;
3841 s1P_val = S_GET_VALUE (s1P);
3842 if (s1P_val > s0P_val && s1P_val < nearest_val)
3843 nearest_val = s1P_val;
3844 }
3845 /* Calculate its size. */
3846 return (offsetT) (nearest_val - s0P_val);
3847}
3848
3849/* Check symbol names for the Psect hack with a globalvalue, and then
3850 generate globalvalues for those that have it. */
3851
3852static void
3853VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment)
3854 unsigned text_siz;
3855 unsigned data_siz;
3856 char *Data_Segment;
3857{
3858 register symbolS *sp;
3859 char *stripped_name, *Name;
3860 int Size;
3861 int Psect_Attributes;
3862 int globalvalue;
3863 int typ, abstyp;
3864
3865 /*
3866 * Scan the symbol table for globalvalues, and emit def/ref when
3867 * required. These will be caught again later and converted to
3868 * N_UNDF
3869 */
3870 for (sp = symbol_rootP; sp; sp = sp->sy_next)
3871 {
3872 typ = S_GET_RAW_TYPE (sp);
3873 abstyp = ((typ & ~N_EXT) == N_ABS);
3874 /*
3875 * See if this is something we want to look at.
3876 */
3877 if (!abstyp &&
3878 typ != (N_DATA | N_EXT) &&
3879 typ != (N_UNDF | N_EXT))
3880 continue;
3881 /*
3882 * See if this has globalvalue specification.
3883 */
3884 Name = S_GET_NAME (sp);
3885
3886 if (abstyp)
3887 {
3888 stripped_name = 0;
3889 Psect_Attributes = GLOBALVALUE_BIT;
3890 }
3891 else if (HAS_PSECT_ATTRIBUTES (Name))
3892 {
3893 stripped_name = (char *) xmalloc (strlen (Name) + 1);
3894 strcpy (stripped_name, Name);
3895 Psect_Attributes = 0;
3896 VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
3897 }
3898 else
3899 continue;
3900
3901 if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
3902 {
3903 switch (typ)
3904 {
3905 case N_ABS:
3906 /* Local symbol references will want
3907 to have an environment defined. */
3908 if (Current_Environment < 0)
3909 VMS_Local_Environment_Setup (".N_ABS");
3910 VMS_Global_Symbol_Spec (Name, 0,
3911 S_GET_VALUE (sp),
3912 GBLSYM_DEF|GBLSYM_VAL|GBLSYM_LCL);
3913 break;
3914 case N_ABS | N_EXT:
3915 VMS_Global_Symbol_Spec (Name, 0,
3916 S_GET_VALUE (sp),
3917 GBLSYM_DEF|GBLSYM_VAL);
3918 break;
3919 case N_UNDF | N_EXT:
3920 VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
3921 break;
3922 case N_DATA | N_EXT:
3923 Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
3924 if (Size > 4)
3925 error (_("Invalid data type for globalvalue"));
3926 globalvalue = md_chars_to_number (Data_Segment +
3927 S_GET_VALUE (sp) - text_siz , Size);
3928 /* Three times for good luck. The linker seems to get confused
3929 if there are fewer than three */
3930 VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
3931 VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
3932 GBLSYM_DEF|GBLSYM_VAL);
3933 VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
3934 GBLSYM_DEF|GBLSYM_VAL);
3935 break;
3936 default:
3937 as_warn (_("Invalid globalvalue of %s"), stripped_name);
3938 break;
3939 } /* switch */
3940 } /* if */
3941 if (stripped_name) free (stripped_name); /* clean up */
3942 } /* for */
3943
3944}
3945
3946
3947
3948/*
3949 * Define a procedure entry pt/mask
3950 */
3951static void
3952VMS_Procedure_Entry_Pt (Name, Psect_Number, Psect_Offset, Entry_Mask)
3953 char *Name;
3954 int Psect_Number;
3955 int Psect_Offset;
3956 int Entry_Mask;
3957{
3958 char Local[32];
3959
3960 /*
3961 * We are writing a GSD record
3962 */
3963 Set_VMS_Object_File_Record (OBJ_S_C_GSD);
3964 /*
3965 * If the buffer is empty we must insert the GSD record type
3966 */
3967 if (Object_Record_Offset == 0)
3968 PUT_CHAR (OBJ_S_C_GSD);
3969 /*
3970 * We are writing a Procedure Entry Pt/Mask subrecord
3971 */
3972 PUT_CHAR (((unsigned) Psect_Number <= 255) ? GSD_S_C_EPM : GSD_S_C_EPMW);
3973 /*
3974 * Data type is undefined
3975 */
3976 PUT_CHAR (0);
3977 /*
3978 * Flags = "RELOCATABLE" and "DEFINED"
3979 */
3980 PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
3981 /*
3982 * Psect Number
3983 */
3984 if ((unsigned) Psect_Number <= 255)
3985 PUT_CHAR (Psect_Number);
3986 else
3987 PUT_SHORT (Psect_Number);
3988 /*
3989 * Offset
3990 */
3991 PUT_LONG (Psect_Offset);
3992 /*
3993 * Entry mask
3994 */
3995 PUT_SHORT (Entry_Mask);
3996 /*
3997 * Finally, the global symbol name
3998 */
3999 VMS_Case_Hack_Symbol (Name, Local);
4000 PUT_COUNTED_STRING (Local);
4001 /*
4002 * Flush the buffer if it is more than 75% full
4003 */
4004 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4005 Flush_VMS_Object_Record_Buffer ();
4006}
4007
4008
4009
4010/*
4011 * Set the current location counter to a particular Psect and Offset
4012 */
4013static void
4014VMS_Set_Psect (Psect_Index, Offset, Record_Type)
4015 int Psect_Index;
4016 int Offset;
4017 int Record_Type;
4018{
4019 /*
4020 * We are writing a "Record_Type" record
4021 */
4022 Set_VMS_Object_File_Record (Record_Type);
4023 /*
4024 * If the buffer is empty we must insert the record type
4025 */
4026 if (Object_Record_Offset == 0)
4027 PUT_CHAR (Record_Type);
4028 /*
4029 * Stack the Psect base + Offset
4030 */
4031 vms_tir_stack_psect (Psect_Index, Offset, 0);
4032 /*
4033 * Set relocation base
4034 */
4035 PUT_CHAR (TIR_S_C_CTL_SETRB);
4036 /*
4037 * Flush the buffer if it is more than 75% full
4038 */
4039 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4040 Flush_VMS_Object_Record_Buffer ();
4041}
4042
4043
4044
4045/*
4046 * Store repeated immediate data in current Psect
4047 */
4048static void
4049VMS_Store_Repeated_Data (Repeat_Count, Pointer, Size, Record_Type)
4050 int Repeat_Count;
4051 register char *Pointer;
4052 int Size;
4053 int Record_Type;
4054{
4055
4056 /*
4057 * Ignore zero bytes/words/longwords
4058 */
4059 switch (Size)
4060 {
4061 case 4:
4062 if (Pointer[3] != 0 || Pointer[2] != 0) break;
4063 /* else FALLTHRU */
4064 case 2:
4065 if (Pointer[1] != 0) break;
4066 /* else FALLTHRU */
4067 case 1:
4068 if (Pointer[0] != 0) break;
4069 /* zero value */
4070 return;
4071 default:
4072 break;
4073 }
4074 /*
4075 * If the data is too big for a TIR_S_C_STO_RIVB sub-record
4076 * then we do it manually
4077 */
4078 if (Size > 255)
4079 {
4080 while (--Repeat_Count >= 0)
4081 VMS_Store_Immediate_Data (Pointer, Size, Record_Type);
4082 return;
4083 }
4084 /*
4085 * We are writing a "Record_Type" record
4086 */
4087 Set_VMS_Object_File_Record (Record_Type);
4088 /*
4089 * If the buffer is empty we must insert record type
4090 */
4091 if (Object_Record_Offset == 0)
4092 PUT_CHAR (Record_Type);
4093 /*
4094 * Stack the repeat count
4095 */
4096 PUT_CHAR (TIR_S_C_STA_LW);
4097 PUT_LONG (Repeat_Count);
4098 /*
4099 * And now the command and its data
4100 */
4101 PUT_CHAR (TIR_S_C_STO_RIVB);
4102 PUT_CHAR (Size);
4103 while (--Size >= 0)
4104 PUT_CHAR (*Pointer++);
4105 /*
4106 * Flush the buffer if it is more than 75% full
4107 */
4108 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4109 Flush_VMS_Object_Record_Buffer ();
4110}
4111
4112
4113
4114/*
4115 * Store a Position Independent Reference
4116 */
4117static void
4118VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative,
4119 Psect, Psect_Offset, Record_Type)
4120 symbolS *Symbol;
4121 int Offset;
4122 int PC_Relative;
4123 int Psect;
4124 int Psect_Offset;
4125 int Record_Type;
4126{
4127 register struct VMS_Symbol *vsp = Symbol->sy_obj;
4128 char Local[32];
4129 int local_sym = 0;
4130
4131 /*
4132 * We are writing a "Record_Type" record
4133 */
4134 Set_VMS_Object_File_Record (Record_Type);
4135 /*
4136 * If the buffer is empty we must insert record type
4137 */
4138 if (Object_Record_Offset == 0)
4139 PUT_CHAR (Record_Type);
4140 /*
4141 * Set to the appropriate offset in the Psect.
4142 * For a Code reference we need to fix the operand
4143 * specifier as well, so back up 1 byte;
4144 * for a Data reference we just store HERE.
4145 */
4146 VMS_Set_Psect (Psect,
4147 PC_Relative ? Psect_Offset - 1 : Psect_Offset,
4148 Record_Type);
4149 /*
4150 * Make sure we are still generating a "Record Type" record
4151 */
4152 if (Object_Record_Offset == 0)
4153 PUT_CHAR (Record_Type);
4154 /*
4155 * Dispatch on symbol type (so we can stack its value)
4156 */
4157 switch (S_GET_RAW_TYPE (Symbol))
4158 {
4159 /*
4160 * Global symbol
4161 */
4162 case N_ABS:
4163 local_sym = 1;
4164 /*FALLTHRU*/
4165 case N_ABS | N_EXT:
4166#ifdef NOT_VAX_11_C_COMPATIBLE
4167 case N_UNDF | N_EXT:
4168 case N_DATA | N_EXT:
4169#endif /* NOT_VAX_11_C_COMPATIBLE */
4170 case N_UNDF:
4171 case N_TEXT | N_EXT:
4172 /*
4173 * Get the symbol name (case hacked)
4174 */
4175 VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local);
4176 /*
4177 * Stack the global symbol value
4178 */
4179 if (!local_sym)
4180 {
4181 PUT_CHAR (TIR_S_C_STA_GBL);
4182 }
4183 else
4184 {
4185 /* Local symbols have an extra field. */
4186 PUT_CHAR (TIR_S_C_STA_LSY);
4187 PUT_SHORT (Current_Environment);
4188 }
4189 PUT_COUNTED_STRING (Local);
4190 if (Offset)
4191 {
4192 /*
4193 * Stack the longword offset
4194 */
4195 PUT_CHAR (TIR_S_C_STA_LW);
4196 PUT_LONG (Offset);
4197 /*
4198 * Add the two, leaving the result on the stack
4199 */
4200 PUT_CHAR (TIR_S_C_OPR_ADD);
4201 }
4202 break;
4203 /*
4204 * Uninitialized local data
4205 */
4206 case N_BSS:
4207 /*
4208 * Stack the Psect (+offset)
4209 */
4210 vms_tir_stack_psect (vsp->Psect_Index,
4211 vsp->Psect_Offset + Offset,
4212 0);
4213 break;
4214 /*
4215 * Local text
4216 */
4217 case N_TEXT:
4218 /*
4219 * Stack the Psect (+offset)
4220 */
4221 vms_tir_stack_psect (vsp->Psect_Index,
4222 S_GET_VALUE (Symbol) + Offset,
4223 0);
4224 break;
4225 /*
4226 * Initialized local or global data
4227 */
4228 case N_DATA:
4229#ifndef NOT_VAX_11_C_COMPATIBLE
4230 case N_UNDF | N_EXT:
4231 case N_DATA | N_EXT:
4232#endif /* NOT_VAX_11_C_COMPATIBLE */
4233 /*
4234 * Stack the Psect (+offset)
4235 */
4236 vms_tir_stack_psect (vsp->Psect_Index,
4237 vsp->Psect_Offset + Offset,
4238 0);
4239 break;
4240 }
4241 /*
4242 * Store either a code or data reference
4243 */
4244 PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR);
4245 /*
4246 * Flush the buffer if it is more than 75% full
4247 */
4248 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4249 Flush_VMS_Object_Record_Buffer ();
4250}
4251
4252
4253
4254/*
4255 * Check in the text area for an indirect pc-relative reference
4256 * and fix it up with addressing mode 0xff [PC indirect]
4257 *
4258 * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
4259 * PIC CODE GENERATING FIXUP ROUTINE.
4260 */
4261static void
4262VMS_Fix_Indirect_Reference (Text_Psect, Offset, fragP, text_frag_root)
4263 int Text_Psect;
4264 addressT Offset;
4265 register fragS *fragP;
4266 fragS *text_frag_root;
4267{
4268 /*
4269 * The addressing mode byte is 1 byte before the address
4270 */
4271 Offset--;
4272 /*
4273 * Is it in THIS frag??
4274 */
4275 if ((Offset < fragP->fr_address) ||
4276 (Offset >= (fragP->fr_address + fragP->fr_fix)))
4277 {
4278 /*
4279 * We need to search for the fragment containing this
4280 * Offset
4281 */
4282 for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
4283 {
4284 if ((Offset >= fragP->fr_address) &&
4285 (Offset < (fragP->fr_address + fragP->fr_fix)))
4286 break;
4287 }
4288 /*
4289 * If we couldn't find the frag, things are BAD!!
4290 */
4291 if (fragP == 0)
4292 error (_("Couldn't find fixup fragment when checking for indirect reference"));
4293 }
4294 /*
4295 * Check for indirect PC relative addressing mode
4296 */
4297 if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff)
4298 {
4299 static char Address_Mode = (char) 0xff;
4300
4301 /*
4302 * Yes: Store the indirect mode back into the image
4303 * to fix up the damage done by STO_PICR
4304 */
4305 VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR);
4306 VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR);
4307 }
4308}
4309
4310
4311
4312/*
4313 * If the procedure "main()" exists we have to add the instruction
4314 * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
4315 *
4316 * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed
4317 * to `HACK_VAXCRTL_STARTUP' because Digital's compiler
4318 * named "DEC C" uses run-time library "DECC$SHR", but this
4319 * startup code is for "VAXCRTL", the library for Digital's
4320 * older "VAX C". Also, this extra code isn't needed for
4321 * supporting gcc because it already generates the VAXCRTL
4322 * startup call when compiling main(). The reference to
4323 * `flag_hash_long_names' looks very suspicious too;
4324 * probably an old-style command line option was inadvertently
4325 * overloaded here, then blindly converted into the new one.
4326 */
4327void
4328vms_check_for_main ()
4329{
4330 register symbolS *symbolP;
4331#ifdef HACK_DEC_C_STARTUP /* JF */
4332 register struct frchain *frchainP;
4333 register fragS *fragP;
4334 register fragS **prev_fragPP;
4335 register struct fix *fixP;
4336 register fragS *New_Frag;
4337 int i;
4338#endif /* HACK_DEC_C_STARTUP */
4339
4340 symbolP = (symbolS *) symbol_find ("_main");
4341 if (symbolP && !S_IS_DEBUG (symbolP) &&
4342 S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
4343 {
4344#ifdef HACK_DEC_C_STARTUP
4345 if (!flag_hash_long_names)
4346 {
4347#endif
4348 /*
4349 * Remember the entry point symbol
4350 */
4351 Entry_Point_Symbol = symbolP;
4352#ifdef HACK_DEC_C_STARTUP
4353 }
4354 else
4355 {
4356 /*
4357 * Scan all the fragment chains for the one with "_main"
4358 * (Actually we know the fragment from the symbol, but we need
4359 * the previous fragment so we can change its pointer)
4360 */
4361 frchainP = frchain_root;
4362 while (frchainP)
4363 {
4364 /*
4365 * Scan all the fragments in this chain, remembering
4366 * the "previous fragment"
4367 */
4368 prev_fragPP = &frchainP->frch_root;
4369 fragP = frchainP->frch_root;
4370 while (fragP && (fragP != frchainP->frch_last))
4371 {
4372 /*
4373 * Is this the fragment?
4374 */
4375 if (fragP == symbolP->sy_frag)
4376 {
4377 /*
4378 * Yes: Modify the fragment by replacing
4379 * it with a new fragment.
4380 */
4381 New_Frag = (fragS *)
4382 xmalloc (sizeof (*New_Frag) +
4383 fragP->fr_fix +
4384 fragP->fr_var +
4385 5);
4386 /*
4387 * The fragments are the same except
4388 * that the "fixed" area is larger
4389 */
4390 *New_Frag = *fragP;
4391 New_Frag->fr_fix += 6;
4392 /*
4393 * Copy the literal data opening a hole
4394 * 2 bytes after "_main" (i.e. just after
4395 * the entry mask). Into which we place
4396 * the JSB instruction.
4397 */
4398 New_Frag->fr_literal[0] = fragP->fr_literal[0];
4399 New_Frag->fr_literal[1] = fragP->fr_literal[1];
4400 New_Frag->fr_literal[2] = 0x16; /* Jsb */
4401 New_Frag->fr_literal[3] = 0xef;
4402 New_Frag->fr_literal[4] = 0;
4403 New_Frag->fr_literal[5] = 0;
4404 New_Frag->fr_literal[6] = 0;
4405 New_Frag->fr_literal[7] = 0;
4406 for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++)
4407 New_Frag->fr_literal[i + 6] =
4408 fragP->fr_literal[i];
4409 /*
4410 * Now replace the old fragment with the
4411 * newly generated one.
4412 */
4413 *prev_fragPP = New_Frag;
4414 /*
4415 * Remember the entry point symbol
4416 */
4417 Entry_Point_Symbol = symbolP;
4418 /*
4419 * Scan the text area fixup structures
4420 * as offsets in the fragment may have
4421 * changed
4422 */
4423 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
4424 {
4425 /*
4426 * Look for references to this
4427 * fragment.
4428 */
4429 if (fixP->fx_frag == fragP)
4430 {
4431 /*
4432 * Change the fragment
4433 * pointer
4434 */
4435 fixP->fx_frag = New_Frag;
4436 /*
4437 * If the offset is after
4438 * the entry mask we need
4439 * to account for the JSB
4440 * instruction we just
4441 * inserted.
4442 */
4443 if (fixP->fx_where >= 2)
4444 fixP->fx_where += 6;
4445 }
4446 }
4447 /*
4448 * Scan the symbols as offsets in the
4449 * fragment may have changed
4450 */
4451 for (symbolP = symbol_rootP;
4452 symbolP;
4453 symbolP = symbol_next (symbolP))
4454 {
4455 /*
4456 * Look for references to this
4457 * fragment.
4458 */
4459 if (symbolP->sy_frag == fragP)
4460 {
4461 /*
4462 * Change the fragment
4463 * pointer
4464 */
4465 symbolP->sy_frag = New_Frag;
4466 /*
4467 * If the offset is after
4468 * the entry mask we need
4469 * to account for the JSB
4470 * instruction we just
4471 * inserted.
4472 */
4473 if (S_GET_VALUE (symbolP) >= 2)
4474 S_SET_VALUE (symbolP,
4475 S_GET_VALUE (symbolP) + 6);
4476 }
4477 }
4478 /*
4479 * Make a symbol reference to
4480 * "_c$main_args" so we can get
4481 * its address inserted into the
4482 * JSB instruction.
4483 */
4484 symbolP = (symbolS *) xmalloc (sizeof (*symbolP));
4485 S_SET_NAME (symbolP, "_C$MAIN_ARGS");
4486 S_SET_TYPE (symbolP, N_UNDF);
4487 S_SET_OTHER (symbolP, 0);
4488 S_SET_DESC (symbolP, 0);
4489 S_SET_VALUE (symbolP, 0);
4490 symbolP->sy_name_offset = 0;
4491 symbolP->sy_number = 0;
4492 symbolP->sy_obj = 0;
4493 symbolP->sy_frag = New_Frag;
4494 symbolP->sy_resolved = 0;
4495 symbolP->sy_resolving = 0;
4496 /* this actually inserts at the beginning of the list */
4497 symbol_append (symbol_rootP, symbolP,
4498 &symbol_rootP, &symbol_lastP);
4499
4500 symbol_rootP = symbolP;
4501 /*
4502 * Generate a text fixup structure
4503 * to get "_c$main_args" stored into the
4504 * JSB instruction.
4505 */
4506 fixP = (struct fix *) xmalloc (sizeof (*fixP));
4507 fixP->fx_frag = New_Frag;
4508 fixP->fx_where = 4;
4509 fixP->fx_addsy = symbolP;
4510 fixP->fx_subsy = 0;
4511 fixP->fx_offset = 0;
4512 fixP->fx_size = 4;
4513 fixP->fx_pcrel = 1;
4514 fixP->fx_next = text_fix_root;
4515 text_fix_root = fixP;
4516 /*
4517 * Now make sure we exit from the loop
4518 */
4519 frchainP = 0;
4520 break;
4521 }
4522 /*
4523 * Try the next fragment
4524 */
4525 prev_fragPP = &fragP->fr_next;
4526 fragP = fragP->fr_next;
4527 }
4528 /*
4529 * Try the next fragment chain
4530 */
4531 if (frchainP)
4532 frchainP = frchainP->frch_next;
4533 }
4534 }
4535#endif /* HACK_DEC_C_STARTUP */
4536 }
4537}
4538
4539
4540
4541/*
4542 * Beginning of vms_write_object_file().
4543 */
4544
4545static
4546struct vms_obj_state {
4547
4548 /* Next program section index to use. */
4549 int psect_number;
4550
4551 /* Psect index for code. Always ends up #0. */
4552 int text_psect;
4553
4554 /* Psect index for initialized static variables. */
4555 int data_psect;
4556
4557 /* Psect index for uninitialized static variables. */
4558 int bss_psect;
4559
4560 /* Psect index for static constructors. */
4561 int ctors_psect;
4562
4563 /* Psect index for static destructors. */
4564 int dtors_psect;
4565
4566 /* Number of bytes used for local symbol data. */
4567 int local_initd_data_size;
4568
4569 /* Dynamic buffer for initialized data. */
4570 char *data_segment;
4571
4572} vms_obj_state;
4573
4574#define Psect_Number vms_obj_state.psect_number
4575#define Text_Psect vms_obj_state.text_psect
4576#define Data_Psect vms_obj_state.data_psect
4577#define Bss_Psect vms_obj_state.bss_psect
4578#define Ctors_Psect vms_obj_state.ctors_psect
4579#define Dtors_Psect vms_obj_state.dtors_psect
4580#define Local_Initd_Data_Size vms_obj_state.local_initd_data_size
4581#define Data_Segment vms_obj_state.data_segment
4582
4583#define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
4584#define IS_GXX_XTOR(symP) (strncmp (S_GET_NAME (symP), "__GLOBAL_.", 10) == 0)
4585#define XTOR_SIZE 4
4586
4587
4588
4589/* Perform text segment fixups. */
4590
4591static void
4592vms_fixup_text_section (text_siz, text_frag_root, data_frag_root)
4593 unsigned text_siz ATTRIBUTE_UNUSED;
4594 struct frag *text_frag_root;
4595 struct frag *data_frag_root;
4596{
4597 register fragS *fragP;
4598 register struct fix *fixP;
4599 offsetT dif;
4600
4601 /* Scan the text fragments. */
4602 for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
4603 {
4604 /* Stop if we get to the data fragments. */
4605 if (fragP == data_frag_root)
4606 break;
4607 /* Ignore fragments with no data. */
4608 if ((fragP->fr_fix == 0) && (fragP->fr_var == 0))
4609 continue;
4610 /* Go the the appropriate offset in the Text Psect. */
4611 VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR);
4612 /* Store the "fixed" part. */
4613 if (fragP->fr_fix)
4614 VMS_Store_Immediate_Data (fragP->fr_literal,
4615 fragP->fr_fix,
4616 OBJ_S_C_TIR);
4617 /* Store the "variable" part. */
4618 if (fragP->fr_var && fragP->fr_offset)
4619 VMS_Store_Repeated_Data (fragP->fr_offset,
4620 fragP->fr_literal + fragP->fr_fix,
4621 fragP->fr_var,
4622 OBJ_S_C_TIR);
4623 } /* text frag loop */
4624
4625 /*
4626 * Now we go through the text segment fixups and generate
4627 * TIR records to fix up addresses within the Text Psect.
4628 */
4629 for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
4630 {
4631 /* We DO handle the case of "Symbol - Symbol" as
4632 long as it is in the same segment. */
4633 if (fixP->fx_subsy && fixP->fx_addsy)
4634 {
4635 /* They need to be in the same segment. */
4636 if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
4637 S_GET_RAW_TYPE (fixP->fx_addsy))
4638 error (_("Fixup data addsy and subsy don't have the same type"));
4639 /* And they need to be in one that we can check the psect on. */
4640 if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
4641 (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
4642 error (_("Fixup data addsy and subsy don't have an appropriate type"));
4643 /* This had better not be PC relative! */
4644 if (fixP->fx_pcrel)
4645 error (_("Fixup data is erroneously \"pcrel\""));
4646 /* Subtract their values to get the difference. */
4647 dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
4648 md_number_to_chars (Local, (valueT)dif, fixP->fx_size);
4649 /* Now generate the fixup object records;
4650 set the psect and store the data. */
4651 VMS_Set_Psect (Text_Psect,
4652 fixP->fx_where + fixP->fx_frag->fr_address,
4653 OBJ_S_C_TIR);
4654 VMS_Store_Immediate_Data (Local,
4655 fixP->fx_size,
4656 OBJ_S_C_TIR);
4657 continue; /* done with this fixup */
4658 } /* if fx_subsy && fx_addsy */
4659 /* Size will HAVE to be "long". */
4660 if (fixP->fx_size != 4)
4661 error (_("Fixup datum is not a longword"));
4662 /* Symbol must be "added" (if it is ever
4663 subtracted we can fix this assumption). */
4664 if (fixP->fx_addsy == 0)
4665 error (_("Fixup datum is not \"fixP->fx_addsy\""));
4666 /* Store the symbol value in a PIC fashion. */
4667 VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
4668 fixP->fx_offset,
4669 fixP->fx_pcrel,
4670 Text_Psect,
4671 fixP->fx_where + fixP->fx_frag->fr_address,
4672 OBJ_S_C_TIR);
4673 /*
4674 * Check for indirect address reference, which has to be fixed up
4675 * (as the linker will screw it up with TIR_S_C_STO_PICR)...
4676 */
4677 if (fixP->fx_pcrel)
4678 VMS_Fix_Indirect_Reference (Text_Psect,
4679 fixP->fx_where + fixP->fx_frag->fr_address,
4680 fixP->fx_frag,
4681 text_frag_root);
4682 } /* text fix loop */
4683}
4684
4685
4686
4687/* Create a buffer holding the data segment. */
4688
4689static void
4690synthesize_data_segment (data_siz, text_siz, data_frag_root)
4691 unsigned data_siz;
4692 unsigned text_siz;
4693 struct frag *data_frag_root;
4694{
4695 register fragS *fragP;
4696 char *fill_literal;
4697 long fill_size, count, i;
4698
4699 /* Allocate the data segment. */
4700 Data_Segment = (char *) xmalloc (data_siz);
4701 /* Run through the data fragments, filling in the segment. */
4702 for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
4703 {
4704 i = fragP->fr_address - text_siz;
4705 if (fragP->fr_fix)
4706 memcpy (Data_Segment + i, fragP->fr_literal, fragP->fr_fix);
4707 i += fragP->fr_fix;
4708
4709 if ((fill_size = fragP->fr_var) != 0)
4710 {
4711 fill_literal = fragP->fr_literal + fragP->fr_fix;
4712 for (count = fragP->fr_offset; count; count--)
4713 {
4714 memcpy (Data_Segment + i, fill_literal, fill_size);
4715 i += fill_size;
4716 }
4717 }
4718 } /* data frag loop */
4719
4720 return;
4721}
4722
4723/* Perform data segment fixups. */
4724
4725static void
4726vms_fixup_data_section (data_siz, text_siz)
4727 unsigned int data_siz ATTRIBUTE_UNUSED;
4728 unsigned int text_siz;
4729{
4730 register struct VMS_Symbol *vsp;
4731 register struct fix *fixP;
4732 register symbolS *sp;
4733 addressT fr_address;
4734 offsetT dif;
4735 valueT val;
4736
4737 /* Run through all the data symbols and store the data. */
4738 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4739 {
4740 /* Ignore anything other than data symbols. */
4741 if (S_GET_TYPE (vsp->Symbol) != N_DATA)
4742 continue;
4743 /* Set the Psect + Offset. */
4744 VMS_Set_Psect (vsp->Psect_Index,
4745 vsp->Psect_Offset,
4746 OBJ_S_C_TIR);
4747 /* Store the data. */
4748 val = S_GET_VALUE (vsp->Symbol);
4749 VMS_Store_Immediate_Data (Data_Segment + val - text_siz,
4750 vsp->Size,
4751 OBJ_S_C_TIR);
4752 } /* N_DATA symbol loop */
4753
4754 /*
4755 * Now we go through the data segment fixups and generate
4756 * TIR records to fix up addresses within the Data Psects.
4757 */
4758 for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
4759 {
4760 /* Find the symbol for the containing datum. */
4761 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
4762 {
4763 /* Only bother with Data symbols. */
4764 sp = vsp->Symbol;
4765 if (S_GET_TYPE (sp) != N_DATA)
4766 continue;
4767 /* Ignore symbol if After fixup. */
4768 val = S_GET_VALUE (sp);
4769 fr_address = fixP->fx_frag->fr_address;
4770 if (val > fixP->fx_where + fr_address)
4771 continue;
4772 /* See if the datum is here. */
4773 if (val + vsp->Size <= fixP->fx_where + fr_address)
4774 continue;
4775 /* We DO handle the case of "Symbol - Symbol" as
4776 long as it is in the same segment. */
4777 if (fixP->fx_subsy && fixP->fx_addsy)
4778 {
4779 /* They need to be in the same segment. */
4780 if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
4781 S_GET_RAW_TYPE (fixP->fx_addsy))
4782 error (_("Fixup data addsy and subsy don't have the same type"));
4783 /* And they need to be in one that we can check the psect on. */
4784 if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
4785 (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
4786 error (_("Fixup data addsy and subsy don't have an appropriate type"));
4787 /* This had better not be PC relative! */
4788 if (fixP->fx_pcrel)
4789 error (_("Fixup data is erroneously \"pcrel\""));
4790 /* Subtract their values to get the difference. */
4791 dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
4792 md_number_to_chars (Local, (valueT)dif, fixP->fx_size);
4793 /*
4794 * Now generate the fixup object records;
4795 * set the psect and store the data.
4796 */
4797 VMS_Set_Psect (vsp->Psect_Index,
4798 fr_address + fixP->fx_where
4799 - val + vsp->Psect_Offset,
4800 OBJ_S_C_TIR);
4801 VMS_Store_Immediate_Data (Local,
4802 fixP->fx_size,
4803 OBJ_S_C_TIR);
4804 break; /* done with this fixup */
4805 }
4806 /* Size will HAVE to be "long". */
4807 if (fixP->fx_size != 4)
4808 error (_("Fixup datum is not a longword"));
4809 /* Symbol must be "added" (if it is ever
4810 subtracted we can fix this assumption). */
4811 if (fixP->fx_addsy == 0)
4812 error (_("Fixup datum is not \"fixP->fx_addsy\""));
4813 /* Store the symbol value in a PIC fashion. */
4814 VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
4815 fixP->fx_offset,
4816 fixP->fx_pcrel,
4817 vsp->Psect_Index,
4818 fr_address + fixP->fx_where
4819 - val + vsp->Psect_Offset,
4820 OBJ_S_C_TIR);
4821 /* Done with this fixup. */
4822 break;
4823 } /* vms_symbol loop */
4824
4825 } /* data fix loop */
4826}
4827
4828/* Perform ctors/dtors segment fixups. */
4829
4830static void
4831vms_fixup_xtors_section (symbols, sect_no)
4832 struct VMS_Symbol *symbols;
4833 int sect_no ATTRIBUTE_UNUSED;
4834{
4835 register struct VMS_Symbol *vsp;
4836
4837 /* Run through all the symbols and store the data. */
4838 for (vsp = symbols; vsp; vsp = vsp->Next)
4839 {
4840 register symbolS *sp;
4841
4842 /* Set relocation base. */
4843 VMS_Set_Psect (vsp->Psect_Index, vsp->Psect_Offset, OBJ_S_C_TIR);
4844
4845 sp = vsp->Symbol;
4846 /* Stack the Psect base with its offset. */
4847 VMS_Set_Data (Text_Psect, S_GET_VALUE (sp), OBJ_S_C_TIR, 0);
4848 }
4849 /* Flush the buffer if it is more than 75% full. */
4850 if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
4851 Flush_VMS_Object_Record_Buffer ();
4852
4853 return;
4854}
4855
4856
4857
4858/* Define symbols for the linker. */
4859
4860static void
4861global_symbol_directory (text_siz, data_siz)
4862 unsigned text_siz, data_siz;
4863{
4864 register fragS *fragP;
4865 register symbolS *sp;
4866 register struct VMS_Symbol *vsp;
4867 int Globalref, define_as_global_symbol;
4868
4869#if 0
4870 /* The g++ compiler does not write out external references to
4871 vtables correctly. Check for this and holler if we see it
4872 happening. If that compiler bug is ever fixed we can remove
4873 this.
4874
4875 (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
4876
4877 This was reportedly fixed as of June 2, 1998. */
4878
4879 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4880 if (S_GET_RAW_TYPE (sp) == N_UNDF && IS_GXX_VTABLE (sp))
4881 {
4882 S_SET_TYPE (sp, N_UNDF | N_EXT);
4883 S_SET_OTHER (sp, 1);
4884 as_warn (_("g++ wrote an extern reference to `%s' as a routine.\nI will fix it, but I hope that it was note really a routine."),
4885 S_GET_NAME (sp));
4886 }
4887#endif
4888
4889 /*
4890 * Now scan the symbols and emit the appropriate GSD records
4891 */
4892 for (sp = symbol_rootP; sp; sp = symbol_next (sp))
4893 {
4894 define_as_global_symbol = 0;
4895 vsp = 0;
4896 /* Dispatch on symbol type. */
4897 switch (S_GET_RAW_TYPE (sp))
4898 {
4899
4900 /* Global uninitialized data. */
4901 case N_UNDF | N_EXT:
4902 /* Make a VMS data symbol entry. */
4903 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
4904 vsp->Symbol = sp;
4905 vsp->Size = S_GET_VALUE (sp);
4906 vsp->Psect_Index = Psect_Number++;
4907 vsp->Psect_Offset = 0;
4908 vsp->Next = VMS_Symbols;
4909 VMS_Symbols = vsp;
4910 sp->sy_obj = vsp;
4911 /* Make the psect for this data. */
4912 Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
4913 vsp->Size,
4914 S_GET_OTHER (sp) ? ps_CONST : ps_COMMON,
4915 vsp);
4916 if (Globalref)
4917 Psect_Number--;
4918#ifdef NOT_VAX_11_C_COMPATIBLE
4919 define_as_global_symbol = 1;
4920#else
4921 /* See if this is an external vtable. We want to help the
4922 linker find these things in libraries, so we make a symbol
4923 reference. This is not compatible with VAX-C usage for
4924 variables, but since vtables are only used internally by
4925 g++, we can get away with this hack. */
4926 define_as_global_symbol = IS_GXX_VTABLE (sp);
4927#endif
4928 break;
4929
4930 /* Local uninitialized data. */
4931 case N_BSS:
4932 /* Make a VMS data symbol entry. */
4933 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
4934 vsp->Symbol = sp;
4935 vsp->Size = 0;
4936 vsp->Psect_Index = Bss_Psect;
4937 vsp->Psect_Offset = S_GET_VALUE (sp) - bss_address_frag.fr_address;
4938 vsp->Next = VMS_Symbols;
4939 VMS_Symbols = vsp;
4940 sp->sy_obj = vsp;
4941 break;
4942
4943 /* Global initialized data. */
4944 case N_DATA | N_EXT:
4945 /* Make a VMS data symbol entry. */
4946 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
4947 vsp->Symbol = sp;
4948 vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
4949 vsp->Psect_Index = Psect_Number++;
4950 vsp->Psect_Offset = 0;
4951 vsp->Next = VMS_Symbols;
4952 VMS_Symbols = vsp;
4953 sp->sy_obj = vsp;
4954 /* Make its psect. */
4955 Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
4956 vsp->Size,
4957 S_GET_OTHER (sp) ? ps_CONST : ps_COMMON,
4958 vsp);
4959 if (Globalref)
4960 Psect_Number--;
4961#ifdef NOT_VAX_11_C_COMPATIBLE
4962 define_as_global_symbol = 1;
4963#else
4964 /* See N_UNDF|N_EXT above for explanation. */
4965 define_as_global_symbol = IS_GXX_VTABLE (sp);
4966#endif
4967 break;
4968
4969 /* Local initialized data. */
4970 case N_DATA:
4971 {
4972 char *sym_name = S_GET_NAME (sp);
4973
4974 /* Always suppress local numeric labels. */
4975 if (sym_name && strcmp (sym_name, FAKE_LABEL_NAME) == 0)
4976 break;
4977
4978 /* Make a VMS data symbol entry. */
4979 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
4980 vsp->Symbol = sp;
4981 vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
4982 vsp->Psect_Index = Data_Psect;
4983 vsp->Psect_Offset = Local_Initd_Data_Size;
4984 Local_Initd_Data_Size += vsp->Size;
4985 vsp->Next = VMS_Symbols;
4986 VMS_Symbols = vsp;
4987 sp->sy_obj = vsp;
4988 }
4989 break;
4990
4991 /* Global Text definition. */
4992 case N_TEXT | N_EXT:
4993 {
4994
4995 if (IS_GXX_XTOR (sp))
4996 {
4997 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
4998 vsp->Symbol = sp;
4999 vsp->Size = XTOR_SIZE;
5000 sp->sy_obj = vsp;
5001 switch ((S_GET_NAME (sp))[10])
5002 {
5003 case 'I':
5004 vsp->Psect_Index = Ctors_Psect;
5005 vsp->Psect_Offset = (Ctors_Symbols==0)?0:(Ctors_Symbols->Psect_Offset+XTOR_SIZE);
5006 vsp->Next = Ctors_Symbols;
5007 Ctors_Symbols = vsp;
5008 break;
5009 case 'D':
5010 vsp->Psect_Index = Dtors_Psect;
5011 vsp->Psect_Offset = (Dtors_Symbols==0)?0:(Dtors_Symbols->Psect_Offset+XTOR_SIZE);
5012 vsp->Next = Dtors_Symbols;
5013 Dtors_Symbols = vsp;
5014 break;
5015 case 'G':
5016 as_warn (_("Can't handle global xtors symbols yet."));
5017 break;
5018 default:
5019 as_warn (_("Unknown %s"), S_GET_NAME (sp));
5020 break;
5021 }
5022 }
5023 else
5024 {
5025 unsigned short Entry_Mask;
5026
5027 /* Get the entry mask. */
5028 fragP = sp->sy_frag;
5029 /* First frag might be empty if we're generating listings.
5030 So skip empty rs_fill frags. */
5031 while (fragP && fragP->fr_type == rs_fill && fragP->fr_fix == 0)
5032 fragP = fragP->fr_next;
5033
5034 /* If first frag doesn't contain the data, what do we do?
5035 If it's possibly smaller than two bytes, that would
5036 imply that the entry mask is not stored where we're
5037 expecting it.
5038
5039 If you can find a test case that triggers this, report
5040 it (and tell me what the entry mask field ought to be),
5041 and I'll try to fix it. KR */
5042 if (fragP->fr_fix < 2)
5043 abort ();
5044
5045 Entry_Mask = (fragP->fr_literal[0] & 0x00ff) |
5046 ((fragP->fr_literal[1] & 0x00ff) << 8);
5047 /* Define the procedure entry point. */
5048 VMS_Procedure_Entry_Pt (S_GET_NAME (sp),
5049 Text_Psect,
5050 S_GET_VALUE (sp),
5051 Entry_Mask);
5052 }
5053 break;
5054 }
5055
5056 /* Local Text definition. */
5057 case N_TEXT:
5058 /* Make a VMS data symbol entry. */
5059 if (Text_Psect != -1)
5060 {
5061 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
5062 vsp->Symbol = sp;
5063 vsp->Size = 0;
5064 vsp->Psect_Index = Text_Psect;
5065 vsp->Psect_Offset = S_GET_VALUE (sp);
5066 vsp->Next = VMS_Symbols;
5067 VMS_Symbols = vsp;
5068 sp->sy_obj = vsp;
5069 }
5070 break;
5071
5072 /* Global Reference. */
5073 case N_UNDF:
5074 /* Make a GSD global symbol reference record. */
5075 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
5076 0,
5077 0,
5078 GBLSYM_REF);
5079 break;
5080
5081 /* Absolute symbol. */
5082 case N_ABS:
5083 case N_ABS | N_EXT:
5084 /* gcc doesn't generate these;
5085 VMS_Emit_Globalvalue handles them though. */
5086 vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
5087 vsp->Symbol = sp;
5088 vsp->Size = 4; /* always assume 32 bits */
5089 vsp->Psect_Index = 0;
5090 vsp->Psect_Offset = S_GET_VALUE (sp);
5091 vsp->Next = VMS_Symbols;
5092 VMS_Symbols = vsp;
5093 sp->sy_obj = vsp;
5094 break;
5095
5096 /* Anything else. */
5097 default:
5098 /* Ignore STAB symbols, including .stabs emitted by g++. */
5099 if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22))
5100 break;
5101 /*
5102 * Error otherwise.
5103 */
5104 as_tsktsk (_("unhandled stab type %d"), S_GET_TYPE (sp));
5105 break;
5106 }
5107
5108 /* Global symbols have different linkage than external variables. */
5109 if (define_as_global_symbol)
5110 VMS_Global_Symbol_Spec (S_GET_NAME (sp),
5111 vsp->Psect_Index,
5112 0,
5113 GBLSYM_DEF);
5114 }
5115
5116 return;
5117}
5118
5119
5120
5121/* Output debugger symbol table information for symbols which
5122 are local to a specific routine. */
5123
5124static void
5125local_symbols_DST (s0P, Current_Routine)
5126 symbolS *s0P, *Current_Routine;
5127{
5128 symbolS *s1P;
5129 char *s0P_name, *pnt0, *pnt1;
5130
5131 s0P_name = S_GET_NAME (s0P);
5132 if (*s0P_name++ != '_')
5133 return;
5134
5135 for (s1P = Current_Routine; s1P; s1P = symbol_next (s1P))
5136 {
5137#if 0 /* redundant; RAW_TYPE != N_FUN suffices */
5138 if (!S_IS_DEBUG (s1P))
5139 continue;
5140#endif
5141 if (S_GET_RAW_TYPE (s1P) != N_FUN)
5142 continue;
5143 pnt0 = s0P_name;
5144 pnt1 = S_GET_NAME (s1P);
5145 /* We assume the two strings are never exactly equal... */
5146 while (*pnt0++ == *pnt1++)
5147 {
5148 }
5149 /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next.
5150 Note: both pointers have advanced one past the non-matching char. */
5151 if ((*pnt1 == 'F' || *pnt1 == 'f') && *--pnt1 == ':' && *--pnt0 == '\0')
5152 {
5153 Define_Routine (s1P, 0, Current_Routine, Text_Psect);
5154 return;
5155 }
5156 }
5157}
5158
5159/* Construct and output the debug symbol table. */
5160
5161static void
5162vms_build_DST (text_siz)
5163 unsigned text_siz;
5164{
5165 register symbolS *symbolP;
5166 symbolS *Current_Routine = 0;
5167 struct input_file *Cur_File = 0;
5168 offsetT Cur_Offset = -1;
5169 int Cur_Line_Number = 0;
5170 int File_Number = 0;
5171 int Debugger_Offset = 0;
5172 int file_available;
5173 int dsc;
5174 offsetT val;
5175
5176 /* Write the Traceback Begin Module record. */
5177 VMS_TBT_Module_Begin ();
5178
5179 /*
5180 * Output debugging info for global variables and static variables
5181 * that are not specific to one routine. We also need to examine
5182 * all stabs directives, to find the definitions to all of the
5183 * advanced data types, and this is done by VMS_LSYM_Parse. This
5184 * needs to be done before any definitions are output to the object
5185 * file, since there can be forward references in the stabs
5186 * directives. When through with parsing, the text of the stabs
5187 * directive is altered, with the definitions removed, so that later
5188 * passes will see directives as they would be written if the type
5189 * were already defined.
5190 *
5191 * We also look for files and include files, and make a list of
5192 * them. We examine the source file numbers to establish the actual
5193 * lines that code was generated from, and then generate offsets.
5194 */
5195 VMS_LSYM_Parse ();
5196 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
5197 {
5198 /* Only deal with STAB symbols here. */
5199 if (!S_IS_DEBUG (symbolP))
5200 continue;
5201 /*
5202 * Dispatch on STAB type.
5203 */
5204 switch (S_GET_RAW_TYPE (symbolP))
5205 {
5206 case N_SLINE:
5207 dsc = S_GET_DESC (symbolP);
5208 if (dsc > Cur_File->max_line)
5209 Cur_File->max_line = dsc;
5210 if (dsc < Cur_File->min_line)
5211 Cur_File->min_line = dsc;
5212 break;
5213 case N_SO:
5214 Cur_File = find_file (symbolP);
5215 Cur_File->flag = 1;
5216 Cur_File->min_line = 1;
5217 break;
5218 case N_SOL:
5219 Cur_File = find_file (symbolP);
5220 break;
5221 case N_GSYM:
5222 VMS_GSYM_Parse (symbolP, Text_Psect);
5223 break;
5224 case N_LCSYM:
5225 VMS_LCSYM_Parse (symbolP, Text_Psect);
5226 break;
5227 case N_FUN: /* For static constant symbols */
5228 case N_STSYM:
5229 VMS_STSYM_Parse (symbolP, Text_Psect);
5230 break;
5231 default:
5232 break;
5233 } /* switch */
5234 } /* for */
5235
5236 /*
5237 * Now we take a quick sweep through the files and assign offsets
5238 * to each one. This will essentially be the starting line number to
5239 * the debugger for each file. Output the info for the debugger to
5240 * specify the files, and then tell it how many lines to use.
5241 */
5242 for (Cur_File = file_root; Cur_File; Cur_File = Cur_File->next)
5243 {
5244 if (Cur_File->max_line == 0)
5245 continue;
5246 if ((strncmp (Cur_File->name, "GNU_GXX_INCLUDE:", 16) == 0) &&
5247 !flag_debug)
5248 continue;
5249 if ((strncmp (Cur_File->name, "GNU_CC_INCLUDE:", 15) == 0) &&
5250 !flag_debug)
5251 continue;
5252 /* show a few extra lines at the start of the region selected */
5253 if (Cur_File->min_line > 2)
5254 Cur_File->min_line -= 2;
5255 Cur_File->offset = Debugger_Offset - Cur_File->min_line + 1;
5256 Debugger_Offset += Cur_File->max_line - Cur_File->min_line + 1;
5257 if (Cur_File->same_file_fpnt)
5258 {
5259 Cur_File->file_number = Cur_File->same_file_fpnt->file_number;
5260 }
5261 else
5262 {
5263 Cur_File->file_number = ++File_Number;
5264 file_available = VMS_TBT_Source_File (Cur_File->name,
5265 Cur_File->file_number);
5266 if (!file_available)
5267 {
5268 Cur_File->file_number = 0;
5269 File_Number--;
5270 continue;
5271 }
5272 }
5273 VMS_TBT_Source_Lines (Cur_File->file_number,
5274 Cur_File->min_line,
5275 Cur_File->max_line - Cur_File->min_line + 1);
5276 } /* for */
5277 Cur_File = (struct input_file *) NULL;
5278
5279 /*
5280 * Scan the symbols and write out the routines
5281 * (this makes the assumption that symbols are in
5282 * order of ascending text segment offset)
5283 */
5284 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
5285 {
5286 /*
5287 * Deal with text symbols.
5288 */
5289 if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
5290 {
5291 /*
5292 * Ignore symbols starting with "L", as they are local symbols.
5293 */
5294 if (*S_GET_NAME (symbolP) == 'L')
5295 continue;
5296 /*
5297 * If there is a routine start defined, terminate it.
5298 */
5299 if (Current_Routine)
5300 VMS_TBT_Routine_End (text_siz, Current_Routine);
5301
5302 /*
5303 * Check for & skip dummy labels like "gcc_compiled.".
5304 * They're identified by the IN_DEFAULT_SECTION flag.
5305 */
5306 if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 &&
5307 S_GET_VALUE (symbolP) == 0)
5308 continue;
5309 /*
5310 * Store the routine begin traceback info.
5311 */
5312 VMS_TBT_Routine_Begin (symbolP, Text_Psect);
5313 Current_Routine = symbolP;
5314 /*
5315 * Define symbols local to this routine.
5316 */
5317 local_symbols_DST (symbolP, Current_Routine);
5318 /*
5319 * Done
5320 */
5321 continue;
5322
5323 }
5324 /*
5325 * Deal with STAB symbols.
5326 */
5327 else if (S_IS_DEBUG (symbolP))
5328 {
5329 /*
5330 * Dispatch on STAB type.
5331 */
5332 switch (S_GET_RAW_TYPE (symbolP))
5333 {
5334 /*
5335 * Line number
5336 */
5337 case N_SLINE:
5338 /* Offset the line into the correct portion of the file. */
5339 if (Cur_File->file_number == 0)
5340 break;
5341 val = S_GET_VALUE (symbolP);
5342 /* Sometimes the same offset gets several source lines
5343 assigned to it. We should be selective about which
5344 lines we allow, we should prefer lines that are in
5345 the main source file when debugging inline functions. */
5346 if (val == Cur_Offset && Cur_File->file_number != 1)
5347 break;
5348
5349 /* calculate actual debugger source line */
5350 dsc = S_GET_DESC (symbolP) + Cur_File->offset;
5351 S_SET_DESC (symbolP, dsc);
5352 /*
5353 * Define PC/Line correlation.
5354 */
5355 if (Cur_Offset == -1)
5356 {
5357 /*
5358 * First N_SLINE; set up initial correlation.
5359 */
5360 VMS_TBT_Line_PC_Correlation (dsc,
5361 val,
5362 Text_Psect,
5363 0);
5364 }
5365 else if ((dsc - Cur_Line_Number) <= 0)
5366 {
5367 /*
5368 * Line delta is not +ve, we need to close the line and
5369 * start a new PC/Line correlation.
5370 */
5371 VMS_TBT_Line_PC_Correlation (0,
5372 val - Cur_Offset,
5373 0,
5374 -1);
5375 VMS_TBT_Line_PC_Correlation (dsc,
5376 val,
5377 Text_Psect,
5378 0);
5379 }
5380 else
5381 {
5382 /*
5383 * Line delta is +ve, all is well.
5384 */
5385 VMS_TBT_Line_PC_Correlation (dsc - Cur_Line_Number,
5386 val - Cur_Offset,
5387 0,
5388 1);
5389 }
5390 /* Update the current line/PC info. */
5391 Cur_Line_Number = dsc;
5392 Cur_Offset = val;
5393 break;
5394
5395 /*
5396 * Source file
5397 */
5398 case N_SO:
5399 /* Remember that we had a source file and emit
5400 the source file debugger record. */
5401 Cur_File = find_file (symbolP);
5402 break;
5403
5404 case N_SOL:
5405 /* We need to make sure that we are really in the actual
5406 source file when we compute the maximum line number.
5407 Otherwise the debugger gets really confused. */
5408 Cur_File = find_file (symbolP);
5409 break;
5410
5411 default:
5412 break;
5413 } /* switch */
5414 } /* if (IS_DEBUG) */
5415 } /* for */
5416
5417 /*
5418 * If there is a routine start defined, terminate it
5419 * (and the line numbers).
5420 */
5421 if (Current_Routine)
5422 {
5423 /* Terminate the line numbers. */
5424 VMS_TBT_Line_PC_Correlation (0,
5425 text_siz - S_GET_VALUE (Current_Routine),
5426 0,
5427 -1);
5428 /* Terminate the routine. */
5429 VMS_TBT_Routine_End (text_siz, Current_Routine);
5430 }
5431
5432 /* Write the Traceback End Module TBT record. */
5433 VMS_TBT_Module_End ();
5434}
5435
5436
5437
5438/* Write a VAX/VMS object file (everything else has been done!). */
5439
5440void
5441vms_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
5442 data_frag_root)
5443 unsigned text_siz;
5444 unsigned data_siz;
5445 unsigned bss_siz;
5446 fragS *text_frag_root;
5447 fragS *data_frag_root;
5448{
5449 register struct VMS_Symbol *vsp;
5450
5451 /*
5452 * Initialize program section indices; values get updated later.
5453 */
5454 Psect_Number = 0; /* next Psect Index to use */
5455 Text_Psect = -1; /* Text Psect Index */
5456 Data_Psect = -2; /* Data Psect Index JF: Was -1 */
5457 Bss_Psect = -3; /* Bss Psect Index JF: Was -1 */
5458 Ctors_Psect = -4; /* Ctors Psect Index */
5459 Dtors_Psect = -5; /* Dtors Psect Index */
5460 /* Initialize other state variables. */
5461 Data_Segment = 0;
5462 Local_Initd_Data_Size = 0;
5463
5464 /*
5465 * Create the actual output file and populate it with required
5466 * "module header" information.
5467 */
5468 Create_VMS_Object_File ();
5469 Write_VMS_MHD_Records ();
5470
5471 /*
5472 * Create the Data segment:
5473 *
5474 * Since this is REALLY hard to do any other way,
5475 * we actually manufacture the data segment and
5476 * then store the appropriate values out of it.
5477 * We need to generate this early, so that globalvalues
5478 * can be properly emitted.
5479 */
5480 if (data_siz > 0)
5481 synthesize_data_segment (data_siz, text_siz, data_frag_root);
5482
5483 /******* Global Symbol Directory *******/
5484
5485 /*
5486 * Emit globalvalues now. We must do this before the text psect is
5487 * defined, or we will get linker warnings about multiply defined
5488 * symbols. All of the globalvalues "reference" psect 0, although
5489 * it really does not have anything to do with it.
5490 */
5491 VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment);
5492 /*
5493 * Define the Text Psect
5494 */
5495 Text_Psect = Psect_Number++;
5496 VMS_Psect_Spec ("$code", text_siz, ps_TEXT, 0);
5497 /*
5498 * Define the BSS Psect
5499 */
5500 if (bss_siz > 0)
5501 {
5502 Bss_Psect = Psect_Number++;
5503 VMS_Psect_Spec ("$uninitialized_data", bss_siz, ps_DATA, 0);
5504 }
5505 /*
5506 * Define symbols to the linker.
5507 */
5508 global_symbol_directory (text_siz, data_siz);
5509 /*
5510 * Define the Data Psect
5511 */
5512 if (data_siz > 0 && Local_Initd_Data_Size > 0)
5513 {
5514 Data_Psect = Psect_Number++;
5515 VMS_Psect_Spec ("$data", Local_Initd_Data_Size, ps_DATA, 0);
5516 /*
5517 * Local initialized data (N_DATA) symbols need to be updated to the
5518 * proper value of Data_Psect now that it's actually been defined.
5519 * (A dummy value was used in global_symbol_directory() above.)
5520 */
5521 for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
5522 if (vsp->Psect_Index < 0 && S_GET_RAW_TYPE (vsp->Symbol) == N_DATA)
5523 vsp->Psect_Index = Data_Psect;
5524 }
5525
5526 if (Ctors_Symbols != 0)
5527 {
5528 char *ps_name = "$ctors";
5529 Ctors_Psect = Psect_Number++;
5530 VMS_Psect_Spec (ps_name, Ctors_Symbols->Psect_Offset + XTOR_SIZE,
5531 ps_CTORS, 0);
5532 VMS_Global_Symbol_Spec (ps_name, Ctors_Psect,
5533 0, GBLSYM_DEF|GBLSYM_WEAK);
5534 for (vsp = Ctors_Symbols; vsp; vsp = vsp->Next)
5535 vsp->Psect_Index = Ctors_Psect;
5536 }
5537
5538 if (Dtors_Symbols != 0)
5539 {
5540 char *ps_name = "$dtors";
5541 Dtors_Psect = Psect_Number++;
5542 VMS_Psect_Spec (ps_name, Dtors_Symbols->Psect_Offset + XTOR_SIZE,
5543 ps_DTORS, 0);
5544 VMS_Global_Symbol_Spec (ps_name, Dtors_Psect,
5545 0, GBLSYM_DEF|GBLSYM_WEAK);
5546 for (vsp = Dtors_Symbols; vsp; vsp = vsp->Next)
5547 vsp->Psect_Index = Dtors_Psect;
5548 }
5549
5550 /******* Text Information and Relocation Records *******/
5551
5552 /*
5553 * Write the text segment data
5554 */
5555 if (text_siz > 0)
5556 vms_fixup_text_section (text_siz, text_frag_root, data_frag_root);
5557 /*
5558 * Write the data segment data, then discard it.
5559 */
5560 if (data_siz > 0)
5561 {
5562 vms_fixup_data_section (data_siz, text_siz);
5563 free (Data_Segment), Data_Segment = 0;
5564 }
5565
5566 if (Ctors_Symbols != 0)
5567 {
5568 vms_fixup_xtors_section (Ctors_Symbols, Ctors_Psect);
5569 }
5570
5571 if (Dtors_Symbols != 0)
5572 {
5573 vms_fixup_xtors_section (Dtors_Symbols, Dtors_Psect);
5574 }
5575
5576 /******* Debugger Symbol Table Records *******/
5577
5578 vms_build_DST (text_siz);
5579
5580 /******* Wrap things up *******/
5581
5582 /*
5583 * Write the End Of Module record
5584 */
5585 if (Entry_Point_Symbol)
5586 Write_VMS_EOM_Record (Text_Psect, S_GET_VALUE (Entry_Point_Symbol));
5587 else
5588 Write_VMS_EOM_Record (-1, (valueT) 0);
5589
5590 /*
5591 * All done, close the object file
5592 */
5593 Close_VMS_Object_File ();
5594}
Note: See TracBrowser for help on using the repository browser.