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