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