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