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