|
|
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: /* The kind-of-variable letter depends on where
653: the variable is and on the scope of its name:
654: G and N_GSYM for static storage and global scope,
655: S for static storage and file scope,
1.1.1.4 root 656: V for static storage and local scope,
1.1 root 657: for those two, use N_LCSYM if data is in bss segment,
658: N_STSYM if it is in data segment, or N_FUN if in text segment.
659: no letter at all, and N_LSYM, for auto variable,
660: r and N_RSYM for register variable. */
661:
662: if (GET_CODE (DECL_RTL (decl)) == MEM
663: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
664: {
665: if (TREE_PUBLIC (decl))
666: {
667: letter = 'G';
668: current_sym_code = N_GSYM;
669: }
670: else
671: {
672: current_sym_addr = XEXP (DECL_RTL (decl), 0);
673:
1.1.1.4 root 674: letter = TREE_PERMANENT (decl) ? 'S' : 'V';
1.1 root 675:
676: if (!DECL_INITIAL (decl))
677: current_sym_code = N_LCSYM;
678: else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
679: /* This is not quite right, but it's the closest
680: of all the codes that Unix defines. */
681: current_sym_code = N_FUN;
682: else
683: current_sym_code = N_STSYM;
684: }
685: }
1.1.1.2 root 686: else if (GET_CODE (DECL_RTL (decl)) == REG)
687: {
688: letter = 'r';
689: current_sym_code = N_RSYM;
690: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));
691: }
692: else if (GET_CODE (DECL_RTL (decl)) == MEM
1.1.1.5 root 693: && TREE_CODE (decl) == PARM_DECL
1.1.1.2 root 694: && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
695: || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG
696: && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))
1.1.1.6 root 697: /* If the value is indirect by memory or by a register
698: that isn't the frame pointer
1.1.1.2 root 699: then it means the object is variable-sized and address through
700: that register or stack slot. DBX has no way to represent this
1.1.1.5 root 701: so all we can do is output the variable as a pointer.
702: If it's not a parameter, ignore it.
703: (VAR_DECLs like this can be made by integrate.c.) */
1.1 root 704: {
1.1.1.2 root 705: if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1 root 706: {
707: letter = 'r';
708: current_sym_code = N_RSYM;
1.1.1.2 root 709: current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (DECL_RTL (decl), 0)));
1.1 root 710: }
711: else
712: {
713: current_sym_code = N_LSYM;
1.1.1.2 root 714: /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).
1.1 root 715: We want the value of that CONST_INT. */
1.1.1.2 root 716: current_sym_value = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (decl), 0), 0), 1));
1.1 root 717: }
1.1.1.2 root 718:
719: type = build_pointer_type (TREE_TYPE (decl));
1.1 root 720: }
1.1.1.2 root 721: else if (GET_CODE (DECL_RTL (decl)) == MEM
1.1.1.8 ! root 722: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1.1.2 root 723: {
724: current_sym_code = N_LSYM;
1.1.1.8 ! root 725: current_sym_value = 0;
! 726: }
! 727: else if (GET_CODE (DECL_RTL (decl)) == MEM
! 728: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == PLUS
! 729: && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 1)) == CONST_INT)
! 730: {
! 731: current_sym_code = N_LSYM;
! 732: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
! 733: We want the value of that CONST_INT. */
! 734: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));
1.1.1.2 root 735: }
1.1.1.8 ! root 736: else
! 737: /* Address might be a MEM, when DECL is a variable-sized object.
! 738: Or it might be const0_rtx, meaning previous passes
! 739: want us to ignore this variable. */
! 740: break;
! 741:
! 742: /* Ok, start a symtab entry and output the variable name. */
! 743: fprintf (asmfile, ".stabs \"%s:",
! 744: IDENTIFIER_POINTER (DECL_NAME (decl)));
1.1.1.2 root 745: if (letter) putc (letter, asmfile);
746: dbxout_type (type, 0);
747: dbxout_finish_symbol ();
1.1 root 748: break;
749: }
750: }
751:
752: static void
753: dbxout_finish_symbol ()
754: {
755: fprintf (asmfile, "\",%d,0,0,", current_sym_code);
756: if (current_sym_addr)
757: output_addr_const (asmfile, current_sym_addr);
758: else
759: fprintf (asmfile, "%d", current_sym_value);
760: putc ('\n', asmfile);
761: }
762:
763: /* Output definitions of all the decls in a chain. */
764:
765: static void
766: dbxout_syms (syms)
767: tree syms;
768: {
769: while (syms)
770: {
771: dbxout_symbol (syms, 1);
772: syms = TREE_CHAIN (syms);
773: }
774: }
775:
776: /* The following two functions output definitions of function parameters.
777: Each parameter gets a definition locating it in the parameter list.
778: Each parameter that is a register variable gets a second definition
779: locating it in the register.
780:
781: Printing or argument lists in gdb uses the definitions that
782: locate in the parameter list. But reference to the variable in
783: expressions uses preferentially the definition as a register. */
784:
785: /* Output definitions, referring to storage in the parmlist,
786: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
787:
788: static void
789: dbxout_parms (parms)
790: tree parms;
791: {
792: for (; parms; parms = TREE_CHAIN (parms))
793: {
1.1.1.2 root 794: if (DECL_OFFSET (parms) >= 0)
795: {
796: current_sym_code = N_PSYM;
797: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
798: current_sym_addr = 0;
799: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
800:
801: fprintf (asmfile, ".stabs \"%s:p",
802: IDENTIFIER_POINTER (DECL_NAME (parms)));
803:
804: if (GET_CODE (DECL_RTL (parms)) == REG
805: && REGNO (DECL_RTL (parms)) >= 0
806: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
807: dbxout_type (DECL_ARG_TYPE (parms), 0);
808: else
809: {
810: /* This is the case where the parm is passed as an int or double
811: and it is converted to a char, short or float and stored back
812: in the parmlist. In this case, describe the parm
813: with the variable's declared type, and adjust the address
814: if the least significant bytes (which we are using) are not
815: the first ones. */
1.1 root 816: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 root 817: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
818: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
819: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
1.1 root 820: #endif
821:
1.1.1.2 root 822: if (GET_CODE (DECL_RTL (parms)) == MEM
823: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
824: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
825: && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)
826: dbxout_type (TREE_TYPE (parms), 0);
827: else
828: {
829: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
830: dbxout_type (DECL_ARG_TYPE (parms), 0);
831: }
832: }
833: dbxout_finish_symbol ();
834: }
835: /* Parm was passed in registers.
1.1.1.4 root 836: If it lives in a hard register, output a "regparm" symbol
1.1.1.2 root 837: for the register it lives in. */
1.1.1.4 root 838: else if (GET_CODE (DECL_RTL (parms)) == REG
839: && REGNO (DECL_RTL (parms)) >= 0
840: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
1.1.1.2 root 841: {
842: current_sym_code = N_RSYM;
843: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
844: current_sym_addr = 0;
845: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
846:
847: fprintf (asmfile, ".stabs \"%s:P",
848: IDENTIFIER_POINTER (DECL_NAME (parms)));
849:
850: dbxout_type (DECL_ARG_TYPE (parms), 0);
851: dbxout_finish_symbol ();
852: }
853: else if (GET_CODE (DECL_RTL (parms)) == MEM
854: && XEXP (DECL_RTL (parms), 0) != const0_rtx)
855: {
856: current_sym_code = N_LSYM;
857: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
858: We want the value of that CONST_INT. */
859: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
860: current_sym_addr = 0;
861: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
862:
863: fprintf (asmfile, ".stabs \"%s:p",
864: IDENTIFIER_POINTER (DECL_NAME (parms)));
865:
866: /* This is the case where the parm is passed as an int or double
867: and it is converted to a char, short or float and stored back
868: in the parmlist. In this case, describe the parm
869: with the variable's declared type, and adjust the address
870: if the least significant bytes (which we are using) are not
871: the first ones. */
872: #ifdef BYTES_BIG_ENDIAN
873: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
874: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
875: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
876: #endif
877:
878: dbxout_type (TREE_TYPE (parms), 0);
879: dbxout_finish_symbol ();
880: }
1.1 root 881: }
882: }
883:
884: /* Output definitions, referring to registers,
885: of all the parms in PARMS which are stored in registers during the function.
886: PARMS is a chain of PARM_DECL nodes. */
887:
888: static void
889: dbxout_reg_parms (parms)
890: tree parms;
891: {
892: while (parms)
893: {
1.1.1.2 root 894: /* Report parms that live in registers during the function. */
1.1 root 895: if (GET_CODE (DECL_RTL (parms)) == REG
1.1.1.2 root 896: && REGNO (DECL_RTL (parms)) >= 0
897: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
898: && DECL_OFFSET (parms) >= 0)
1.1 root 899: {
900: current_sym_code = N_RSYM;
901: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
902: current_sym_addr = 0;
1.1.1.6 root 903: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
1.1 root 904: fprintf (asmfile, ".stabs \"%s:r",
905: IDENTIFIER_POINTER (DECL_NAME (parms)));
906: dbxout_type (TREE_TYPE (parms), 0);
907: dbxout_finish_symbol ();
908: }
1.1.1.2 root 909: /* Report parms that live in memory but outside the parmlist. */
910: else if (GET_CODE (DECL_RTL (parms)) == MEM
911: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
912: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT)
913: {
914: int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
915: /* A parm declared char is really passed as an int,
916: so it occupies the least significant bytes.
917: On a big-endian machine those are not the low-numbered ones. */
918: #ifdef BYTES_BIG_ENDIAN
919: if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
920: offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
921: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
922: #endif
923: if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset)
924: {
925: current_sym_code = N_LSYM;
926: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
927: current_sym_addr = 0;
1.1.1.6 root 928: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
1.1.1.2 root 929: fprintf (asmfile, ".stabs \"%s:",
930: IDENTIFIER_POINTER (DECL_NAME (parms)));
931: dbxout_type (TREE_TYPE (parms), 0);
932: dbxout_finish_symbol ();
933: }
934: }
1.1 root 935: parms = TREE_CHAIN (parms);
936: }
937: }
938:
1.1.1.6 root 939: /* Given a chain of ..._TYPE nodes (as come in a parameter list),
940: output definitions of those names, in raw form */
941:
942: void
943: dbxout_args (args)
944: tree args;
945: {
946: while (args)
947: {
948: putc (',', asmfile);
949: dbxout_type (TREE_VALUE (args), 0);
950: CHARS (1);
951: args = TREE_CHAIN (args);
952: }
953: }
954:
1.1.1.7 root 955: /* Given a chain of ..._TYPE nodes,
956: find those which have typedef names and output those names.
957: This is to ensure those types get output. */
1.1 root 958:
959: void
960: dbxout_types (types)
961: register tree types;
962: {
963: while (types)
964: {
965: if (TYPE_NAME (types)
1.1.1.7 root 966: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL
967: && ! TREE_ASM_WRITTEN (TYPE_NAME (types)))
968: dbxout_symbol (TYPE_NAME (types), 1);
1.1 root 969: types = TREE_CHAIN (types);
970: }
971: }
972:
973: /* Output the tags (struct, union and enum definitions with names) for a block,
974: given a list of them (a chain of TREE_LIST nodes) in TAGS.
975: We must check to include those that have been mentioned already with
976: only a cross-reference. */
977:
978: void
979: dbxout_tags (tags)
980: tree tags;
981: {
982: register tree link;
983: for (link = tags; link; link = TREE_CHAIN (link))
984: {
1.1.1.2 root 985: register tree type = TYPE_MAIN_VARIANT (TREE_VALUE (link));
1.1 root 986: if (TREE_PURPOSE (link) != 0
1.1.1.2 root 987: && ! TREE_ASM_WRITTEN (link)
1.1 root 988: && TYPE_SIZE (type) != 0)
989: {
1.1.1.2 root 990: TREE_ASM_WRITTEN (link) = 1;
1.1 root 991: current_sym_code = N_LSYM;
992: current_sym_value = 0;
993: current_sym_addr = 0;
1.1.1.6 root 994: current_sym_nchars = 2 + IDENTIFIER_LENGTH (TREE_PURPOSE (link));
1.1 root 995:
996: fprintf (asmfile, ".stabs \"%s:T",
997: IDENTIFIER_POINTER (TREE_PURPOSE (link)));
998: dbxout_type (type, 1);
999: dbxout_finish_symbol ();
1000: }
1001: }
1002: }
1003:
1004: /* Output everything about a symbol block (that is to say, a LET_STMT node
1005: that represents a scope level),
1006: including recursive output of contained blocks.
1007:
1008: STMT is the LET_STMT node.
1009: DEPTH is its depth within containing symbol blocks.
1010: ARGS is usually zero; but for the outermost block of the
1011: body of a function, it is a chain of PARM_DECLs for the function parameters.
1012: We output definitions of all the register parms
1013: as if they were local variables of that block.
1014:
1015: Actually, STMT may be several statements chained together.
1016: We handle them all in sequence. */
1017:
1018: static void
1019: dbxout_block (stmt, depth, args)
1020: register tree stmt;
1021: int depth;
1.1.1.2 root 1022: tree args;
1.1 root 1023: {
1024: int blocknum;
1025:
1026: while (stmt)
1027: {
1028: switch (TREE_CODE (stmt))
1029: {
1030: case COMPOUND_STMT:
1031: case LOOP_STMT:
1032: dbxout_block (STMT_BODY (stmt), depth, 0);
1033: break;
1034:
1035: case IF_STMT:
1036: dbxout_block (STMT_THEN (stmt), depth, 0);
1037: dbxout_block (STMT_ELSE (stmt), depth, 0);
1038: break;
1039:
1040: case LET_STMT:
1041: /* In dbx format, the syms of a block come before the N_LBRAC. */
1042: dbxout_tags (STMT_TYPE_TAGS (stmt));
1.1.1.2 root 1043: dbxout_syms (STMT_VARS (stmt));
1.1 root 1044: if (args)
1045: dbxout_reg_parms (args);
1046:
1047: /* Now output an N_LBRAC symbol to represent the beginning of
1048: the block. Use the block's tree-walk order to generate
1049: the assembler symbols LBBn and LBEn
1050: that final will define around the code in this block. */
1051: if (depth > 0)
1052: {
1053: blocknum = next_block_number++;
1054: fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum);
1055: }
1056:
1057: /* Output the interior of the block. */
1058: dbxout_block (STMT_BODY (stmt), depth + 1, 0);
1059:
1060: /* Refer to the marker for the end of the block. */
1061: if (depth > 0)
1062: fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum);
1063: }
1064: stmt = TREE_CHAIN (stmt);
1065: }
1066: }
1067:
1068: /* Output dbx data for a function definition.
1069: This includes a definition of the function name itself (a symbol),
1070: definitions of the parameters (locating them in the parameter list)
1071: and then output the block that makes up the function's body
1072: (including all the auto variables of the function). */
1073:
1074: void
1075: dbxout_function (decl)
1076: tree decl;
1077: {
1078: dbxout_symbol (decl, 0);
1079: dbxout_parms (DECL_ARGUMENTS (decl));
1080: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
1081: }
1.1.1.2 root 1082:
1.1.1.4 root 1083: #else /* not DBX_DEBUGGING_INFO */
1.1.1.2 root 1084:
1085: void
1086: dbxout_init (asm_file, input_file_name)
1087: FILE *asm_file;
1088: char *input_file_name;
1089: {}
1090:
1091: void
1092: dbxout_symbol (decl, local)
1093: tree decl;
1094: int local;
1095: {}
1096:
1097: void
1098: dbxout_types (types)
1099: register tree types;
1100: {}
1101:
1102: void
1103: dbxout_tags (tags)
1104: tree tags;
1105: {}
1106:
1107: void
1108: dbxout_function (decl)
1109: tree decl;
1110: {}
1111:
1.1.1.4 root 1112: #endif /* DBX_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.