Oh GACK! src-clean doesn't quite work that easily since cleandist rebuilds the
[unix-history] / gnu / usr.bin / gcc1 / cc1 / symout.c
CommitLineData
15637ed4
RG
1/* Output GDB-format symbol table information from GNU compiler.
2 Copyright (C) 1987, 1988 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "tree.h"
23#include "symseg.h"
24#include "rtl.h"
25#include "gdbfiles.h"
26#include <stdio.h>
27#undef NULL
28/* <...> used here so one can prevent use of ./stddef.h
29 by changing the -I options used. */
30#include <stddef.h>
31
32/* Get N_SO from stab.h if we can expect the file to exist. */
33#ifdef DBX_DEBUGGING_INFO
34#ifdef USG
35#include "stab.h" /* If doing DBX on sysV, use our own stab.h. */
36#else
37#include <stab.h> /* On BSD, use the system's stab.h. */
38#endif /* not USG */
39#endif
40
41/* .stabs code for source file name. */
42#ifndef N_SO
43#define N_SO 0x64
44#endif
45
46/* Unix maximum on file name length. Needed for getwd. */
47#define MAXNAMLEN 1024
48
49/* Get the number to output for a reference to type TYPE. */
50#define TYPE_OUTPUT_ADDRESS(TYPE) \
51 TYPE_SYMTAB_ADDRESS (TYPE_MAIN_VARIANT (TYPE))
52
53/* Stream for writing symbol table file. */
54static FILE *symfile;
55
56/* Name of symbol table file. */
57static char *symfile_name;
58
59/* Stream for writing to assembler file. */
60static FILE *asmfile;
61
62/* Address for allocating space in symbol table file.
63 Changes in this variable are paired globally with writes to symfile,
64 but often we allocate many structures, advancing next_address,
65 before writing any of them. */
66static int next_address;
67
68/* Chain recording all the types that have been output,
69 giving the address-in-the-symseg of each one. */
70
71struct typevec_elt
72{
73 int address;
74 struct typevec_elt *next;
75};
76
77static struct typevec_elt *typevec;
78
79/* Number of types recorded so far in the chain. */
80
81static int total_types;
82
83/* Lists of types to which forward references have been made.
84 Separate lists for temporary and permanent types. */
85
86static tree temporary_fwd_refs;
87static tree permanent_fwd_refs;
88
89/* `blockvec' is a chain recording all the symbol-blocks that have been output,
90 giving the address-in-the-symseg of each one. */
91
92struct blockvec_elt
93{
94 int address;
95 struct blockvec_elt *next;
96};
97
98static struct blockvec_elt *blockvec;
99
100/* Number of blocks recorded so far in the chain. */
101
102static int total_blocks;
103
104static void symout_range_bounds ();
105static void symout_array_domain ();
106static void symout_record_fields ();
107static void symout_enum_values ();
108static void symout_record_field_names ();
109static void symout_enum_value_names ();
110static int subrange_p ();
111static void symout_strings_skip ();
112static void symout_strings_print ();
113\f
114/* At the beginning of compilation, start writing the symbol table.
115 Initialize the type and block chain.
116 Also open and initialize the symseg file. */
117
118void
119symout_init (filename, asm_file, sourcename)
120 char *filename;
121 FILE *asm_file;
122 char *sourcename;
123{
124 struct symbol_root buffer;
125
126#ifdef VMS
127 fatal ("Cannot write GDB debugging format on VMS");
128#endif
129
130 asmfile = asm_file;
131 fprintf (asmfile, ".text 0\n.gdbbeg 0\n.gdbbeg 1\n");
132 fprintf (asmfile,
133 "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n",
134 sourcename, N_SO);
135 fprintf (asmfile, ".data 0\nLdata:\n");
136 ASM_OUTPUT_LOCAL (asmfile, "Lbss", 0, 0);
137 fprintf (asmfile, ".gdbsym Ldata,%d\n",
138 (char *) &buffer.databeg - (char *) &buffer);
139 fprintf (asmfile, ".gdbsym Lbss,%d\n",
140 (char *) &buffer.bssbeg - (char *) &buffer);
141
142 symfile = fopen (filename, "w");
143 if (symfile == 0)
144 pfatal_with_name (filename);
145 symfile_name = (char *) malloc (strlen (filename) + 1);
146 strcpy (symfile_name, filename);
147
148 typevec = 0;
149 blockvec = 0;
150 total_types = 0;
151 total_blocks = 0;
152
153 permanent_fwd_refs = 0;
154 temporary_fwd_refs = 0;
155
156 bzero (&buffer, sizeof buffer);
157 fwrite (&buffer, sizeof buffer, 1, symfile);
158
159 next_address = sizeof buffer;
160}
161\f
162/* Functions for outputting strings into the symbol table.
163 The string to be output is effectively the concatenation of
164 the two strings P1 and P2. Their lengths are given as S1 and S2.
165 If P1 or P2 is zero, that string is not used.
166
167 A null character is output to terminate the string,
168 and it is followed by more nulls as padding to a word boundary. */
169
170static void
171symout_strings (p1, s1, p2, s2)
172 char *p1;
173 int s1;
174 char *p2;
175 int s2;
176{
177 symout_strings_print (p1, s1, p2, s2);
178 symout_strings_skip (p1, s1, p2, s2);
179}
180
181/* Like symout_strings but only output; do not update next_address. */
182
183static void
184symout_strings_print (p1, s1, p2, s2)
185 char *p1;
186 int s1;
187 char *p2;
188 int s2;
189{
190 register int total;
191
192 if (p1 && s1 == 0)
193 s1 = strlen (p1);
194 if (p2 && s2 == 0)
195 s2 = strlen (p2);
196
197 if (p1)
198 fwrite (p1, s1, 1, symfile);
199 if (p2)
200 fwrite (p2, s2, 1, symfile);
201 putc (0, symfile);
202
203 total = s1 + s2 + 1;
204 while (total % sizeof (int))
205 {
206 putc (0, symfile);
207 total++;
208 }
209}
210
211/* Like symout_strings but just update next_address; do not output. */
212
213static void
214symout_strings_skip (p1, s1, p2, s2)
215 char *p1;
216 int s1;
217 char *p2;
218 int s2;
219{
220 register int total;
221
222 if (p1 && s1 == 0)
223 s1 = strlen (p1);
224 if (p2 && s2 == 0)
225 s2 = strlen (p2);
226
227 total = s1 + s2 + 1;
228 while (total % sizeof (int))
229 total++;
230
231 next_address += total;
232}
233\f
234/* Call here to output a chain of types.
235 After each function, this is done first for the chain of permanent types
236 made during the function, and then for the chain of temporary types.
237 This must be done before outputting the symbols and blocks of the function.
238
239 At the end of compilation, this is done for all the permanent types
240 made since the last function.
241
242 Each permanent type is done once, at the beginning of the next function,
243 or at the end of the compilation if no functions follow.
244 Once a type has been processed here, its TYPE_SYMTAB_ADDRESS remains
245 set up. */
246
247void
248symout_types (types)
249 tree types;
250{
251 struct typerec
252 {
253 int number;
254 int address;
255 int nfields;
256 int fields_address;
257 int name_address;
258 char *name;
259 char *name_prefix;
260 };
261
262 register int n_types, i;
263 register struct typerec *records;
264 register tree next;
265 struct type buffer;
266 int this_run_address = next_address;
267
268 /* Count the number of types to be handled here. */
269
270 for (next = types, n_types = 0;
271 next;
272 next = TREE_CHAIN (next), n_types++);
273
274 records = (struct typerec *) alloca (n_types * sizeof (struct typerec));
275
276 /* Compute the amount of space each type needs, updating next_address
277 and storing the address of the data for each type. */
278
279 for (next = types, i = 0;
280 next;
281 next = TREE_CHAIN (next), i++)
282 {
283 register struct typevec_elt *velt
284 = (struct typevec_elt *) xmalloc (sizeof (struct typevec_elt));
285 velt->next = typevec;
286 typevec = velt;
287
288 total_types++;
289
290 if (TYPE_NAME (next))
291 {
292 records[i].name_address = next_address;
293
294 if (TREE_CODE (TYPE_NAME (next)) == IDENTIFIER_NODE)
295 {
296 records[i].name = IDENTIFIER_POINTER (TYPE_NAME (next));
297 switch (TREE_CODE (next))
298 {
299 case RECORD_TYPE:
300 records[i].name_prefix = "struct ";
301 break;
302
303 case UNION_TYPE:
304 records[i].name_prefix = "union ";
305 break;
306
307 case ENUMERAL_TYPE:
308 records[i].name_prefix = "enum ";
309 break;
310 }
311 }
312 else
313 {
314 records[i].name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (next)));
315 records[i].name_prefix = 0;
316 }
317 symout_strings_skip (records[i].name_prefix, 0,
318 records[i].name, 0);
319
320 }
321 else
322 {
323 records[i].name = 0;
324 records[i].name_address = 0;
325 records[i].name_prefix = 0;
326 }
327
328 /* If this type was forward-referenced from a previous call
329 to symout_types, store this type's address into the reference. */
330 if (TYPE_POINTER_TO (next) != 0
331 && TYPE_SYMTAB_ADDRESS (TYPE_POINTER_TO (next)) != 0
332 && TYPE_SYMTAB_ADDRESS (TYPE_POINTER_TO (next)) < this_run_address)
333 {
334 int pos = ftell (symfile);
335 int myaddr = next_address;
336 fflush (symfile);
337 fseek (symfile,
338 (TYPE_SYMTAB_ADDRESS (TYPE_POINTER_TO (next))
339 + offsetof (struct type, target_type)),
340 0);
341 fwrite (&myaddr, sizeof (int), 1, symfile);
342 fflush (symfile);
343 fseek (symfile, pos, 0);
344 }
345
346 records[i].address = next_address;
347 TYPE_SYMTAB_ADDRESS (next) = next_address;
348 velt->address = next_address;
349 next_address += sizeof (struct type);
350 records[i].nfields = 0;
351 records[i].fields_address = 0;
352 switch (TREE_CODE (next))
353 {
354 case ARRAY_TYPE:
355 records[i].nfields
356 = (TYPE_DOMAIN(next)
357 ? ! integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (next)))
358 : 0 );
359 break;
360
361 case INTEGER_TYPE:
362 if (subrange_p (next))
363 buffer.nfields = 2;
364 break;
365
366 case RECORD_TYPE:
367 case UNION_TYPE:
368 case ENUMERAL_TYPE:
369 records[i].nfields = list_length (TYPE_FIELDS (next));
370 }
371 if (records[i].nfields)
372 records[i].fields_address = next_address;
373 next_address += records[i].nfields * sizeof (struct field);
374 }
375
376 /* Now write the data whose space we have assigned.
377 First fill the data into BUFFER, then write BUFFER. */
378
379 for (next = types, i = 0;
380 next;
381 next = TREE_CHAIN (next), i++)
382 {
383 if (records[i].name)
384 symout_strings_print (records[i].name_prefix, 0,
385 records[i].name, 0);
386
387 if (TREE_TYPE (next) != 0 && TYPE_OUTPUT_ADDRESS (TREE_TYPE (next)) == 0)
388 {
389 /* We are making a forward-reference to our target type.
390 Make a list of all of these. */
391 if (TREE_PERMANENT (next))
392 permanent_fwd_refs
393 = perm_tree_cons (TREE_TYPE (next), 0, permanent_fwd_refs);
394 else
395 temporary_fwd_refs
396 = tree_cons (TREE_TYPE (next), 0, temporary_fwd_refs);
397 }
398
399 if (TYPE_SIZE (next) == 0)
400 buffer.length = 0;
401 else
402 buffer.length
403 = (TREE_INT_CST_LOW (TYPE_SIZE (next))
404 * TYPE_SIZE_UNIT (next) / BITS_PER_UNIT);
405
406 buffer.name = (char *) records[i].name_address;
407 buffer.target_type = (struct type *) (TREE_TYPE (next) ? TYPE_OUTPUT_ADDRESS (TREE_TYPE (next)) : 0);
408
409 buffer.pointer_type = 0;
410 buffer.function_type = 0;
411 buffer.flags
412 = ((TREE_CODE (next) == INTEGER_TYPE || TREE_CODE (next) == ENUMERAL_TYPE)
413 && TREE_UNSIGNED (next))
414 ? TYPE_FLAG_UNSIGNED : 0;
415 buffer.nfields = records[i].nfields;
416 buffer.fields = (struct field *) records[i].fields_address;
417
418 switch (TREE_CODE (next))
419 {
420 case INTEGER_TYPE:
421 buffer.code = TYPE_CODE_INT;
422 if (buffer.nfields)
423 buffer.code = TYPE_CODE_RANGE;
424 break;
425
426 case REAL_TYPE:
427 buffer.code = TYPE_CODE_FLT;
428 break;
429
430 case VOID_TYPE:
431 buffer.code = TYPE_CODE_VOID;
432 break;
433
434 case POINTER_TYPE:
435 buffer.code = TYPE_CODE_PTR;
436 break;
437
438 case ARRAY_TYPE:
439 if (buffer.nfields == 0)
440 buffer.code = TYPE_CODE_ARRAY;
441 else
442 buffer.code = TYPE_CODE_PASCAL_ARRAY;
443 break;
444
445 case RECORD_TYPE:
446 buffer.code = TYPE_CODE_STRUCT;
447 break;
448
449 case UNION_TYPE:
450 buffer.code = TYPE_CODE_UNION;
451 break;
452
453 case FUNCTION_TYPE:
454 buffer.code = TYPE_CODE_FUNC;
455 break;
456
457 case ENUMERAL_TYPE:
458 buffer.code = TYPE_CODE_ENUM;
459 break;
460
461 default:
462 abort ();
463 }
464
465 fwrite (&buffer, sizeof buffer, 1, symfile);
466
467 /* Now write the `struct field's that certain kinds of type have.
468 This allocates space for the names of those fields,
469 incrementing next_address for the names. */
470
471 switch (TREE_CODE (next))
472 {
473 case ARRAY_TYPE:
474 if (buffer.nfields)
475 symout_array_domain (next);
476 break;
477
478 case RECORD_TYPE:
479 case UNION_TYPE:
480 symout_record_fields (next);
481 break;
482
483 case ENUMERAL_TYPE:
484 symout_enum_values (next);
485 break;
486
487 case INTEGER_TYPE:
488 if (buffer.nfields)
489 symout_range_bounds (next);
490 }
491 }
492
493 /* Now output the strings referred to by the fields of certain types.
494 (next_address was already updated for these strings.) */
495
496 for (next = types, i = 0;
497 next;
498 next = TREE_CHAIN (next), i++)
499 {
500 switch (TREE_CODE (next))
501 {
502 case RECORD_TYPE:
503 case UNION_TYPE:
504 symout_record_field_names (next);
505 break;
506
507 case ENUMERAL_TYPE:
508 symout_enum_value_names (next);
509 break;
510 }
511 }
512}
513
514/* Given a list of types TYPES, return a chain of just those
515 that haven't been written in the symbol table. */
516
517static tree
518filter_undefined_types (types)
519 tree types;
520{
521 tree new = 0;
522 tree next;
523
524 for (next = types; next; next = TREE_CHAIN (next))
525 if (TYPE_SYMTAB_ADDRESS (TREE_PURPOSE (next)) == 0)
526 {
527 TREE_CHAIN (TREE_PURPOSE (next)) = new;
528 new = TREE_PURPOSE (next);
529 }
530
531 return new;
532}
533\f
534/* Return nonzero if TYPE's range of possible values
535 is not the full range allowed by the number of bits it has.
536 TYPE is assumed to be an INTEGER_TYPE or ENUMERAL_TYPE. */
537
538static int
539subrange_p (type)
540 tree type;
541{
542 int uns = TREE_UNSIGNED (type);
543
544 if (TYPE_PRECISION (type) >= HOST_BITS_PER_INT)
545 {
546 if (uns)
547 return integer_zerop (TYPE_MIN_VALUE (type))
548 && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
549 && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
550 == (1 << (TYPE_PRECISION (type) - HOST_BITS_PER_INT)) - 1);
551 return TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
552 && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
553 && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type))
554 == (-1) << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT))
555 && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
556 == (1 << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT)) - 1);
557 }
558
559 if (uns)
560 {
561 int mask;
562
563 if (TYPE_PRECISION (type) == HOST_BITS_PER_INT)
564 /* Shifting by 32 loses on some machines. */
565 mask = -1;
566 else
567 mask = (1 << TYPE_PRECISION (type)) - 1;
568
569 return (integer_zerop (TYPE_MIN_VALUE (type))
570 && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == mask));
571 }
572 else
573 return ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))
574 == (-1) << (TYPE_PRECISION (type) - 1))
575 && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
576 == (1 << (TYPE_PRECISION (type) - 1)) - 1));
577}
578
579/* Functions to output the "fields" of various kinds of types.
580 These assume that next_address has already been incremented to
581 cover these fields, and the fields of all the other types being
582 output in this batch; so next_address can be used to allocate
583 space to store field names, etc. */
584
585static void
586symout_array_domain (type)
587 tree type;
588{
589 struct field buffer;
590
591 buffer.bitpos = 0;
592 buffer.bitsize = 0;
593 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TYPE_DOMAIN (type));
594 buffer.name = 0;
595 fwrite (&buffer, sizeof (struct field), 1, symfile);
596}
597
598static void
599symout_range_bounds (type)
600 tree type;
601{
602 struct field buffer;
603
604 buffer.bitpos = TREE_INT_CST_LOW (TYPE_MIN_VALUE (type));
605 buffer.bitsize = 0;
606 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
607 buffer.name = 0;
608 fwrite (&buffer, sizeof (struct field), 1, symfile);
609
610 buffer.bitpos = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type));
611 buffer.bitsize = 0;
612 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
613 buffer.name = 0;
614 fwrite (&buffer, sizeof (struct field), 1, symfile);
615}
616
617static void
618symout_record_fields (type)
619 tree type;
620{
621 struct field buffer;
622 register tree field;
623
624 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
625 {
626 buffer.bitpos = DECL_OFFSET (field);
627 buffer.bitsize
628 = (TREE_PACKED (field)
629 ? TREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field)
630 : 0);
631 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (field));
632 if (DECL_NAME (field))
633 {
634 buffer.name = (char *) next_address;
635 symout_strings_skip (0, IDENTIFIER_LENGTH (DECL_NAME (field)), 0, 0);
636 }
637 else
638 buffer.name = 0;
639 fwrite (&buffer, sizeof (struct field), 1, symfile);
640 }
641}
642
643static void
644symout_enum_values (type)
645 tree type;
646{
647 struct field buffer;
648 register tree link, value;
649
650 for (link = TYPE_VALUES (type); link; link = TREE_CHAIN (link))
651 {
652 value = TREE_VALUE (link);
653 buffer.bitpos = TREE_INT_CST_LOW (value);
654 buffer.bitsize = 0;
655 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
656 buffer.name = (char *) next_address;
657 symout_strings_skip (0, IDENTIFIER_LENGTH (TREE_PURPOSE (link)), 0, 0);
658 fwrite (&buffer, sizeof buffer, 1, symfile);
659 }
660}
661
662/* Output field names or value names for the fields of a type.
663 This is called, for the types that need it, after the fields
664 have been output for all the types in the batch.
665 We do not update next_address here, because it has already been
666 updated for all the names in all the fields in all the types. */
667
668static void
669symout_record_field_names (type)
670 tree type;
671{
672 register tree field;
673
674 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
675 if (DECL_NAME (field))
676 symout_strings_print (IDENTIFIER_POINTER (DECL_NAME (field)),
677 IDENTIFIER_LENGTH (DECL_NAME (field)),
678 0, 0);
679}
680
681static void
682symout_enum_value_names (type)
683 tree type;
684{
685 register tree value;
686
687 for (value = TYPE_VALUES (type); value; value = TREE_CHAIN (value))
688 symout_strings_print (IDENTIFIER_POINTER (TREE_PURPOSE (value)),
689 IDENTIFIER_LENGTH (TREE_PURPOSE (value)),
690 0, 0);
691}
692\f
693/* Output the symbols of a block, given the list of decl nodes.
694 Store the file addresses at which the symbols are output
695 into ADDR_BUFFER, a vector which has just the right length.
696
697 If FILTER is 1, do only the private symbols in DECLS.
698 If FILTER is 2, do only the public ones (but no externals).
699 If FILTER is 0, do all (except external functions). */
700
701static void
702symout_block_symbols (decls, addr_buffer, filter)
703 tree decls;
704 int *addr_buffer;
705 int filter;
706{
707 register tree decl;
708 struct symbol buffer;
709 register int i;
710
711 for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
712 {
713 register int name_address = next_address;
714
715 if (filter == (TREE_PUBLIC (decl) ? 1 : 2))
716 continue;
717
718 /* Do not mention external functions.
719 Let their own files mention them.
720 In the top blocks, don't mention external anything. */
721
722 if (TREE_EXTERNAL (decl)
723 && (filter || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE))
724 continue;
725
726 if (TREE_TYPE (decl) == error_mark_node)
727 continue;
728
729 symout_strings (IDENTIFIER_POINTER (DECL_NAME (decl)),
730 IDENTIFIER_LENGTH (DECL_NAME (decl)),
731 0, 0);
732 addr_buffer[i] = next_address;
733 buffer.name = (char *) name_address;
734 buffer.namespace = VAR_NAMESPACE;
735 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (decl));
736 switch (TREE_CODE (decl))
737 {
738 case PARM_DECL:
739 buffer.class = LOC_ARG;
740 buffer.value.value = DECL_OFFSET (decl) / BITS_PER_UNIT;
741 break;
742
743 case VAR_DECL:
744 case RESULT_DECL:
745 if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
746 {
747 if (! TREE_PUBLIC (decl) || DECL_INITIAL (decl))
748 {
749 char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
750 fprintf (asmfile, "\t.gdbsym ");
751 ASM_OUTPUT_LABELREF (asmfile, str);
752 fprintf (asmfile, ",%d\n",
753 next_address + (char *)&buffer.value - (char *)&buffer);
754 buffer.class = LOC_STATIC;
755 }
756 else
757 /* Uninitialized public symbols are output as .comm;
758 Tell GDB to get address from loader global symbol.
759 Also come here for symbols declared extern. */
760 buffer.class = LOC_EXTERNAL;
761 }
762 else
763 {
764 if (GET_CODE (DECL_RTL (decl)) == REG)
765 {
766 buffer.class = LOC_REGISTER;
767 buffer.value.value = REGNO (DECL_RTL (decl));
768 /* Detect vars that were optimized entirely away. */
769 if (buffer.value.value == -1)
770 buffer.class = LOC_CONST;
771 }
772 else if (GET_CODE (DECL_RTL (decl)) == MEM
773 && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
774 || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG
775 && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))
776 /* If the value is indirect by memory or by a register
777 that isn't the frame pointer
778 then it means the object is variable-sized and address through
779 that register or stack slot.
780 If we have a pointer-type (which we should, for an array),
781 output the variable as a pointer.
782 Otherwise ignore it, since it is hard to create the ptr
783 type now and output it, and -gg is being retired. */
784 {
785 tree ptype = TYPE_POINTER_TO (TREE_TYPE (TREE_TYPE (decl)));
786 if (ptype == 0
787 || TYPE_OUTPUT_ADDRESS (ptype) == 0)
788 continue;
789
790 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (ptype);
791
792
793 if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
794 {
795 buffer.class = LOC_REGISTER;
796 buffer.value.value = REGNO (DECL_RTL (decl));
797 /* Detect vars that were optimized entirely away. */
798 if (buffer.value.value == -1)
799 buffer.class = LOC_CONST;
800 }
801 else
802 {
803 register rtx addr = XEXP (DECL_RTL (decl), 0);
804 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)
805 abort ();
806 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
807 abort ();
808 buffer.class = LOC_LOCAL;
809 buffer.value.value = INTVAL (XEXP (addr, 1));
810 if (GET_CODE (addr) == MINUS)
811 buffer.value.value = - buffer.value.value;
812 }
813 }
814 /* Locals in memory are expected to be addressed as
815 (PLUS (REG ...) (CONST_INT ...)).
816 Bomb out if that is not so. */
817 else if (GET_CODE (DECL_RTL (decl)) == MEM)
818 {
819 register rtx addr = XEXP (DECL_RTL (decl), 0);
820 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)
821 abort ();
822 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
823 abort ();
824 buffer.class = LOC_LOCAL;
825 buffer.value.value = INTVAL (XEXP (addr, 1));
826 if (GET_CODE (addr) == MINUS)
827 buffer.value.value = - buffer.value.value;
828 }
829 else
830 abort ();
831 }
832 break;
833
834 case TYPE_DECL:
835 buffer.class = LOC_TYPEDEF;
836 buffer.value.value = 0;
837 break;
838
839 case CONST_DECL:
840 buffer.class = LOC_CONST;
841 buffer.value.value = TREE_INT_CST_LOW (DECL_INITIAL (decl));
842 break;
843
844 case FUNCTION_DECL:
845 if (DECL_INITIAL (decl))
846 {
847 buffer.class = LOC_BLOCK;
848 buffer.value.value = DECL_BLOCK_SYMTAB_ADDRESS (decl);
849 }
850 else
851 buffer.class = LOC_EXTERNAL;
852 }
853
854 fwrite (&buffer, sizeof buffer, 1, symfile);
855 next_address += sizeof buffer;
856 i++;
857 }
858}
859
860/* Output the tags (struct, union and enum definitions) for a block,
861 given a list of them (a chain of TREE_LIST nodes) in TAGS.
862 Store their addresses in the file into ADDR_BUFFER. */
863
864static void
865symout_block_tags (tags, addr_buffer)
866 tree tags;
867 int *addr_buffer;
868{
869 register tree tag;
870 struct symbol buffer;
871 register int i;
872
873 for (tag = tags, i = 0; tag; tag = TREE_CHAIN (tag), i++)
874 {
875 buffer.name = (char *) next_address;
876
877 symout_strings (IDENTIFIER_POINTER (TREE_PURPOSE (tag)),
878 IDENTIFIER_LENGTH (TREE_PURPOSE (tag)),
879 0, 0);
880 addr_buffer[i] = next_address;
881 buffer.namespace = STRUCT_NAMESPACE;
882 buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_VALUE (tag));
883 buffer.class = LOC_TYPEDEF;
884 buffer.value.value = 0;
885
886 fwrite (&buffer, sizeof buffer, 1, symfile);
887 next_address += sizeof buffer;
888 }
889}
890
891/* Output all the data structure for a "block"
892 (any binding contour).
893 DECLS is the chain of declarations of variables in this block.
894 TAGS is the list of struct, union and enum tag definitions of this block.
895 SUPERBLOCK_ADDRESS is the symtab file address of the containing block's
896 data structure. */
897
898int
899symout_block (decls, tags, args, superblock_address)
900 tree decls;
901 tree tags;
902 tree args;
903 int superblock_address;
904{
905 register tree decl;
906 register int i;
907 register int *addr_buffer;
908 struct block buffer;
909 int n_decls, n_tags, n_args, total;
910 register struct blockvec_elt *velt;
911 int block_address;
912
913 for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
914 if (! TREE_EXTERNAL (decl)
915 || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE)
916 i++;
917
918 n_decls = i;
919
920 for (decl = args, i = 0; decl; decl = TREE_CHAIN (decl), i++);
921 n_args = i;
922
923 for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
924 n_tags = i;
925
926 total = n_decls + n_args + n_tags;
927
928 addr_buffer = (int *) alloca (total * sizeof (int));
929
930 symout_block_symbols (args, addr_buffer, 0);
931 symout_block_symbols (decls, addr_buffer + n_args, 0);
932 symout_block_tags (tags, addr_buffer + n_decls + n_args);
933
934 velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
935 velt->next = blockvec;
936 velt->address = next_address;
937 blockvec = velt;
938
939 buffer.startaddr = 0;
940 buffer.endaddr = 0;
941 buffer.superblock = (struct block *) superblock_address;
942 buffer.function = 0;
943 buffer.nsyms = total;
944
945 block_address = next_address;
946 fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
947 next_address += sizeof buffer - sizeof buffer.sym;
948
949 fwrite (addr_buffer, sizeof (int), total, symfile);
950 next_address += total * sizeof (int);
951
952 fprintf (asmfile, "\t.gdbblock %d,%d\n", total_blocks + 2, block_address);
953 total_blocks++;
954
955 return block_address;
956}
957
958/* Walk STMT, the body of a function, and output symtab data on
959 all the blocks that compose it and all symbols inside them.
960 ARGS is a chain of decls for argument variables of the function.
961 SUPERBLOCK_ADDRESS is the address of symbol data for the
962 innermost block containing STMT; it is used for recursive calls,
963 and is always 0 for the outermost call (since the containing
964 block for a function is output later than the function). */
965
966int
967symout_function (stmt, args, superblock_address)
968 register tree stmt;
969 tree args;
970 int superblock_address;
971{
972 int address = superblock_address;
973
974 while (stmt)
975 {
976 switch (TREE_CODE (stmt))
977 {
978 case COMPOUND_STMT:
979 case LOOP_STMT:
980 symout_function (STMT_BODY (stmt), 0, address);
981 break;
982
983 case IF_STMT:
984 symout_function (STMT_THEN (stmt), 0, address);
985 symout_function (STMT_ELSE (stmt), 0, address);
986 break;
987
988 case LET_STMT:
989 /* Ignore LET_STMTs for blocks never really used to make RTL. */
990 if (! TREE_USED (stmt))
991 break;
992 address =
993 symout_block (STMT_VARS (stmt), STMT_TYPE_TAGS (stmt), args,
994 superblock_address);
995
996 symout_function (STMT_SUBBLOCKS (stmt), 0, address);
997 }
998 stmt = TREE_CHAIN (stmt);
999 }
1000 return address;
1001}
1002
1003symout_function_end ()
1004{
1005 /* Output dummy entries for any undefined structure references. */
1006 symout_types (filter_undefined_types (temporary_fwd_refs));
1007 temporary_fwd_refs = 0;
1008}
1009\f
1010/* Output all the data structure for a top two blocks in a compilation.
1011 The top block is for public (global) symbols;
1012 the next one is for private (this file only) symbols.
1013
1014 DECLS is the chain of declarations of variables in this block.
1015 TAGS is the list of struct, union and enum tag definitions. */
1016
1017void
1018symout_top_blocks (decls, tags)
1019 tree decls;
1020 tree tags;
1021{
1022 register tree decl;
1023 register int i;
1024 register int *addr_buffer;
1025 struct block buffer;
1026 int n_decls, n_tags;
1027 register struct blockvec_elt *velt;
1028 int top_block_addr;
1029
1030 /* First do the public-symbols block. */
1031
1032 for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
1033 if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
1034 i++;
1035 n_decls = i;
1036
1037 addr_buffer = (int *) alloca (n_decls * sizeof (int));
1038
1039 symout_block_symbols (decls, addr_buffer, 2);
1040
1041 fprintf (asmfile, ".text 0\n\t.gdbend 0\n");
1042 fprintf (asmfile, "\t.gdbblock 0,%d\n", next_address);
1043
1044 total_blocks++;
1045 velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
1046 velt->next = blockvec;
1047 velt->address = next_address;
1048 blockvec = velt;
1049
1050 top_block_addr = next_address;
1051
1052 buffer.startaddr = 0;
1053 buffer.endaddr = 0;
1054 buffer.superblock = 0;
1055 buffer.function = 0;
1056 buffer.nsyms = n_decls;;
1057
1058 fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
1059 next_address += sizeof buffer - sizeof buffer.sym;
1060
1061 fwrite (addr_buffer, sizeof (int), n_decls, symfile);
1062 next_address += n_decls * sizeof (int);
1063
1064 /* Next do the private-symbols block. */
1065
1066 for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
1067 if (! TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
1068 i++;
1069 n_decls = i;
1070
1071 for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
1072 n_tags = i;
1073
1074 addr_buffer = (int *) alloca ((n_decls + n_tags) * sizeof (int));
1075
1076 symout_block_symbols (decls, addr_buffer, 1);
1077 symout_block_tags (tags, addr_buffer + n_decls);
1078
1079 fprintf (asmfile, "\t.gdbend 1\n");
1080 fprintf (asmfile, "\t.gdbblock 1,%d\n", next_address);
1081
1082 total_blocks++;
1083 velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
1084 velt->next = blockvec;
1085 velt->address = next_address;
1086 blockvec = velt;
1087
1088 buffer.startaddr = 0;
1089 buffer.endaddr = 0;
1090 buffer.superblock = (struct block *) top_block_addr;
1091 buffer.function = 0;
1092 buffer.nsyms = n_decls + n_tags;;
1093
1094 fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
1095 next_address += sizeof buffer - sizeof buffer.sym;
1096
1097 fwrite (addr_buffer, sizeof (int), n_decls + n_tags, symfile);
1098 next_address += (n_decls + n_tags) * sizeof (int);
1099}
1100\f
1101/* Output the source-line-number information. */
1102
1103/* Output a `struct source' for the source file described by F.
1104 Return the address-in-the-symseg of the `struct source'. */
1105
1106static int
1107symout_source_file (f)
1108 struct gdbfile *f;
1109{
1110 /* Make the `struct source' big enough for as many lines as
1111 this file has. */
1112 int size = sizeof (struct source) + (f->nlines - 1) * sizeof (struct line);
1113 struct source *buffer
1114 = (struct source *) alloca (size);
1115 int addr;
1116
1117 /* Use zero for the line data, since assembler will store the real data. */
1118 bzero (buffer, size);
1119
1120 /* Output the file's name as a string. The assembler doesn't know this. */
1121 buffer->name = (char *) next_address;
1122 symout_strings (f->name, 0, 0, 0);
1123 buffer->nlines = f->nlines;
1124
1125 /* Write the structure. */
1126 addr = next_address;
1127 fwrite (buffer, 1, size, symfile);
1128 next_address += size;
1129
1130 /* Tell assembler where to write the real line-number data. */
1131 fprintf (asmfile, "\t.gdblinetab %d,%d\n",
1132 f->filenum, addr + sizeof (int));
1133
1134 return addr;
1135}
1136
1137/* Output the `struct sourcevector' which describes all the
1138 source files and points a `struct source' for each one. */
1139
1140static int
1141symout_sources ()
1142{
1143 register struct gdbfile *f;
1144 int nfiles = 0;
1145 struct sourcevector *s;
1146 int i;
1147 int size;
1148 int addr;
1149
1150 /* Count number of files to determine size of the sourcevector. */
1151 for (f = gdbfiles; f; f = f->next)
1152 ++nfiles;
1153
1154 /* Allocate buffer for the sourcevector and record its length. */
1155 size = sizeof (int) + nfiles * sizeof (struct source *);
1156 s = (struct sourcevector *) alloca (size);
1157 s->length = nfiles;
1158
1159 /* Output a `struct source' for each file; put address into sourcevector. */
1160 for (f = gdbfiles, i = 0; f; f = f->next, i++)
1161 s->source[i] = (struct source *) symout_source_file (f);
1162
1163 /* Output the sourcevector. */
1164 addr = next_address;
1165 fwrite (s, 1, size, symfile);
1166 next_address += size;
1167 return addr;
1168}
1169\f
1170/* Call here at the end of compilation, after outputting all the
1171 blocks and symbols, to output the blockvector and typevector
1172 and close the symbol table file. FILETIME is source file's
1173 creation time. */
1174
1175void
1176symout_finish (filename, filetime)
1177 char *filename;
1178 int filetime;
1179{
1180 int *blockvector = (int *) alloca ((total_blocks + 1) * sizeof (int));
1181 int *typevector;
1182 int now = time (0);
1183 register int i;
1184 struct symbol_root buffer;
1185 char dir[MAXNAMLEN];
1186
1187 /* Output dummy entries for any undefined structure references. */
1188 symout_types (filter_undefined_types (permanent_fwd_refs));
1189
1190 typevector = (int *) alloca ((total_types + 1) * sizeof (int));
1191
1192 buffer.language = language_c;
1193 buffer.blockvector = (struct blockvector *) next_address;
1194
1195 /* The two blocks at the beginning of the chain
1196 are the file's private symbols block and public symbols block.
1197 They belong at the front of the blockvector, in that order. */
1198 blockvector[2] = blockvec->address;
1199 blockvec = blockvec->next;
1200 blockvector[1] = blockvec->address;
1201 blockvec = blockvec->next;
1202
1203 /* The rest of the blocks are in the chain in reverse order. */
1204 for (i = total_blocks; i > 2; i--)
1205 {
1206 blockvector[i] = blockvec->address;
1207 blockvec = blockvec->next;
1208 }
1209 blockvector[0] = total_blocks;
1210
1211 fwrite (blockvector, sizeof (int), total_blocks + 1, symfile);
1212 next_address += sizeof (int) * (total_blocks + 1);
1213
1214 buffer.typevector = (struct typevector *) next_address;
1215
1216 for (i = total_types; i > 0; i--)
1217 {
1218 typevector[i] = typevec->address;
1219 typevec = typevec->next;
1220 }
1221 typevector[0] = total_types;
1222
1223 fwrite (typevector, sizeof (int), total_types + 1, symfile);
1224 next_address += sizeof (int) * (total_types + 1);
1225
1226 buffer.sourcevector = (struct sourcevector *) symout_sources ();
1227
1228 buffer.format = 1;
1229 buffer.textrel = 0; /* These four will be set up by linker. */
1230 buffer.datarel = 0; /* Make them 0 now, which is right for */
1231 buffer.bssrel = 0; /* looking at the .o file in gdb. */
1232 buffer.ldsymoff = 0;
1233
1234 buffer.version = (char *) next_address;
1235 symout_strings (ctime (&filetime), 0, 0, 0);
1236
1237 buffer.compilation = (char *) next_address;
1238 symout_strings (ctime (&now), 0, 0, 0);
1239
1240 buffer.filename = (char *) next_address;
1241 symout_strings (filename, 0, 0, 0);
1242
1243 buffer.filedir = (char *) next_address;
1244#ifdef USG
1245 strcpy (dir, getcwd (dir, MAXNAMLEN));
1246#else
1247#ifndef VMS
1248 getwd (dir);
1249#else
1250 abort ();
1251#endif
1252#endif
1253 symout_strings (dir, 0, 0, 0);
1254
1255 fflush (symfile);
1256
1257 if (ferror (symfile) != 0)
1258 fatal_io_error (symfile_name);
1259
1260 buffer.length = next_address;
1261
1262 if (lseek (fileno (symfile), 0, 0) < 0)
1263 pfatal_with_name (symfile_name);
1264 if (write (fileno (symfile), &buffer, sizeof buffer) < 0)
1265 pfatal_with_name (symfile_name);
1266 close (fileno (symfile));
1267}