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