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