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