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