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