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