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