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