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