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