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