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