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