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