|
|
1.1 root 1: /* Output dbx-format symbol table information from GNU compiler.
1.1.1.6 root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc.
1.1 root 3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: /* Output dbx-format symbol table data.
23: This consists of many symbol table entries, each of them
24: a .stabs assembler pseudo-op with four operands:
25: a "name" which is really a description of one symbol and its type,
26: a "code", which is a symbol defined in stab.h whose name starts with N_,
27: an unused operand always 0,
28: and a "value" which is an address or an offset.
29: The name is enclosed in doublequote characters.
30:
31: Each function, variable, typedef, and structure tag
32: has a symbol table entry to define it.
33: The beginning and end of each level of name scoping within
34: a function are also marked by special symbol table entries.
35:
36: The "name" consists of the symbol name, a colon, a kind-of-symbol letter,
37: and a data type number. The data type number may be followed by
38: "=" and a type definition; normally this will happen the first time
39: the type number is mentioned. The type definition may refer to
40: other types by number, and those type numbers may be followed
41: by "=" and nested definitions.
42:
43: This can make the "name" quite long.
44: When a name is more than 80 characters, we split the .stabs pseudo-op
45: into two .stabs pseudo-ops, both sharing the same "code" and "value".
46: The first one is marked as continued with a double-backslash at the
47: end of its "name".
48:
49: The kind-of-symbol letter distinguished function names from global
50: variables from file-scope variables from parameters from auto
51: variables in memory from typedef names from register variables.
52: See `dbxout_symbol'.
53:
54: The "code" is mostly redundant with the kind-of-symbol letter
55: that goes in the "name", but not entirely: for symbols located
56: in static storage, the "code" says which segment the address is in,
57: which controls how it is relocated.
58:
59: The "value" for a symbol in static storage
60: is the core address of the symbol (actually, the assembler
61: label for the symbol). For a symbol located in a stack slot
62: it is the stack offset; for one in a register, the register number.
63: For a typedef symbol, it is zero.
64:
1.1.1.9 root 65: If DEBUG_SYMS_TEXT is defined, all debugging symbols must be
66: output while in the text section.
67:
1.1 root 68: For more on data type definitions, see `dbxout_type'. */
69:
70: #include "config.h"
71: #include "tree.h"
72: #include "rtl.h"
1.1.1.6 root 73: #include "flags.h"
1.1 root 74: #include <stdio.h>
1.1.1.2 root 75:
76: /* Typical USG systems don't have stab.h, and they also have
77: no use for DBX-format debugging info. */
78:
1.1.1.4 root 79: #ifdef DBX_DEBUGGING_INFO
1.1.1.2 root 80:
1.1.1.9 root 81: #ifdef DEBUG_SYMS_TEXT
82: #define FORCE_TEXT text_section ();
83: #else
84: #define FORCE_TEXT
85: #endif
86:
1.1.1.11! root 87: #ifdef USG
! 88: #include "stab.h" /* If doing DBX on sysV, use our own stab.h. */
! 89: #else
! 90: #include <stab.h> /* On BSD, use the system's stab.h. */
! 91: #endif /* not USG */
1.1.1.2 root 92:
1.1 root 93: /* Stream for writing to assembler file. */
94:
95: static FILE *asmfile;
96:
97: enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
98:
99: /* Vector recording the status of describing C data types.
100: When we first notice a data type (a tree node),
101: we assign it a number using next_type_number.
102: That is its index in this vector.
103: The vector element says whether we have yet output
104: the definition of the type. TYPE_XREF says we have
105: output it as a cross-reference only. */
106:
107: enum typestatus *typevec;
108:
109: /* Number of elements of space allocated in `typevec'. */
110:
111: static int typevec_len;
112:
113: /* In dbx output, each type gets a unique number.
114: This is the number for the next type output.
115: The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */
116:
117: static int next_type_number;
118:
119: /* In dbx output, we must assign symbol-blocks id numbers
120: in the order in which their beginnings are encountered.
121: We output debugging info that refers to the beginning and
122: end of the ranges of code in each block
123: with assembler labels LBBn and LBEn, where n is the block number.
124: The labels are generated in final, which assigns numbers to the
125: blocks in the same way. */
126:
127: static int next_block_number;
128:
129: /* These variables are for dbxout_symbol to communicate to
130: dbxout_finish_symbol.
131: current_sym_code is the symbol-type-code, a symbol N_... define in stab.h.
132: current_sym_value and current_sym_addr are two ways to address the
133: value to store in the symtab entry.
134: current_sym_addr if nonzero represents the value as an rtx.
135: If that is zero, current_sym_value is used. This is used
136: when the value is an offset (such as for auto variables,
137: register variables and parms). */
138:
139: static int current_sym_code;
140: static int current_sym_value;
141: static rtx current_sym_addr;
142:
143: /* Number of chars of symbol-description generated so far for the
144: current symbol. Used by CHARS and CONTIN. */
145:
146: static int current_sym_nchars;
147:
148: /* Report having output N chars of the current symbol-description. */
149:
150: #define CHARS(N) (current_sym_nchars += (N))
151:
152: /* Break the current symbol-description, generating a continuation,
153: if it has become long. */
154:
1.1.1.2 root 155: #ifndef DBX_CONTIN_LENGTH
156: #define DBX_CONTIN_LENGTH 80
157: #endif
158:
159: #if DBX_CONTIN_LENGTH > 0
1.1 root 160: #define CONTIN \
1.1.1.2 root 161: do {if (current_sym_nchars > DBX_CONTIN_LENGTH) dbxout_continue ();} while (0)
162: #else
163: #define CONTIN
164: #endif
1.1 root 165:
166: void dbxout_types ();
167: void dbxout_tags ();
1.1.1.6 root 168: void dbxout_args ();
1.1.1.7 root 169: void dbxout_symbol ();
1.1 root 170: static void dbxout_type_name ();
171: static void dbxout_type ();
172: static void dbxout_finish_symbol ();
173: static void dbxout_continue ();
174:
175: /* At the beginning of compilation, start writing the symbol table.
176: Initialize `typevec' and output the standard data types of C. */
177:
178: void
179: dbxout_init (asm_file, input_file_name)
180: FILE *asm_file;
181: char *input_file_name;
182: {
183: asmfile = asm_file;
184:
185: typevec_len = 100;
186: typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]);
187: bzero (typevec, typevec_len * sizeof typevec[0]);
1.1.1.6 root 188:
1.1.1.5 root 189: /* Used to put `Ltext:' before the reference, but that loses on sun 4. */
1.1 root 190: fprintf (asmfile,
1.1.1.5 root 191: "\t.stabs \"%s\",%d,0,0,Ltext\nLtext:\n",
1.1.1.2 root 192: input_file_name, N_SO);
1.1 root 193:
194: next_type_number = 1;
195: next_block_number = 2;
196:
197: /* Make sure that types `int' and `char' have numbers 1 and 2.
198: Definitions of other integer types will refer to those numbers. */
199:
1.1.1.10 root 200: dbxout_symbol (TYPE_NAME (integer_type_node), 0);
201: dbxout_symbol (TYPE_NAME (char_type_node), 0);
1.1 root 202:
1.1.1.2 root 203: /* Get all permanent types not yet gotten, and output them. */
1.1 root 204:
205: dbxout_types (get_permanent_types ());
206: }
207:
208: /* Continue a symbol-description that gets too big.
209: End one symbol table entry with a double-backslash
210: and start a new one, eventually producing something like
211: .stabs "start......\\",code,0,value
212: .stabs "...rest",code,0,value */
213:
214: static void
215: dbxout_continue ()
216: {
1.1.1.2 root 217: #ifdef DBX_CONTIN_CHAR
218: fprintf (asmfile, "%c", DBX_CONTIN_CHAR);
219: #else
1.1 root 220: fprintf (asmfile, "\\\\");
1.1.1.2 root 221: #endif
1.1 root 222: dbxout_finish_symbol ();
223: fprintf (asmfile, ".stabs \"");
224: current_sym_nchars = 0;
225: }
226:
227: /* Output a reference to a type. If the type has not yet been
228: described in the dbx output, output its definition now.
229: For a type already defined, just refer to its definition
230: using the type number.
231:
232: If FULL is nonzero, and the type has been described only with
233: a forward-reference, output the definition now.
234: If FULL is zero in this case, just refer to the forward-reference
235: using the number previously allocated. */
236:
237: static void
238: dbxout_type (type, full)
239: tree type;
240: int full;
241: {
242: register tree tem;
243:
1.1.1.2 root 244: /* If there was an input error and we don't really have a type,
245: avoid crashing and write something that is at least valid
246: by assuming `int'. */
247: if (type == error_mark_node)
248: type = integer_type_node;
249: else if (TYPE_SIZE (type) == 0)
250: type = TYPE_MAIN_VARIANT (type);
251:
1.1 root 252: if (TYPE_SYMTAB_ADDRESS (type) == 0)
253: {
254: /* Type has no dbx number assigned. Assign next available number. */
255: TYPE_SYMTAB_ADDRESS (type) = next_type_number++;
256:
257: /* Make sure type vector is long enough to record about this type. */
258:
259: if (next_type_number == typevec_len)
260: {
261: typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]);
262: bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]);
263: typevec_len *= 2;
264: }
265: }
266:
267: /* Output the number of this type, to refer to it. */
268: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
269: CHARS (3);
270:
271: /* If this type's definition has been output or is now being output,
272: that is all. */
273:
274: switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
275: {
276: case TYPE_UNSEEN:
277: break;
278: case TYPE_XREF:
279: if (! full)
280: return;
281: break;
282: case TYPE_DEFINED:
283: return;
284: }
285:
1.1.1.2 root 286: #ifdef DBX_NO_XREFS
287: /* For systems where dbx output does not allow the `=xsNAME:' syntax,
288: leave the type-number completely undefined rather than output
289: a cross-reference. */
290: if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
291: || TREE_CODE (type) == ENUMERAL_TYPE)
292:
293: if ((TYPE_NAME (type) != 0 && !full)
294: || TYPE_SIZE (type) == 0)
295: {
296: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
297: return;
298: }
299: #endif
300:
1.1 root 301: /* Output a definition now. */
302:
303: fprintf (asmfile, "=");
304: CHARS (1);
305:
306: /* Mark it as defined, so that if it is self-referent
307: we will not get into an infinite recursion of definitions. */
308:
309: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
310:
311: switch (TREE_CODE (type))
312: {
313: case VOID_TYPE:
314: /* For a void type, just define it as itself; ie, "5=5".
315: This makes us consider it defined
316: without saying what it is. The debugger will make it
317: a void type when the reference is seen, and nothing will
318: ever override that default. */
319: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
320: CHARS (3);
321: break;
322:
323: case INTEGER_TYPE:
1.1.1.2 root 324: if (type == char_type_node && ! TREE_UNSIGNED (type))
1.1 root 325: /* Output the type `char' as a subrange of itself!
326: I don't understand this definition, just copied it
327: from the output of pcc. */
328: fprintf (asmfile, "r2;0;127;");
329: else
330: /* Output other integer types as subranges of `int'. */
331: fprintf (asmfile, "r1;%d;%d;",
332: TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)),
333: TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
334: CHARS (25);
335: break;
336:
337: case REAL_TYPE:
338: /* This must be magic. */
339: fprintf (asmfile, "r1;%d;0;",
340: TREE_INT_CST_LOW (size_in_bytes (type)));
341: CHARS (16);
342: break;
343:
344: case ARRAY_TYPE:
345: /* Output "a" followed by a range type definition
346: for the index type of the array
347: followed by a reference to the target-type.
348: ar1;0;N;M for an array of type M and size N. */
349: fprintf (asmfile, "ar1;0;%d;",
1.1.1.2 root 350: (TYPE_DOMAIN (type)
351: ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
352: : -1));
1.1 root 353: CHARS (17);
354: dbxout_type (TREE_TYPE (type), 0);
355: break;
356:
357: case RECORD_TYPE:
358: case UNION_TYPE:
359: /* Output a structure type. */
360: if ((TYPE_NAME (type) != 0 && !full)
361: || TYPE_SIZE (type) == 0)
362: {
363: /* If the type is just a cross reference, output one
364: and mark the type as partially described.
365: If it later becomes defined, we will output
1.1.1.2 root 366: its real definition.
1.1.1.7 root 367: If the type has a name, don't nest its definition within
1.1.1.2 root 368: another type's definition; instead, output an xref
369: and let the definition come when the name is defined. */
1.1 root 370: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
371: CHARS (3);
1.1.1.10 root 372: #if 0 /* This assertion is legitimately false in C++. */
1.1.1.7 root 373: /* We shouldn't be outputting a reference to a type before its
374: definition unless the type has a tag name.
375: A typedef name without a tag name should be impossible. */
376: if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE)
377: abort ();
1.1.1.10 root 378: #endif
1.1 root 379: dbxout_type_name (type);
380: fprintf (asmfile, ":");
381: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
382: break;
383: }
384: tem = size_in_bytes (type);
385: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
386: TREE_INT_CST_LOW (tem));
1.1.1.6 root 387:
388: if (TYPE_BASETYPES (type) && use_gdb_dbx_extensions)
389: {
390: putc ('!', asmfile);
391: putc ((TREE_PUBLIC (TYPE_BASETYPES (type)) ? '2' : '0'),
392: asmfile);
393: dbxout_type (TREE_VALUE (TYPE_BASETYPES (type)), 0);
394: putc (',', asmfile);
395: CHARS (3);
396: }
1.1 root 397: CHARS (11);
1.1.1.6 root 398:
1.1 root 399: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
400: /* Output the name, type, position (in bits), size (in bits)
401: of each field. */
402: /* Omit here the nameless fields that are used to skip bits. */
403: if (DECL_NAME (tem) != 0)
404: {
1.1.1.2 root 405: /* Continue the line if necessary,
406: but not before the first field. */
407: if (tem != TYPE_FIELDS (type))
408: CONTIN;
1.1 root 409: fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
1.1.1.6 root 410: CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));
411: if (use_gdb_dbx_extensions)
412: {
413: putc ('/', asmfile);
414: #ifdef TREE_PRIVATE
415: putc ((TREE_PRIVATE (tem) ? '0'
416: : TREE_PROTECTED (tem) ? '1' : '2'),
417: asmfile);
418: #endif
419: CHARS (2);
420: if (TREE_CODE (tem) == FUNCTION_DECL)
421: {
422: putc (':', asmfile);
423: CHARS (1);
424: dbxout_type (TREE_TYPE (tem), 0); /* FUNCTION_TYPE */
425: dbxout_args (TYPE_ARG_TYPES (TREE_TYPE (tem)));
426: #ifdef TREE_VIRTUAL
427: fprintf (asmfile, ":%s;%c",
428: XSTR (XEXP (DECL_RTL (tem), 0), 0),
429: TREE_VIRTUAL (tem) ? '*' : '.');
430: #endif
431: CHARS (3 + strlen (XSTR (XEXP (DECL_RTL (tem), 0), 0)));
432: }
433: else
434: dbxout_type (TREE_TYPE (tem), 0);
435: }
436: else
437: dbxout_type (TREE_TYPE (tem), 0);
438:
439: if (TREE_CODE (tem) == VAR_DECL)
440: {
441: if (use_gdb_dbx_extensions)
442: {
443: fprintf (asmfile, ":%s",
444: XSTR (XEXP (DECL_RTL (tem), 0), 0));
445: CHARS (2 + strlen (XSTR (XEXP (DECL_RTL (tem), 0), 0)));
446: }
447: else
448: {
449: fprintf (asmfile, ",0,0;");
450: CHARS (5);
451: }
452: }
453: else
454: {
455: fprintf (asmfile, ",%d,%d;", DECL_OFFSET (tem),
456: (TREE_INT_CST_LOW (DECL_SIZE (tem))
457: * DECL_SIZE_UNIT (tem)));
458: CHARS (23);
459: }
1.1 root 460: }
1.1.1.6 root 461:
1.1 root 462: putc (';', asmfile);
463: CHARS (1);
464: break;
465:
466: case ENUMERAL_TYPE:
467: if ((TYPE_NAME (type) != 0 && !full)
468: || TYPE_SIZE (type) == 0)
469: {
470: fprintf (asmfile, "xe");
471: CHARS (3);
472: dbxout_type_name (type);
473: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
474: fprintf (asmfile, ":");
475: return;
476: }
477: putc ('e', asmfile);
478: CHARS (1);
479: for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
480: {
481: fprintf (asmfile, "%s:%d,", IDENTIFIER_POINTER (TREE_PURPOSE (tem)),
482: TREE_INT_CST_LOW (TREE_VALUE (tem)));
1.1.1.6 root 483: CHARS (11 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));
1.1 root 484: if (TREE_CHAIN (tem) != 0)
485: CONTIN;
486: }
487: putc (';', asmfile);
488: CHARS (1);
489: break;
490:
491: case POINTER_TYPE:
492: putc ('*', asmfile);
493: CHARS (1);
494: dbxout_type (TREE_TYPE (type), 0);
495: break;
496:
1.1.1.6 root 497: case METHOD_TYPE:
498: if (use_gdb_dbx_extensions)
499: {
500: putc ('@', asmfile);
501: CHARS (1);
1.1.1.10 root 502: dbxout_type (TYPE_METHOD_BASETYPE (type), 0);
503: putc (',', asmfile);
504: CHARS (1);
505: dbxout_type (TREE_TYPE (type), 0);
506: }
507: else
508: {
509: /* Treat it as a function type. */
510: dbxout_type (TREE_TYPE (type), 0);
511: }
512: break;
513:
514: case OFFSET_TYPE:
515: if (use_gdb_dbx_extensions)
516: {
517: putc ('@', asmfile);
518: CHARS (1);
519: dbxout_type (TYPE_OFFSET_BASETYPE (type), 0);
1.1.1.6 root 520: putc (',', asmfile);
521: CHARS (1);
522: dbxout_type (TREE_TYPE (type), 0);
523: }
524: else
525: {
526: /* Treat it as a function type. */
527: dbxout_type (TREE_TYPE (type), 0);
528: }
529: break;
530:
531: case REFERENCE_TYPE:
532: putc (use_gdb_dbx_extensions ? '&' : '*', asmfile);
533: CHARS (1);
534: dbxout_type (TREE_TYPE (type), 0);
535: break;
536:
1.1 root 537: case FUNCTION_TYPE:
538: putc ('f', asmfile);
539: CHARS (1);
540: dbxout_type (TREE_TYPE (type), 0);
541: break;
1.1.1.6 root 542:
543: default:
544: abort ();
1.1 root 545: }
546: }
547:
548: /* Output the name of type TYPE, with no punctuation.
549: Such names can be set up either by typedef declarations
550: or by struct, enum and union tags. */
551:
552: static void
553: dbxout_type_name (type)
554: register tree type;
555: {
1.1.1.6 root 556: tree t;
1.1 root 557: if (TYPE_NAME (type) == 0)
558: abort ();
559: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
1.1.1.6 root 560: {
561: t = TYPE_NAME (type);
562: }
1.1 root 563: else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
1.1.1.6 root 564: {
565: t = DECL_NAME (TYPE_NAME (type));
566: }
1.1 root 567: else
568: abort ();
569:
1.1.1.6 root 570: fprintf (asmfile, "%s", IDENTIFIER_POINTER (t));
571: CHARS (IDENTIFIER_LENGTH (t));
1.1 root 572: }
573:
574: /* Output a .stabs for the symbol defined by DECL,
575: which must be a ..._DECL node in the normal namespace.
576: It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
577: LOCAL is nonzero if the scope is less than the entire file. */
578:
579: void
580: dbxout_symbol (decl, local)
581: tree decl;
582: int local;
583: {
1.1.1.2 root 584: int letter = 0;
585: tree type = TREE_TYPE (decl);
1.1 root 586:
587: /* If global, first output all types and all
588: struct, enum and union tags that have been created
589: and not yet output. */
590:
591: if (local == 0)
592: {
593: dbxout_tags (gettags ());
594: dbxout_types (get_permanent_types ());
595: }
596:
597: current_sym_code = 0;
598: current_sym_value = 0;
599: current_sym_addr = 0;
600:
601: /* The output will always start with the symbol name,
602: so count that always in the length-output-so-far. */
603:
1.1.1.6 root 604: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl));
1.1 root 605:
606: switch (TREE_CODE (decl))
607: {
608: case CONST_DECL:
609: /* Enum values are defined by defining the enum type. */
610: break;
611:
612: case FUNCTION_DECL:
1.1.1.3 root 613: if (DECL_RTL (decl) == 0)
614: return;
1.1 root 615: if (TREE_EXTERNAL (decl))
616: break;
617: if (GET_CODE (DECL_RTL (decl)) != MEM
618: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
619: break;
1.1.1.9 root 620: FORCE_TEXT;
1.1 root 621: fprintf (asmfile, ".stabs \"%s:%c",
622: IDENTIFIER_POINTER (DECL_NAME (decl)),
623: TREE_PUBLIC (decl) ? 'F' : 'f');
624:
625: current_sym_code = N_FUN;
626: current_sym_addr = XEXP (DECL_RTL (decl), 0);
627:
628: if (TREE_TYPE (TREE_TYPE (decl)))
629: dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0);
630: else
631: dbxout_type (void_type_node, 0);
632: dbxout_finish_symbol ();
633: break;
634:
635: case TYPE_DECL:
1.1.1.7 root 636: #if 0
637: /* This seems all wrong. Outputting most kinds of types gives no name
638: at all. A true definition gives no name; a cross-ref for a
639: structure can give the tag name, but not a type name.
640: It seems that no typedef name is defined by outputting a type. */
641:
1.1.1.3 root 642: /* If this typedef name was defined by outputting the type,
643: don't duplicate it. */
644: if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED
645: && TYPE_NAME (TREE_TYPE (decl)) == decl)
646: return;
1.1.1.7 root 647: #endif
648: /* Don't output the same typedef twice. */
649: if (TREE_ASM_WRITTEN (decl))
650: return;
1.1.1.3 root 651:
1.1 root 652: /* Output typedef name. */
1.1.1.9 root 653: FORCE_TEXT;
1.1 root 654: fprintf (asmfile, ".stabs \"%s:t",
655: IDENTIFIER_POINTER (DECL_NAME (decl)));
656:
657: current_sym_code = N_LSYM;
658:
1.1.1.3 root 659: dbxout_type (TREE_TYPE (decl), 1);
1.1 root 660: dbxout_finish_symbol ();
1.1.1.7 root 661:
662: /* Prevent duplicate output of a typedef. */
663: TREE_ASM_WRITTEN (decl) = 1;
1.1 root 664: break;
665:
666: case PARM_DECL:
667: /* Parm decls go in their own separate chains
668: and are output by dbxout_reg_parms and dbxout_parms. */
669: abort ();
670:
671: case VAR_DECL:
1.1.1.3 root 672: if (DECL_RTL (decl) == 0)
673: return;
1.1 root 674: /* Don't mention a variable that is external.
675: Let the file that defines it describe it. */
676: if (TREE_EXTERNAL (decl))
677: break;
678:
679: /* Don't mention a variable at all
680: if it was completely optimized into nothingness. */
681: if (GET_CODE (DECL_RTL (decl)) == REG
1.1.1.2 root 682: && (REGNO (DECL_RTL (decl)) < 0
683: || REGNO (DECL_RTL (decl)) >= FIRST_PSEUDO_REGISTER))
1.1 root 684: break;
685:
686: /* The kind-of-variable letter depends on where
687: the variable is and on the scope of its name:
688: G and N_GSYM for static storage and global scope,
689: S for static storage and file scope,
1.1.1.4 root 690: V for static storage and local scope,
1.1 root 691: for those two, use N_LCSYM if data is in bss segment,
692: N_STSYM if it is in data segment, or N_FUN if in text segment.
693: no letter at all, and N_LSYM, for auto variable,
694: r and N_RSYM for register variable. */
695:
696: if (GET_CODE (DECL_RTL (decl)) == MEM
697: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
698: {
699: if (TREE_PUBLIC (decl))
700: {
701: letter = 'G';
702: current_sym_code = N_GSYM;
703: }
704: else
705: {
706: current_sym_addr = XEXP (DECL_RTL (decl), 0);
707:
1.1.1.4 root 708: letter = TREE_PERMANENT (decl) ? 'S' : 'V';
1.1 root 709:
710: if (!DECL_INITIAL (decl))
711: current_sym_code = N_LCSYM;
712: else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
713: /* This is not quite right, but it's the closest
714: of all the codes that Unix defines. */
715: current_sym_code = N_FUN;
716: else
717: current_sym_code = N_STSYM;
718: }
719: }
1.1.1.2 root 720: else if (GET_CODE (DECL_RTL (decl)) == REG)
721: {
722: letter = 'r';
723: current_sym_code = N_RSYM;
724: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));
725: }
726: else if (GET_CODE (DECL_RTL (decl)) == MEM
727: && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
728: || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG
729: && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))
1.1.1.6 root 730: /* If the value is indirect by memory or by a register
731: that isn't the frame pointer
1.1.1.2 root 732: then it means the object is variable-sized and address through
733: that register or stack slot. DBX has no way to represent this
1.1.1.5 root 734: so all we can do is output the variable as a pointer.
735: If it's not a parameter, ignore it.
736: (VAR_DECLs like this can be made by integrate.c.) */
1.1 root 737: {
1.1.1.2 root 738: if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1 root 739: {
740: letter = 'r';
741: current_sym_code = N_RSYM;
1.1.1.2 root 742: current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (DECL_RTL (decl), 0)));
1.1 root 743: }
744: else
745: {
746: current_sym_code = N_LSYM;
1.1.1.2 root 747: /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).
1.1 root 748: We want the value of that CONST_INT. */
1.1.1.2 root 749: current_sym_value = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (decl), 0), 0), 1));
1.1 root 750: }
1.1.1.2 root 751:
752: type = build_pointer_type (TREE_TYPE (decl));
1.1 root 753: }
1.1.1.2 root 754: else if (GET_CODE (DECL_RTL (decl)) == MEM
1.1.1.8 root 755: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1.1.2 root 756: {
757: current_sym_code = N_LSYM;
1.1.1.8 root 758: current_sym_value = 0;
759: }
760: else if (GET_CODE (DECL_RTL (decl)) == MEM
761: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == PLUS
762: && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 1)) == CONST_INT)
763: {
764: current_sym_code = N_LSYM;
765: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
766: We want the value of that CONST_INT. */
767: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));
1.1.1.2 root 768: }
1.1.1.8 root 769: else
770: /* Address might be a MEM, when DECL is a variable-sized object.
771: Or it might be const0_rtx, meaning previous passes
772: want us to ignore this variable. */
773: break;
774:
775: /* Ok, start a symtab entry and output the variable name. */
1.1.1.9 root 776: FORCE_TEXT;
1.1.1.8 root 777: fprintf (asmfile, ".stabs \"%s:",
778: IDENTIFIER_POINTER (DECL_NAME (decl)));
1.1.1.2 root 779: if (letter) putc (letter, asmfile);
780: dbxout_type (type, 0);
781: dbxout_finish_symbol ();
1.1 root 782: break;
783: }
784: }
785:
786: static void
787: dbxout_finish_symbol ()
788: {
789: fprintf (asmfile, "\",%d,0,0,", current_sym_code);
790: if (current_sym_addr)
791: output_addr_const (asmfile, current_sym_addr);
792: else
793: fprintf (asmfile, "%d", current_sym_value);
794: putc ('\n', asmfile);
795: }
796:
797: /* Output definitions of all the decls in a chain. */
798:
799: static void
800: dbxout_syms (syms)
801: tree syms;
802: {
803: while (syms)
804: {
805: dbxout_symbol (syms, 1);
806: syms = TREE_CHAIN (syms);
807: }
808: }
809:
810: /* The following two functions output definitions of function parameters.
811: Each parameter gets a definition locating it in the parameter list.
812: Each parameter that is a register variable gets a second definition
813: locating it in the register.
814:
815: Printing or argument lists in gdb uses the definitions that
816: locate in the parameter list. But reference to the variable in
817: expressions uses preferentially the definition as a register. */
818:
819: /* Output definitions, referring to storage in the parmlist,
820: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
821:
822: static void
823: dbxout_parms (parms)
824: tree parms;
825: {
826: for (; parms; parms = TREE_CHAIN (parms))
827: {
1.1.1.2 root 828: if (DECL_OFFSET (parms) >= 0)
829: {
830: current_sym_code = N_PSYM;
831: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
832: current_sym_addr = 0;
833: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
834:
1.1.1.9 root 835: FORCE_TEXT;
1.1.1.2 root 836: fprintf (asmfile, ".stabs \"%s:p",
837: IDENTIFIER_POINTER (DECL_NAME (parms)));
838:
839: if (GET_CODE (DECL_RTL (parms)) == REG
840: && REGNO (DECL_RTL (parms)) >= 0
841: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
842: dbxout_type (DECL_ARG_TYPE (parms), 0);
843: else
844: {
845: /* This is the case where the parm is passed as an int or double
846: and it is converted to a char, short or float and stored back
847: in the parmlist. In this case, describe the parm
848: with the variable's declared type, and adjust the address
849: if the least significant bytes (which we are using) are not
850: the first ones. */
1.1 root 851: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 root 852: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
853: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
854: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
1.1 root 855: #endif
856:
1.1.1.2 root 857: if (GET_CODE (DECL_RTL (parms)) == MEM
858: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
859: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
860: && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)
861: dbxout_type (TREE_TYPE (parms), 0);
862: else
863: {
864: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
865: dbxout_type (DECL_ARG_TYPE (parms), 0);
866: }
867: }
868: dbxout_finish_symbol ();
869: }
870: /* Parm was passed in registers.
1.1.1.4 root 871: If it lives in a hard register, output a "regparm" symbol
1.1.1.2 root 872: for the register it lives in. */
1.1.1.4 root 873: else if (GET_CODE (DECL_RTL (parms)) == REG
874: && REGNO (DECL_RTL (parms)) >= 0
875: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
1.1.1.2 root 876: {
877: current_sym_code = N_RSYM;
878: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
879: current_sym_addr = 0;
880: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
881:
1.1.1.9 root 882: FORCE_TEXT;
1.1.1.2 root 883: fprintf (asmfile, ".stabs \"%s:P",
884: IDENTIFIER_POINTER (DECL_NAME (parms)));
885:
886: dbxout_type (DECL_ARG_TYPE (parms), 0);
887: dbxout_finish_symbol ();
888: }
889: else if (GET_CODE (DECL_RTL (parms)) == MEM
890: && XEXP (DECL_RTL (parms), 0) != const0_rtx)
891: {
892: current_sym_code = N_LSYM;
893: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
894: We want the value of that CONST_INT. */
895: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
896: current_sym_addr = 0;
897: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
898:
1.1.1.9 root 899: FORCE_TEXT;
1.1.1.2 root 900: fprintf (asmfile, ".stabs \"%s:p",
901: IDENTIFIER_POINTER (DECL_NAME (parms)));
902:
903: /* This is the case where the parm is passed as an int or double
904: and it is converted to a char, short or float and stored back
905: in the parmlist. In this case, describe the parm
906: with the variable's declared type, and adjust the address
907: if the least significant bytes (which we are using) are not
908: the first ones. */
909: #ifdef BYTES_BIG_ENDIAN
910: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
911: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
912: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
913: #endif
914:
915: dbxout_type (TREE_TYPE (parms), 0);
916: dbxout_finish_symbol ();
917: }
1.1 root 918: }
919: }
920:
921: /* Output definitions, referring to registers,
922: of all the parms in PARMS which are stored in registers during the function.
923: PARMS is a chain of PARM_DECL nodes. */
924:
925: static void
926: dbxout_reg_parms (parms)
927: tree parms;
928: {
929: while (parms)
930: {
1.1.1.2 root 931: /* Report parms that live in registers during the function. */
1.1 root 932: if (GET_CODE (DECL_RTL (parms)) == REG
1.1.1.2 root 933: && REGNO (DECL_RTL (parms)) >= 0
934: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
935: && DECL_OFFSET (parms) >= 0)
1.1 root 936: {
937: current_sym_code = N_RSYM;
938: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
939: current_sym_addr = 0;
1.1.1.6 root 940: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
1.1.1.9 root 941: FORCE_TEXT;
1.1 root 942: fprintf (asmfile, ".stabs \"%s:r",
943: IDENTIFIER_POINTER (DECL_NAME (parms)));
944: dbxout_type (TREE_TYPE (parms), 0);
945: dbxout_finish_symbol ();
946: }
1.1.1.2 root 947: /* Report parms that live in memory but outside the parmlist. */
948: else if (GET_CODE (DECL_RTL (parms)) == MEM
949: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
950: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT)
951: {
952: int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
953: /* A parm declared char is really passed as an int,
954: so it occupies the least significant bytes.
955: On a big-endian machine those are not the low-numbered ones. */
956: #ifdef BYTES_BIG_ENDIAN
957: if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
958: offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
959: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
960: #endif
961: if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset)
962: {
963: current_sym_code = N_LSYM;
964: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
965: current_sym_addr = 0;
1.1.1.6 root 966: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
1.1.1.9 root 967: FORCE_TEXT;
1.1.1.2 root 968: fprintf (asmfile, ".stabs \"%s:",
969: IDENTIFIER_POINTER (DECL_NAME (parms)));
970: dbxout_type (TREE_TYPE (parms), 0);
971: dbxout_finish_symbol ();
972: }
973: }
1.1 root 974: parms = TREE_CHAIN (parms);
975: }
976: }
977:
1.1.1.6 root 978: /* Given a chain of ..._TYPE nodes (as come in a parameter list),
979: output definitions of those names, in raw form */
980:
981: void
982: dbxout_args (args)
983: tree args;
984: {
985: while (args)
986: {
987: putc (',', asmfile);
988: dbxout_type (TREE_VALUE (args), 0);
989: CHARS (1);
990: args = TREE_CHAIN (args);
991: }
992: }
993:
1.1.1.7 root 994: /* Given a chain of ..._TYPE nodes,
995: find those which have typedef names and output those names.
996: This is to ensure those types get output. */
1.1 root 997:
998: void
999: dbxout_types (types)
1000: register tree types;
1001: {
1002: while (types)
1003: {
1004: if (TYPE_NAME (types)
1.1.1.7 root 1005: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL
1006: && ! TREE_ASM_WRITTEN (TYPE_NAME (types)))
1007: dbxout_symbol (TYPE_NAME (types), 1);
1.1 root 1008: types = TREE_CHAIN (types);
1009: }
1010: }
1011:
1012: /* Output the tags (struct, union and enum definitions with names) for a block,
1013: given a list of them (a chain of TREE_LIST nodes) in TAGS.
1014: We must check to include those that have been mentioned already with
1015: only a cross-reference. */
1016:
1017: void
1018: dbxout_tags (tags)
1019: tree tags;
1020: {
1021: register tree link;
1022: for (link = tags; link; link = TREE_CHAIN (link))
1023: {
1.1.1.2 root 1024: register tree type = TYPE_MAIN_VARIANT (TREE_VALUE (link));
1.1 root 1025: if (TREE_PURPOSE (link) != 0
1.1.1.2 root 1026: && ! TREE_ASM_WRITTEN (link)
1.1 root 1027: && TYPE_SIZE (type) != 0)
1028: {
1.1.1.2 root 1029: TREE_ASM_WRITTEN (link) = 1;
1.1 root 1030: current_sym_code = N_LSYM;
1031: current_sym_value = 0;
1032: current_sym_addr = 0;
1.1.1.6 root 1033: current_sym_nchars = 2 + IDENTIFIER_LENGTH (TREE_PURPOSE (link));
1.1 root 1034:
1.1.1.9 root 1035: FORCE_TEXT;
1.1 root 1036: fprintf (asmfile, ".stabs \"%s:T",
1037: IDENTIFIER_POINTER (TREE_PURPOSE (link)));
1038: dbxout_type (type, 1);
1039: dbxout_finish_symbol ();
1040: }
1041: }
1042: }
1043:
1044: /* Output everything about a symbol block (that is to say, a LET_STMT node
1045: that represents a scope level),
1046: including recursive output of contained blocks.
1047:
1048: STMT is the LET_STMT node.
1049: DEPTH is its depth within containing symbol blocks.
1050: ARGS is usually zero; but for the outermost block of the
1051: body of a function, it is a chain of PARM_DECLs for the function parameters.
1052: We output definitions of all the register parms
1053: as if they were local variables of that block.
1054:
1055: Actually, STMT may be several statements chained together.
1056: We handle them all in sequence. */
1057:
1058: static void
1059: dbxout_block (stmt, depth, args)
1060: register tree stmt;
1061: int depth;
1.1.1.2 root 1062: tree args;
1.1 root 1063: {
1064: int blocknum;
1065:
1066: while (stmt)
1067: {
1068: switch (TREE_CODE (stmt))
1069: {
1070: case COMPOUND_STMT:
1071: case LOOP_STMT:
1072: dbxout_block (STMT_BODY (stmt), depth, 0);
1073: break;
1074:
1075: case IF_STMT:
1076: dbxout_block (STMT_THEN (stmt), depth, 0);
1077: dbxout_block (STMT_ELSE (stmt), depth, 0);
1078: break;
1079:
1080: case LET_STMT:
1081: /* In dbx format, the syms of a block come before the N_LBRAC. */
1082: dbxout_tags (STMT_TYPE_TAGS (stmt));
1.1.1.2 root 1083: dbxout_syms (STMT_VARS (stmt));
1.1 root 1084: if (args)
1085: dbxout_reg_parms (args);
1086:
1087: /* Now output an N_LBRAC symbol to represent the beginning of
1088: the block. Use the block's tree-walk order to generate
1089: the assembler symbols LBBn and LBEn
1090: that final will define around the code in this block. */
1091: if (depth > 0)
1092: {
1093: blocknum = next_block_number++;
1094: fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum);
1095: }
1096:
1097: /* Output the interior of the block. */
1098: dbxout_block (STMT_BODY (stmt), depth + 1, 0);
1099:
1100: /* Refer to the marker for the end of the block. */
1101: if (depth > 0)
1102: fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum);
1103: }
1104: stmt = TREE_CHAIN (stmt);
1105: }
1106: }
1107:
1108: /* Output dbx data for a function definition.
1109: This includes a definition of the function name itself (a symbol),
1110: definitions of the parameters (locating them in the parameter list)
1111: and then output the block that makes up the function's body
1112: (including all the auto variables of the function). */
1113:
1114: void
1115: dbxout_function (decl)
1116: tree decl;
1117: {
1118: dbxout_symbol (decl, 0);
1119: dbxout_parms (DECL_ARGUMENTS (decl));
1120: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
1121: }
1.1.1.2 root 1122:
1.1.1.4 root 1123: #else /* not DBX_DEBUGGING_INFO */
1.1.1.2 root 1124:
1125: void
1126: dbxout_init (asm_file, input_file_name)
1127: FILE *asm_file;
1128: char *input_file_name;
1129: {}
1130:
1131: void
1132: dbxout_symbol (decl, local)
1133: tree decl;
1134: int local;
1135: {}
1136:
1137: void
1138: dbxout_types (types)
1139: register tree types;
1140: {}
1141:
1142: void
1143: dbxout_tags (tags)
1144: tree tags;
1145: {}
1146:
1147: void
1148: dbxout_function (decl)
1149: tree decl;
1150: {}
1151:
1.1.1.4 root 1152: #endif /* DBX_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.