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