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