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