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