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