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