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