|
|
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.7 root 196: dbxout_symbol (TYPE_NAME (integer_type_node));
197: dbxout_symbol (TYPE_NAME (char_type_node));
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.7 root 368: /* We shouldn't be outputting a reference to a type before its
369: definition unless the type has a tag name.
370: A typedef name without a tag name should be impossible. */
371: if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE)
372: abort ();
1.1 root 373: dbxout_type_name (type);
374: fprintf (asmfile, ":");
375: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
376: break;
377: }
378: tem = size_in_bytes (type);
379: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
380: TREE_INT_CST_LOW (tem));
1.1.1.6 root 381:
382: if (TYPE_BASETYPES (type) && use_gdb_dbx_extensions)
383: {
384: putc ('!', asmfile);
385: putc ((TREE_PUBLIC (TYPE_BASETYPES (type)) ? '2' : '0'),
386: asmfile);
387: dbxout_type (TREE_VALUE (TYPE_BASETYPES (type)), 0);
388: putc (',', asmfile);
389: CHARS (3);
390: }
1.1 root 391: CHARS (11);
1.1.1.6 root 392:
1.1 root 393: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
394: /* Output the name, type, position (in bits), size (in bits)
395: of each field. */
396: /* Omit here the nameless fields that are used to skip bits. */
397: if (DECL_NAME (tem) != 0)
398: {
1.1.1.2 root 399: /* Continue the line if necessary,
400: but not before the first field. */
401: if (tem != TYPE_FIELDS (type))
402: CONTIN;
1.1 root 403: fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
1.1.1.6 root 404: CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));
405: if (use_gdb_dbx_extensions)
406: {
407: putc ('/', asmfile);
408: #ifdef TREE_PRIVATE
409: putc ((TREE_PRIVATE (tem) ? '0'
410: : TREE_PROTECTED (tem) ? '1' : '2'),
411: asmfile);
412: #endif
413: CHARS (2);
414: if (TREE_CODE (tem) == FUNCTION_DECL)
415: {
416: putc (':', asmfile);
417: CHARS (1);
418: dbxout_type (TREE_TYPE (tem), 0); /* FUNCTION_TYPE */
419: dbxout_args (TYPE_ARG_TYPES (TREE_TYPE (tem)));
420: #ifdef TREE_VIRTUAL
421: fprintf (asmfile, ":%s;%c",
422: XSTR (XEXP (DECL_RTL (tem), 0), 0),
423: TREE_VIRTUAL (tem) ? '*' : '.');
424: #endif
425: CHARS (3 + strlen (XSTR (XEXP (DECL_RTL (tem), 0), 0)));
426: }
427: else
428: dbxout_type (TREE_TYPE (tem), 0);
429: }
430: else
431: dbxout_type (TREE_TYPE (tem), 0);
432:
433: if (TREE_CODE (tem) == VAR_DECL)
434: {
435: if (use_gdb_dbx_extensions)
436: {
437: fprintf (asmfile, ":%s",
438: XSTR (XEXP (DECL_RTL (tem), 0), 0));
439: CHARS (2 + strlen (XSTR (XEXP (DECL_RTL (tem), 0), 0)));
440: }
441: else
442: {
443: fprintf (asmfile, ",0,0;");
444: CHARS (5);
445: }
446: }
447: else
448: {
449: fprintf (asmfile, ",%d,%d;", DECL_OFFSET (tem),
450: (TREE_INT_CST_LOW (DECL_SIZE (tem))
451: * DECL_SIZE_UNIT (tem)));
452: CHARS (23);
453: }
1.1 root 454: }
1.1.1.6 root 455:
1.1 root 456: putc (';', asmfile);
457: CHARS (1);
458: break;
459:
460: case ENUMERAL_TYPE:
461: if ((TYPE_NAME (type) != 0 && !full)
462: || TYPE_SIZE (type) == 0)
463: {
464: fprintf (asmfile, "xe");
465: CHARS (3);
466: dbxout_type_name (type);
467: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
468: fprintf (asmfile, ":");
469: return;
470: }
471: putc ('e', asmfile);
472: CHARS (1);
473: for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
474: {
475: fprintf (asmfile, "%s:%d,", IDENTIFIER_POINTER (TREE_PURPOSE (tem)),
476: TREE_INT_CST_LOW (TREE_VALUE (tem)));
1.1.1.6 root 477: CHARS (11 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));
1.1 root 478: if (TREE_CHAIN (tem) != 0)
479: CONTIN;
480: }
481: putc (';', asmfile);
482: CHARS (1);
483: break;
484:
485: case POINTER_TYPE:
486: putc ('*', asmfile);
487: CHARS (1);
488: dbxout_type (TREE_TYPE (type), 0);
489: break;
490:
1.1.1.6 root 491: case METHOD_TYPE:
492: if (use_gdb_dbx_extensions)
493: {
494: putc ('@', asmfile);
495: CHARS (1);
496: dbxout_type (TYPE_METHOD_CLASS (type), 0);
497: putc (',', asmfile);
498: CHARS (1);
499: dbxout_type (TREE_TYPE (type), 0);
500: }
501: else
502: {
503: /* Treat it as a function type. */
504: dbxout_type (TREE_TYPE (type), 0);
505: }
506: break;
507:
508: case REFERENCE_TYPE:
509: putc (use_gdb_dbx_extensions ? '&' : '*', asmfile);
510: CHARS (1);
511: dbxout_type (TREE_TYPE (type), 0);
512: break;
513:
1.1 root 514: case FUNCTION_TYPE:
515: putc ('f', asmfile);
516: CHARS (1);
517: dbxout_type (TREE_TYPE (type), 0);
518: break;
1.1.1.6 root 519:
520: default:
521: abort ();
1.1 root 522: }
523: }
524:
525: /* Output the name of type TYPE, with no punctuation.
526: Such names can be set up either by typedef declarations
527: or by struct, enum and union tags. */
528:
529: static void
530: dbxout_type_name (type)
531: register tree type;
532: {
1.1.1.6 root 533: tree t;
1.1 root 534: if (TYPE_NAME (type) == 0)
535: abort ();
536: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
1.1.1.6 root 537: {
538: t = TYPE_NAME (type);
539: }
1.1 root 540: else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
1.1.1.6 root 541: {
542: t = DECL_NAME (TYPE_NAME (type));
543: }
1.1 root 544: else
545: abort ();
546:
1.1.1.6 root 547: fprintf (asmfile, "%s", IDENTIFIER_POINTER (t));
548: CHARS (IDENTIFIER_LENGTH (t));
1.1 root 549: }
550:
551: /* Output a .stabs for the symbol defined by DECL,
552: which must be a ..._DECL node in the normal namespace.
553: It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
554: LOCAL is nonzero if the scope is less than the entire file. */
555:
556: void
557: dbxout_symbol (decl, local)
558: tree decl;
559: int local;
560: {
1.1.1.2 root 561: int letter = 0;
562: tree type = TREE_TYPE (decl);
1.1 root 563:
564: /* If global, first output all types and all
565: struct, enum and union tags that have been created
566: and not yet output. */
567:
568: if (local == 0)
569: {
570: dbxout_tags (gettags ());
571: dbxout_types (get_permanent_types ());
572: }
573:
574: current_sym_code = 0;
575: current_sym_value = 0;
576: current_sym_addr = 0;
577:
578: /* The output will always start with the symbol name,
579: so count that always in the length-output-so-far. */
580:
1.1.1.6 root 581: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl));
1.1 root 582:
583: switch (TREE_CODE (decl))
584: {
585: case CONST_DECL:
586: /* Enum values are defined by defining the enum type. */
587: break;
588:
589: case FUNCTION_DECL:
1.1.1.3 root 590: if (DECL_RTL (decl) == 0)
591: return;
1.1 root 592: if (TREE_EXTERNAL (decl))
593: break;
594: if (GET_CODE (DECL_RTL (decl)) != MEM
595: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
596: break;
1.1.1.9 ! root 597: FORCE_TEXT;
1.1 root 598: fprintf (asmfile, ".stabs \"%s:%c",
599: IDENTIFIER_POINTER (DECL_NAME (decl)),
600: TREE_PUBLIC (decl) ? 'F' : 'f');
601:
602: current_sym_code = N_FUN;
603: current_sym_addr = XEXP (DECL_RTL (decl), 0);
604:
605: if (TREE_TYPE (TREE_TYPE (decl)))
606: dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0);
607: else
608: dbxout_type (void_type_node, 0);
609: dbxout_finish_symbol ();
610: break;
611:
612: case TYPE_DECL:
1.1.1.7 root 613: #if 0
614: /* This seems all wrong. Outputting most kinds of types gives no name
615: at all. A true definition gives no name; a cross-ref for a
616: structure can give the tag name, but not a type name.
617: It seems that no typedef name is defined by outputting a type. */
618:
1.1.1.3 root 619: /* If this typedef name was defined by outputting the type,
620: don't duplicate it. */
621: if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED
622: && TYPE_NAME (TREE_TYPE (decl)) == decl)
623: return;
1.1.1.7 root 624: #endif
625: /* Don't output the same typedef twice. */
626: if (TREE_ASM_WRITTEN (decl))
627: return;
1.1.1.3 root 628:
1.1 root 629: /* Output typedef name. */
1.1.1.9 ! root 630: FORCE_TEXT;
1.1 root 631: fprintf (asmfile, ".stabs \"%s:t",
632: IDENTIFIER_POINTER (DECL_NAME (decl)));
633:
634: current_sym_code = N_LSYM;
635:
1.1.1.3 root 636: dbxout_type (TREE_TYPE (decl), 1);
1.1 root 637: dbxout_finish_symbol ();
1.1.1.7 root 638:
639: /* Prevent duplicate output of a typedef. */
640: TREE_ASM_WRITTEN (decl) = 1;
1.1 root 641: break;
642:
643: case PARM_DECL:
644: /* Parm decls go in their own separate chains
645: and are output by dbxout_reg_parms and dbxout_parms. */
646: abort ();
647:
648: case VAR_DECL:
1.1.1.3 root 649: if (DECL_RTL (decl) == 0)
650: return;
1.1 root 651: /* Don't mention a variable that is external.
652: Let the file that defines it describe it. */
653: if (TREE_EXTERNAL (decl))
654: break;
655:
656: /* Don't mention a variable at all
657: if it was completely optimized into nothingness. */
658: if (GET_CODE (DECL_RTL (decl)) == REG
1.1.1.2 root 659: && (REGNO (DECL_RTL (decl)) < 0
660: || REGNO (DECL_RTL (decl)) >= FIRST_PSEUDO_REGISTER))
1.1 root 661: break;
662:
663: /* The kind-of-variable letter depends on where
664: the variable is and on the scope of its name:
665: G and N_GSYM for static storage and global scope,
666: S for static storage and file scope,
1.1.1.4 root 667: V for static storage and local scope,
1.1 root 668: for those two, use N_LCSYM if data is in bss segment,
669: N_STSYM if it is in data segment, or N_FUN if in text segment.
670: no letter at all, and N_LSYM, for auto variable,
671: r and N_RSYM for register variable. */
672:
673: if (GET_CODE (DECL_RTL (decl)) == MEM
674: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
675: {
676: if (TREE_PUBLIC (decl))
677: {
678: letter = 'G';
679: current_sym_code = N_GSYM;
680: }
681: else
682: {
683: current_sym_addr = XEXP (DECL_RTL (decl), 0);
684:
1.1.1.4 root 685: letter = TREE_PERMANENT (decl) ? 'S' : 'V';
1.1 root 686:
687: if (!DECL_INITIAL (decl))
688: current_sym_code = N_LCSYM;
689: else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
690: /* This is not quite right, but it's the closest
691: of all the codes that Unix defines. */
692: current_sym_code = N_FUN;
693: else
694: current_sym_code = N_STSYM;
695: }
696: }
1.1.1.2 root 697: else if (GET_CODE (DECL_RTL (decl)) == REG)
698: {
699: letter = 'r';
700: current_sym_code = N_RSYM;
701: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));
702: }
703: else if (GET_CODE (DECL_RTL (decl)) == MEM
704: && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
705: || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG
706: && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))
1.1.1.6 root 707: /* If the value is indirect by memory or by a register
708: that isn't the frame pointer
1.1.1.2 root 709: then it means the object is variable-sized and address through
710: that register or stack slot. DBX has no way to represent this
1.1.1.5 root 711: so all we can do is output the variable as a pointer.
712: If it's not a parameter, ignore it.
713: (VAR_DECLs like this can be made by integrate.c.) */
1.1 root 714: {
1.1.1.2 root 715: if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1 root 716: {
717: letter = 'r';
718: current_sym_code = N_RSYM;
1.1.1.2 root 719: current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (DECL_RTL (decl), 0)));
1.1 root 720: }
721: else
722: {
723: current_sym_code = N_LSYM;
1.1.1.2 root 724: /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).
1.1 root 725: We want the value of that CONST_INT. */
1.1.1.2 root 726: current_sym_value = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (decl), 0), 0), 1));
1.1 root 727: }
1.1.1.2 root 728:
729: type = build_pointer_type (TREE_TYPE (decl));
1.1 root 730: }
1.1.1.2 root 731: else if (GET_CODE (DECL_RTL (decl)) == MEM
1.1.1.8 root 732: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1.1.2 root 733: {
734: current_sym_code = N_LSYM;
1.1.1.8 root 735: current_sym_value = 0;
736: }
737: else if (GET_CODE (DECL_RTL (decl)) == MEM
738: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == PLUS
739: && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 1)) == CONST_INT)
740: {
741: current_sym_code = N_LSYM;
742: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
743: We want the value of that CONST_INT. */
744: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));
1.1.1.2 root 745: }
1.1.1.8 root 746: else
747: /* Address might be a MEM, when DECL is a variable-sized object.
748: Or it might be const0_rtx, meaning previous passes
749: want us to ignore this variable. */
750: break;
751:
752: /* Ok, start a symtab entry and output the variable name. */
1.1.1.9 ! root 753: FORCE_TEXT;
1.1.1.8 root 754: fprintf (asmfile, ".stabs \"%s:",
755: IDENTIFIER_POINTER (DECL_NAME (decl)));
1.1.1.2 root 756: if (letter) putc (letter, asmfile);
757: dbxout_type (type, 0);
758: dbxout_finish_symbol ();
1.1 root 759: break;
760: }
761: }
762:
763: static void
764: dbxout_finish_symbol ()
765: {
766: fprintf (asmfile, "\",%d,0,0,", current_sym_code);
767: if (current_sym_addr)
768: output_addr_const (asmfile, current_sym_addr);
769: else
770: fprintf (asmfile, "%d", current_sym_value);
771: putc ('\n', asmfile);
772: }
773:
774: /* Output definitions of all the decls in a chain. */
775:
776: static void
777: dbxout_syms (syms)
778: tree syms;
779: {
780: while (syms)
781: {
782: dbxout_symbol (syms, 1);
783: syms = TREE_CHAIN (syms);
784: }
785: }
786:
787: /* The following two functions output definitions of function parameters.
788: Each parameter gets a definition locating it in the parameter list.
789: Each parameter that is a register variable gets a second definition
790: locating it in the register.
791:
792: Printing or argument lists in gdb uses the definitions that
793: locate in the parameter list. But reference to the variable in
794: expressions uses preferentially the definition as a register. */
795:
796: /* Output definitions, referring to storage in the parmlist,
797: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
798:
799: static void
800: dbxout_parms (parms)
801: tree parms;
802: {
803: for (; parms; parms = TREE_CHAIN (parms))
804: {
1.1.1.2 root 805: if (DECL_OFFSET (parms) >= 0)
806: {
807: current_sym_code = N_PSYM;
808: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
809: current_sym_addr = 0;
810: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
811:
1.1.1.9 ! root 812: FORCE_TEXT;
1.1.1.2 root 813: fprintf (asmfile, ".stabs \"%s:p",
814: IDENTIFIER_POINTER (DECL_NAME (parms)));
815:
816: if (GET_CODE (DECL_RTL (parms)) == REG
817: && REGNO (DECL_RTL (parms)) >= 0
818: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
819: dbxout_type (DECL_ARG_TYPE (parms), 0);
820: else
821: {
822: /* This is the case where the parm is passed as an int or double
823: and it is converted to a char, short or float and stored back
824: in the parmlist. In this case, describe the parm
825: with the variable's declared type, and adjust the address
826: if the least significant bytes (which we are using) are not
827: the first ones. */
1.1 root 828: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 root 829: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
830: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
831: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
1.1 root 832: #endif
833:
1.1.1.2 root 834: if (GET_CODE (DECL_RTL (parms)) == MEM
835: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
836: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
837: && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)
838: dbxout_type (TREE_TYPE (parms), 0);
839: else
840: {
841: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
842: dbxout_type (DECL_ARG_TYPE (parms), 0);
843: }
844: }
845: dbxout_finish_symbol ();
846: }
847: /* Parm was passed in registers.
1.1.1.4 root 848: If it lives in a hard register, output a "regparm" symbol
1.1.1.2 root 849: for the register it lives in. */
1.1.1.4 root 850: else if (GET_CODE (DECL_RTL (parms)) == REG
851: && REGNO (DECL_RTL (parms)) >= 0
852: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
1.1.1.2 root 853: {
854: current_sym_code = N_RSYM;
855: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
856: current_sym_addr = 0;
857: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
858:
1.1.1.9 ! root 859: FORCE_TEXT;
1.1.1.2 root 860: fprintf (asmfile, ".stabs \"%s:P",
861: IDENTIFIER_POINTER (DECL_NAME (parms)));
862:
863: dbxout_type (DECL_ARG_TYPE (parms), 0);
864: dbxout_finish_symbol ();
865: }
866: else if (GET_CODE (DECL_RTL (parms)) == MEM
867: && XEXP (DECL_RTL (parms), 0) != const0_rtx)
868: {
869: current_sym_code = N_LSYM;
870: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
871: We want the value of that CONST_INT. */
872: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
873: current_sym_addr = 0;
874: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
875:
1.1.1.9 ! root 876: FORCE_TEXT;
1.1.1.2 root 877: fprintf (asmfile, ".stabs \"%s:p",
878: IDENTIFIER_POINTER (DECL_NAME (parms)));
879:
880: /* This is the case where the parm is passed as an int or double
881: and it is converted to a char, short or float and stored back
882: in the parmlist. In this case, describe the parm
883: with the variable's declared type, and adjust the address
884: if the least significant bytes (which we are using) are not
885: the first ones. */
886: #ifdef BYTES_BIG_ENDIAN
887: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
888: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
889: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
890: #endif
891:
892: dbxout_type (TREE_TYPE (parms), 0);
893: dbxout_finish_symbol ();
894: }
1.1 root 895: }
896: }
897:
898: /* Output definitions, referring to registers,
899: of all the parms in PARMS which are stored in registers during the function.
900: PARMS is a chain of PARM_DECL nodes. */
901:
902: static void
903: dbxout_reg_parms (parms)
904: tree parms;
905: {
906: while (parms)
907: {
1.1.1.2 root 908: /* Report parms that live in registers during the function. */
1.1 root 909: if (GET_CODE (DECL_RTL (parms)) == REG
1.1.1.2 root 910: && REGNO (DECL_RTL (parms)) >= 0
911: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
912: && DECL_OFFSET (parms) >= 0)
1.1 root 913: {
914: current_sym_code = N_RSYM;
915: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
916: current_sym_addr = 0;
1.1.1.6 root 917: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
1.1.1.9 ! root 918: FORCE_TEXT;
1.1 root 919: fprintf (asmfile, ".stabs \"%s:r",
920: IDENTIFIER_POINTER (DECL_NAME (parms)));
921: dbxout_type (TREE_TYPE (parms), 0);
922: dbxout_finish_symbol ();
923: }
1.1.1.2 root 924: /* Report parms that live in memory but outside the parmlist. */
925: else if (GET_CODE (DECL_RTL (parms)) == MEM
926: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
927: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT)
928: {
929: int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
930: /* A parm declared char is really passed as an int,
931: so it occupies the least significant bytes.
932: On a big-endian machine those are not the low-numbered ones. */
933: #ifdef BYTES_BIG_ENDIAN
934: if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
935: offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
936: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
937: #endif
938: if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset)
939: {
940: current_sym_code = N_LSYM;
941: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
942: current_sym_addr = 0;
1.1.1.6 root 943: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
1.1.1.9 ! root 944: FORCE_TEXT;
1.1.1.2 root 945: fprintf (asmfile, ".stabs \"%s:",
946: IDENTIFIER_POINTER (DECL_NAME (parms)));
947: dbxout_type (TREE_TYPE (parms), 0);
948: dbxout_finish_symbol ();
949: }
950: }
1.1 root 951: parms = TREE_CHAIN (parms);
952: }
953: }
954:
1.1.1.6 root 955: /* Given a chain of ..._TYPE nodes (as come in a parameter list),
956: output definitions of those names, in raw form */
957:
958: void
959: dbxout_args (args)
960: tree args;
961: {
962: while (args)
963: {
964: putc (',', asmfile);
965: dbxout_type (TREE_VALUE (args), 0);
966: CHARS (1);
967: args = TREE_CHAIN (args);
968: }
969: }
970:
1.1.1.7 root 971: /* Given a chain of ..._TYPE nodes,
972: find those which have typedef names and output those names.
973: This is to ensure those types get output. */
1.1 root 974:
975: void
976: dbxout_types (types)
977: register tree types;
978: {
979: while (types)
980: {
981: if (TYPE_NAME (types)
1.1.1.7 root 982: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL
983: && ! TREE_ASM_WRITTEN (TYPE_NAME (types)))
984: dbxout_symbol (TYPE_NAME (types), 1);
1.1 root 985: types = TREE_CHAIN (types);
986: }
987: }
988:
989: /* Output the tags (struct, union and enum definitions with names) for a block,
990: given a list of them (a chain of TREE_LIST nodes) in TAGS.
991: We must check to include those that have been mentioned already with
992: only a cross-reference. */
993:
994: void
995: dbxout_tags (tags)
996: tree tags;
997: {
998: register tree link;
999: for (link = tags; link; link = TREE_CHAIN (link))
1000: {
1.1.1.2 root 1001: register tree type = TYPE_MAIN_VARIANT (TREE_VALUE (link));
1.1 root 1002: if (TREE_PURPOSE (link) != 0
1.1.1.2 root 1003: && ! TREE_ASM_WRITTEN (link)
1.1 root 1004: && TYPE_SIZE (type) != 0)
1005: {
1.1.1.2 root 1006: TREE_ASM_WRITTEN (link) = 1;
1.1 root 1007: current_sym_code = N_LSYM;
1008: current_sym_value = 0;
1009: current_sym_addr = 0;
1.1.1.6 root 1010: current_sym_nchars = 2 + IDENTIFIER_LENGTH (TREE_PURPOSE (link));
1.1 root 1011:
1.1.1.9 ! root 1012: FORCE_TEXT;
1.1 root 1013: fprintf (asmfile, ".stabs \"%s:T",
1014: IDENTIFIER_POINTER (TREE_PURPOSE (link)));
1015: dbxout_type (type, 1);
1016: dbxout_finish_symbol ();
1017: }
1018: }
1019: }
1020:
1021: /* Output everything about a symbol block (that is to say, a LET_STMT node
1022: that represents a scope level),
1023: including recursive output of contained blocks.
1024:
1025: STMT is the LET_STMT node.
1026: DEPTH is its depth within containing symbol blocks.
1027: ARGS is usually zero; but for the outermost block of the
1028: body of a function, it is a chain of PARM_DECLs for the function parameters.
1029: We output definitions of all the register parms
1030: as if they were local variables of that block.
1031:
1032: Actually, STMT may be several statements chained together.
1033: We handle them all in sequence. */
1034:
1035: static void
1036: dbxout_block (stmt, depth, args)
1037: register tree stmt;
1038: int depth;
1.1.1.2 root 1039: tree args;
1.1 root 1040: {
1041: int blocknum;
1042:
1043: while (stmt)
1044: {
1045: switch (TREE_CODE (stmt))
1046: {
1047: case COMPOUND_STMT:
1048: case LOOP_STMT:
1049: dbxout_block (STMT_BODY (stmt), depth, 0);
1050: break;
1051:
1052: case IF_STMT:
1053: dbxout_block (STMT_THEN (stmt), depth, 0);
1054: dbxout_block (STMT_ELSE (stmt), depth, 0);
1055: break;
1056:
1057: case LET_STMT:
1058: /* In dbx format, the syms of a block come before the N_LBRAC. */
1059: dbxout_tags (STMT_TYPE_TAGS (stmt));
1.1.1.2 root 1060: dbxout_syms (STMT_VARS (stmt));
1.1 root 1061: if (args)
1062: dbxout_reg_parms (args);
1063:
1064: /* Now output an N_LBRAC symbol to represent the beginning of
1065: the block. Use the block's tree-walk order to generate
1066: the assembler symbols LBBn and LBEn
1067: that final will define around the code in this block. */
1068: if (depth > 0)
1069: {
1070: blocknum = next_block_number++;
1071: fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum);
1072: }
1073:
1074: /* Output the interior of the block. */
1075: dbxout_block (STMT_BODY (stmt), depth + 1, 0);
1076:
1077: /* Refer to the marker for the end of the block. */
1078: if (depth > 0)
1079: fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum);
1080: }
1081: stmt = TREE_CHAIN (stmt);
1082: }
1083: }
1084:
1085: /* Output dbx data for a function definition.
1086: This includes a definition of the function name itself (a symbol),
1087: definitions of the parameters (locating them in the parameter list)
1088: and then output the block that makes up the function's body
1089: (including all the auto variables of the function). */
1090:
1091: void
1092: dbxout_function (decl)
1093: tree decl;
1094: {
1095: dbxout_symbol (decl, 0);
1096: dbxout_parms (DECL_ARGUMENTS (decl));
1097: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
1098: }
1.1.1.2 root 1099:
1.1.1.4 root 1100: #else /* not DBX_DEBUGGING_INFO */
1.1.1.2 root 1101:
1102: void
1103: dbxout_init (asm_file, input_file_name)
1104: FILE *asm_file;
1105: char *input_file_name;
1106: {}
1107:
1108: void
1109: dbxout_symbol (decl, local)
1110: tree decl;
1111: int local;
1112: {}
1113:
1114: void
1115: dbxout_types (types)
1116: register tree types;
1117: {}
1118:
1119: void
1120: dbxout_tags (tags)
1121: tree tags;
1122: {}
1123:
1124: void
1125: dbxout_function (decl)
1126: tree decl;
1127: {}
1128:
1.1.1.4 root 1129: #endif /* DBX_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.