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