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