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