|
|
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:
! 75: #ifndef NO_DBX_FORMAT
! 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:
1.1.1.2 ! root 470: /* If the decl lacks rtl representation, avoid fault below. */
! 471:
! 472: if (DECL_RTL (decl) == 0)
! 473: return;
! 474:
1.1 root 475: current_sym_code = 0;
476: current_sym_value = 0;
477: current_sym_addr = 0;
478:
479: /* The output will always start with the symbol name,
480: so count that always in the length-output-so-far. */
481:
482: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (decl)));
483:
484: switch (TREE_CODE (decl))
485: {
486: case CONST_DECL:
487: /* Enum values are defined by defining the enum type. */
488: break;
489:
490: case FUNCTION_DECL:
491: if (TREE_EXTERNAL (decl))
492: break;
493: if (GET_CODE (DECL_RTL (decl)) != MEM
494: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
495: break;
496: fprintf (asmfile, ".stabs \"%s:%c",
497: IDENTIFIER_POINTER (DECL_NAME (decl)),
498: TREE_PUBLIC (decl) ? 'F' : 'f');
499:
500: current_sym_code = N_FUN;
501: current_sym_addr = XEXP (DECL_RTL (decl), 0);
502:
503: if (TREE_TYPE (TREE_TYPE (decl)))
504: dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0);
505: else
506: dbxout_type (void_type_node, 0);
507: dbxout_finish_symbol ();
508: break;
509:
510: case TYPE_DECL:
511: /* Output typedef name. */
512: fprintf (asmfile, ".stabs \"%s:t",
513: IDENTIFIER_POINTER (DECL_NAME (decl)));
514:
515: current_sym_code = N_LSYM;
516:
517: dbxout_type (TREE_TYPE (decl), 0);
518: dbxout_finish_symbol ();
519: break;
520:
521: case PARM_DECL:
522: /* Parm decls go in their own separate chains
523: and are output by dbxout_reg_parms and dbxout_parms. */
524: abort ();
525:
526: case VAR_DECL:
527: /* Don't mention a variable that is external.
528: Let the file that defines it describe it. */
529: if (TREE_EXTERNAL (decl))
530: break;
531:
532: /* Don't mention a variable at all
533: if it was completely optimized into nothingness. */
534: if (GET_CODE (DECL_RTL (decl)) == REG
1.1.1.2 ! root 535: && (REGNO (DECL_RTL (decl)) < 0
! 536: || REGNO (DECL_RTL (decl)) >= FIRST_PSEUDO_REGISTER))
1.1 root 537: break;
538:
539: /* Ok, start a symtab entry and output the variable name. */
540: fprintf (asmfile, ".stabs \"%s:",
541: IDENTIFIER_POINTER (DECL_NAME (decl)));
1.1.1.2 ! root 542:
1.1 root 543: /* The kind-of-variable letter depends on where
544: the variable is and on the scope of its name:
545: G and N_GSYM for static storage and global scope,
546: S for static storage and file scope,
547: v for static storage and local scope,
548: for those two, use N_LCSYM if data is in bss segment,
549: N_STSYM if it is in data segment, or N_FUN if in text segment.
550: no letter at all, and N_LSYM, for auto variable,
551: r and N_RSYM for register variable. */
552:
553: if (GET_CODE (DECL_RTL (decl)) == MEM
554: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
555: {
556: if (TREE_PUBLIC (decl))
557: {
558: letter = 'G';
559: current_sym_code = N_GSYM;
560: }
561: else
562: {
563: current_sym_addr = XEXP (DECL_RTL (decl), 0);
564:
565: letter = TREE_PERMANENT (decl) ? 'S' : 'v';
566:
567: if (!DECL_INITIAL (decl))
568: current_sym_code = N_LCSYM;
569: else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
570: /* This is not quite right, but it's the closest
571: of all the codes that Unix defines. */
572: current_sym_code = N_FUN;
573: else
574: current_sym_code = N_STSYM;
575: }
576: }
1.1.1.2 ! root 577: else if (GET_CODE (DECL_RTL (decl)) == REG)
! 578: {
! 579: letter = 'r';
! 580: current_sym_code = N_RSYM;
! 581: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));
! 582: }
! 583: else if (GET_CODE (DECL_RTL (decl)) == MEM
! 584: && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
! 585: || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG
! 586: && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))
! 587: /* If the value is indirect by memory or by a register
! 588: that isn't the frame pointer
! 589: then it means the object is variable-sized and address through
! 590: that register or stack slot. DBX has no way to represent this
! 591: so all we can do is output the variable as a pointer. */
1.1 root 592: {
1.1.1.2 ! root 593: if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
1.1 root 594: {
595: letter = 'r';
596: current_sym_code = N_RSYM;
1.1.1.2 ! root 597: current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (DECL_RTL (decl), 0)));
1.1 root 598: }
599: else
600: {
601: current_sym_code = N_LSYM;
1.1.1.2 ! root 602: /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).
1.1 root 603: We want the value of that CONST_INT. */
1.1.1.2 ! root 604: current_sym_value = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (decl), 0), 0), 1));
1.1 root 605: }
1.1.1.2 ! root 606:
! 607: type = build_pointer_type (TREE_TYPE (decl));
1.1 root 608: }
1.1.1.2 ! root 609: else if (GET_CODE (DECL_RTL (decl)) == MEM
! 610: && XEXP (DECL_RTL (decl), 0) != const0_rtx)
! 611: /* const0_rtx is used as the address for a variable that
! 612: is a dummy due to an erroneous declaration.
! 613: Ignore such vars. */
! 614: {
! 615: current_sym_code = N_LSYM;
! 616: if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
! 617: current_sym_value = 0;
! 618: else
! 619: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
! 620: We want the value of that CONST_INT. */
! 621: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));
! 622: }
! 623: if (letter) putc (letter, asmfile);
! 624: dbxout_type (type, 0);
! 625: dbxout_finish_symbol ();
1.1 root 626: break;
627: }
628: }
629:
630: static void
631: dbxout_finish_symbol ()
632: {
633: fprintf (asmfile, "\",%d,0,0,", current_sym_code);
634: if (current_sym_addr)
635: output_addr_const (asmfile, current_sym_addr);
636: else
637: fprintf (asmfile, "%d", current_sym_value);
638: putc ('\n', asmfile);
639: }
640:
641: /* Output definitions of all the decls in a chain. */
642:
643: static void
644: dbxout_syms (syms)
645: tree syms;
646: {
647: while (syms)
648: {
649: dbxout_symbol (syms, 1);
650: syms = TREE_CHAIN (syms);
651: }
652: }
653:
654: /* The following two functions output definitions of function parameters.
655: Each parameter gets a definition locating it in the parameter list.
656: Each parameter that is a register variable gets a second definition
657: locating it in the register.
658:
659: Printing or argument lists in gdb uses the definitions that
660: locate in the parameter list. But reference to the variable in
661: expressions uses preferentially the definition as a register. */
662:
663: /* Output definitions, referring to storage in the parmlist,
664: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
665:
666: static void
667: dbxout_parms (parms)
668: tree parms;
669: {
670: for (; parms; parms = TREE_CHAIN (parms))
671: {
1.1.1.2 ! root 672: if (DECL_OFFSET (parms) >= 0)
! 673: {
! 674: current_sym_code = N_PSYM;
! 675: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
! 676: current_sym_addr = 0;
! 677: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
! 678:
! 679: fprintf (asmfile, ".stabs \"%s:p",
! 680: IDENTIFIER_POINTER (DECL_NAME (parms)));
! 681:
! 682: if (GET_CODE (DECL_RTL (parms)) == REG
! 683: && REGNO (DECL_RTL (parms)) >= 0
! 684: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
! 685: dbxout_type (DECL_ARG_TYPE (parms), 0);
! 686: else
! 687: {
! 688: /* This is the case where the parm is passed as an int or double
! 689: and it is converted to a char, short or float and stored back
! 690: in the parmlist. In this case, describe the parm
! 691: with the variable's declared type, and adjust the address
! 692: if the least significant bytes (which we are using) are not
! 693: the first ones. */
1.1 root 694: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 ! root 695: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
! 696: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
! 697: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
1.1 root 698: #endif
699:
1.1.1.2 ! root 700: if (GET_CODE (DECL_RTL (parms)) == MEM
! 701: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
! 702: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
! 703: && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)
! 704: dbxout_type (TREE_TYPE (parms), 0);
! 705: else
! 706: {
! 707: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
! 708: dbxout_type (DECL_ARG_TYPE (parms), 0);
! 709: }
! 710: }
! 711: dbxout_finish_symbol ();
! 712: }
! 713: /* Parm was passed in registers.
! 714: If it is in a register, output a "regparm" symbol
! 715: for the register it lives in. */
! 716: else if (GET_CODE (DECL_RTL (parms)) == REG)
! 717: {
! 718: current_sym_code = N_RSYM;
! 719: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
! 720: current_sym_addr = 0;
! 721: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
! 722:
! 723: fprintf (asmfile, ".stabs \"%s:P",
! 724: IDENTIFIER_POINTER (DECL_NAME (parms)));
! 725:
! 726: dbxout_type (DECL_ARG_TYPE (parms), 0);
! 727: dbxout_finish_symbol ();
! 728: }
! 729: else if (GET_CODE (DECL_RTL (parms)) == MEM
! 730: && XEXP (DECL_RTL (parms), 0) != const0_rtx)
! 731: {
! 732: current_sym_code = N_LSYM;
! 733: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
! 734: We want the value of that CONST_INT. */
! 735: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
! 736: current_sym_addr = 0;
! 737: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
! 738:
! 739: fprintf (asmfile, ".stabs \"%s:p",
! 740: IDENTIFIER_POINTER (DECL_NAME (parms)));
! 741:
! 742: /* This is the case where the parm is passed as an int or double
! 743: and it is converted to a char, short or float and stored back
! 744: in the parmlist. In this case, describe the parm
! 745: with the variable's declared type, and adjust the address
! 746: if the least significant bytes (which we are using) are not
! 747: the first ones. */
! 748: #ifdef BYTES_BIG_ENDIAN
! 749: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
! 750: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
! 751: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
! 752: #endif
! 753:
! 754: dbxout_type (TREE_TYPE (parms), 0);
! 755: dbxout_finish_symbol ();
! 756: }
! 757:
1.1 root 758: }
759: }
760:
761: /* Output definitions, referring to registers,
762: of all the parms in PARMS which are stored in registers during the function.
763: PARMS is a chain of PARM_DECL nodes. */
764:
765: static void
766: dbxout_reg_parms (parms)
767: tree parms;
768: {
769: while (parms)
770: {
1.1.1.2 ! root 771: /* Report parms that live in registers during the function. */
1.1 root 772: if (GET_CODE (DECL_RTL (parms)) == REG
1.1.1.2 ! root 773: && REGNO (DECL_RTL (parms)) >= 0
! 774: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
! 775: && DECL_OFFSET (parms) >= 0)
1.1 root 776: {
777: current_sym_code = N_RSYM;
778: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
779: current_sym_addr = 0;
780: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
781: fprintf (asmfile, ".stabs \"%s:r",
782: IDENTIFIER_POINTER (DECL_NAME (parms)));
783: dbxout_type (TREE_TYPE (parms), 0);
784: dbxout_finish_symbol ();
785: }
1.1.1.2 ! root 786: /* Report parms that live in memory but outside the parmlist. */
! 787: else if (GET_CODE (DECL_RTL (parms)) == MEM
! 788: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
! 789: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT)
! 790: {
! 791: int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
! 792: /* A parm declared char is really passed as an int,
! 793: so it occupies the least significant bytes.
! 794: On a big-endian machine those are not the low-numbered ones. */
! 795: #ifdef BYTES_BIG_ENDIAN
! 796: if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
! 797: offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
! 798: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
! 799: #endif
! 800: if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset)
! 801: {
! 802: current_sym_code = N_LSYM;
! 803: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
! 804: current_sym_addr = 0;
! 805: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
! 806: fprintf (asmfile, ".stabs \"%s:",
! 807: IDENTIFIER_POINTER (DECL_NAME (parms)));
! 808: dbxout_type (TREE_TYPE (parms), 0);
! 809: dbxout_finish_symbol ();
! 810: }
! 811: }
1.1 root 812: parms = TREE_CHAIN (parms);
813: }
814: }
815:
816: /* Given a chain of ..._TYPE nodes, all of which have names,
817: output definitions of those names, as typedefs. */
818:
819: void
820: dbxout_types (types)
821: register tree types;
822: {
823: while (types)
824: {
825: if (TYPE_NAME (types)
826: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL)
827: dbxout_type_def (types);
828: types = TREE_CHAIN (types);
829: }
830: }
831:
832: /* Output a definition of a typedef name.
1.1.1.2 ! root 833: It works much like any other kind of symbol definition.
! 834: Output nothing if TYPE's definition has been output already. */
1.1 root 835:
836: static void
837: dbxout_type_def (type)
838: tree type;
839: {
1.1.1.2 ! root 840: #if 0 /* Incorrect; causes some type NAMES not to be defined,
! 841: whose TYPES were defined already. */
! 842: if (TYPE_SYMTAB_ADDRESS (type) != 0
! 843: && typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED)
! 844: return;
! 845: #endif
! 846:
1.1 root 847: current_sym_code = N_LSYM;
848: current_sym_value = 0;
849: current_sym_addr = 0;
850: current_sym_nchars = 0;
851: current_sym_nchars
852: = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
853:
854: fprintf (asmfile, ".stabs \"%s:t",
855: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
856: dbxout_type (type, 1);
857: dbxout_finish_symbol ();
858: }
859:
860: /* Output the tags (struct, union and enum definitions with names) for a block,
861: given a list of them (a chain of TREE_LIST nodes) in TAGS.
862: We must check to include those that have been mentioned already with
863: only a cross-reference. */
864:
865: void
866: dbxout_tags (tags)
867: tree tags;
868: {
869: register tree link;
870: for (link = tags; link; link = TREE_CHAIN (link))
871: {
1.1.1.2 ! root 872: register tree type = TYPE_MAIN_VARIANT (TREE_VALUE (link));
1.1 root 873: if (TREE_PURPOSE (link) != 0
1.1.1.2 ! root 874: && ! TREE_ASM_WRITTEN (link)
1.1 root 875: && TYPE_SIZE (type) != 0)
876: {
1.1.1.2 ! root 877: TREE_ASM_WRITTEN (link) = 1;
1.1 root 878: current_sym_code = N_LSYM;
879: current_sym_value = 0;
880: current_sym_addr = 0;
881: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (link)));
882:
883: fprintf (asmfile, ".stabs \"%s:T",
884: IDENTIFIER_POINTER (TREE_PURPOSE (link)));
885: dbxout_type (type, 1);
886: dbxout_finish_symbol ();
887: }
888: }
889: }
890:
891: /* Output everything about a symbol block (that is to say, a LET_STMT node
892: that represents a scope level),
893: including recursive output of contained blocks.
894:
895: STMT is the LET_STMT node.
896: DEPTH is its depth within containing symbol blocks.
897: ARGS is usually zero; but for the outermost block of the
898: body of a function, it is a chain of PARM_DECLs for the function parameters.
899: We output definitions of all the register parms
900: as if they were local variables of that block.
901:
902: Actually, STMT may be several statements chained together.
903: We handle them all in sequence. */
904:
905: static void
906: dbxout_block (stmt, depth, args)
907: register tree stmt;
908: int depth;
1.1.1.2 ! root 909: tree args;
1.1 root 910: {
911: int blocknum;
912:
913: while (stmt)
914: {
915: switch (TREE_CODE (stmt))
916: {
917: case COMPOUND_STMT:
918: case LOOP_STMT:
919: dbxout_block (STMT_BODY (stmt), depth, 0);
920: break;
921:
922: case IF_STMT:
923: dbxout_block (STMT_THEN (stmt), depth, 0);
924: dbxout_block (STMT_ELSE (stmt), depth, 0);
925: break;
926:
927: case LET_STMT:
928: /* In dbx format, the syms of a block come before the N_LBRAC. */
929: dbxout_tags (STMT_TYPE_TAGS (stmt));
1.1.1.2 ! root 930: dbxout_syms (STMT_VARS (stmt));
1.1 root 931: if (args)
932: dbxout_reg_parms (args);
933:
934: /* Now output an N_LBRAC symbol to represent the beginning of
935: the block. Use the block's tree-walk order to generate
936: the assembler symbols LBBn and LBEn
937: that final will define around the code in this block. */
938: if (depth > 0)
939: {
940: blocknum = next_block_number++;
941: fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum);
942: }
943:
944: /* Output the interior of the block. */
945: dbxout_block (STMT_BODY (stmt), depth + 1, 0);
946:
947: /* Refer to the marker for the end of the block. */
948: if (depth > 0)
949: fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum);
950: }
951: stmt = TREE_CHAIN (stmt);
952: }
953: }
954:
955: /* Output dbx data for a function definition.
956: This includes a definition of the function name itself (a symbol),
957: definitions of the parameters (locating them in the parameter list)
958: and then output the block that makes up the function's body
959: (including all the auto variables of the function). */
960:
961: void
962: dbxout_function (decl)
963: tree decl;
964: {
965: dbxout_symbol (decl, 0);
966: dbxout_parms (DECL_ARGUMENTS (decl));
967: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
968: }
1.1.1.2 ! root 969:
! 970: #else /* NO_DBX_FORMAT */
! 971:
! 972: void
! 973: dbxout_init (asm_file, input_file_name)
! 974: FILE *asm_file;
! 975: char *input_file_name;
! 976: {}
! 977:
! 978: void
! 979: dbxout_symbol (decl, local)
! 980: tree decl;
! 981: int local;
! 982: {}
! 983:
! 984: void
! 985: dbxout_types (types)
! 986: register tree types;
! 987: {}
! 988:
! 989: void
! 990: dbxout_tags (tags)
! 991: tree tags;
! 992: {}
! 993:
! 994: void
! 995: dbxout_function (decl)
! 996: tree decl;
! 997: {}
! 998:
! 999: #endif /* NO_DBX_FORMAT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.