|
|
1.1 root 1: /* Output xcoff-format symbol table information from GNU compiler.
2: Copyright (C) 1992 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20:
21: /* Output xcoff-format symbol table data. The main functionality is contained
22: in dbxout.c. This file implements the sdbout-like parts of the xcoff
23: interface. Many functions are very similar to their counterparts in
24: sdbout.c. */
25:
26: /* Include this first, because it may define MIN and MAX. */
27: #include <stdio.h>
28:
29: #include "config.h"
30: #include "tree.h"
31: #include "rtl.h"
32: #include "flags.h"
33:
34: #ifdef XCOFF_DEBUGGING_INFO
35:
36: /* This defines the C_* storage classes. */
37: #include <dbxstclass.h>
38:
39: #include "xcoffout.h"
40:
41: #if defined (USG) || defined (NO_STAB_H)
42: #include "gstab.h"
43: #else
44: #include <stab.h>
45:
46: /* This is a GNU extension we need to reference in this file. */
47: #ifndef N_CATCH
48: #define N_CATCH 0x54
49: #endif
50: #endif
51:
52: /* These are GNU extensions we need to reference in this file. */
53: #ifndef N_DSLINE
54: #define N_DSLINE 0x46
55: #endif
56: #ifndef N_BSLINE
57: #define N_BSLINE 0x48
58: #endif
59:
60: /* Line number of beginning of current function, minus one.
61: Negative means not in a function or not using xcoff. */
62:
63: int xcoff_begin_function_line = -1;
64:
65: /* Name of the current include file. */
66:
67: char *xcoff_current_include_file;
68:
69: /* Name of the current function file. This is the file the `.bf' is
70: emitted from. In case a line is emitted from a different file,
71: (by including that file of course), then the line number will be
72: absolute. */
73:
74: char *xcoff_current_function_file;
75:
76: /* Names of bss and data sections. These should be unique names for each
77: compilation unit. */
78:
79: char *xcoff_bss_section_name;
80: char *xcoff_private_data_section_name;
81: char *xcoff_read_only_section_name;
82:
83: /* Macro definitions used below. */
84: /* Ensure we don't output a negative line number. */
85: #define MAKE_LINE_SAFE(LINE) \
86: if (LINE <= xcoff_begin_function_line) \
87: LINE = xcoff_begin_function_line + 1 \
88:
89: #define ASM_OUTPUT_LFB(FILE,LINENUM) \
90: { \
91: if (xcoff_begin_function_line == -1) \
92: { \
93: xcoff_begin_function_line = (LINENUM) - 1;\
94: fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \
95: } \
96: xcoff_current_function_file \
97: = (xcoff_current_include_file \
98: ? xcoff_current_include_file : main_input_filename); \
99: }
100:
101: #define ASM_OUTPUT_LFE(FILE,LINENUM) \
102: do { \
103: int linenum = LINENUM; \
104: MAKE_LINE_SAFE (linenum); \
105: fprintf (FILE, "\t.ef\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
106: xcoff_begin_function_line = -1; \
107: } while (0)
108:
109: #define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \
110: do { \
111: int linenum = LINENUM; \
112: MAKE_LINE_SAFE (linenum); \
113: fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
114: } while (0)
115:
116: #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
117: do { \
118: int linenum = LINENUM; \
119: MAKE_LINE_SAFE (linenum); \
120: fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
121: } while (0)
122:
123: /* Support routines for XCOFF debugging info. */
124:
125: /* Assign NUMBER as the stabx type number for the type described by NAME.
126: Search all decls in the list SYMS to find the type NAME. */
127:
128: static void
129: assign_type_number (syms, name, number)
130: tree syms;
131: char *name;
132: int number;
133: {
134: tree decl;
135:
136: for (decl = syms; decl; decl = TREE_CHAIN (decl))
137: if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name))
138: {
139: TREE_ASM_WRITTEN (decl) = 1;
140: TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number;
141: }
142: }
143:
144: /* Setup gcc primitive types to use the XCOFF built-in type numbers where
145: possible. */
146:
147: void
148: xcoff_output_standard_types (syms)
149: tree syms;
150: {
151: /* Handle built-in C types here. */
152:
153: assign_type_number (syms, "int", -1);
154: assign_type_number (syms, "char", -2);
155: assign_type_number (syms, "short int", -3);
156: assign_type_number (syms, "long int", -4);
157: assign_type_number (syms, "unsigned char", -5);
158: assign_type_number (syms, "signed char", -6);
159: assign_type_number (syms, "short unsigned int", -7);
160: assign_type_number (syms, "unsigned int", -8);
161: /* No such type "unsigned". */
162: assign_type_number (syms, "long unsigned int", -10);
163: assign_type_number (syms, "void", -11);
164: assign_type_number (syms, "float", -12);
165: assign_type_number (syms, "double", -13);
166: assign_type_number (syms, "long double", -14);
167: /* Pascal and Fortran types run from -15 to -29. */
168: /* No such type "wchar". */
169:
170: /* "long long int", and "long long unsigned int", are not handled here,
171: because there are no predefined types that match them. */
172:
173: /* ??? Should also handle built-in C++ and Obj-C types. There perhaps
174: aren't any that C doesn't already have. */
175: }
176:
177: /* Print an error message for unrecognized stab codes. */
178:
179: #define UNKNOWN_STAB(STR) \
180: do { \
181: fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \
182: fflush (stderr); \
183: } while (0)
184:
185: /* Conversion routine from BSD stabs to AIX storage classes. */
186:
187: int
188: stab_to_sclass (stab)
189: int stab;
190: {
191: switch (stab)
192: {
193: case N_GSYM:
194: return C_GSYM;
195:
196: case N_FNAME:
197: UNKNOWN_STAB ("N_FNAME");
198: abort();
199:
200: case N_FUN:
201: return C_FUN;
202:
203: case N_STSYM:
204: case N_LCSYM:
205: return C_STSYM;
206:
207: case N_MAIN:
208: UNKNOWN_STAB ("N_MAIN");
209: abort ();
210:
211: case N_RSYM:
212: return C_RSYM;
213:
214: case N_SSYM:
215: UNKNOWN_STAB ("N_SSYM");
216: abort ();
217:
218: case N_RPSYM:
219: return C_RPSYM;
220:
221: case N_PSYM:
222: return C_PSYM;
223: case N_LSYM:
224: return C_LSYM;
225: case N_DECL:
226: return C_DECL;
227: case N_ENTRY:
228: return C_ENTRY;
229:
230: case N_SO:
231: UNKNOWN_STAB ("N_SO");
232: abort ();
233:
234: case N_SOL:
235: UNKNOWN_STAB ("N_SOL");
236: abort ();
237:
238: case N_SLINE:
239: UNKNOWN_STAB ("N_SLINE");
240: abort ();
241:
242: case N_DSLINE:
243: UNKNOWN_STAB ("N_DSLINE");
244: abort ();
245:
246: case N_BSLINE:
247: UNKNOWN_STAB ("N_BSLINE");
248: abort ();
249: #if 0
250: /* This has the same value as N_BSLINE. */
251: case N_BROWS:
252: UNKNOWN_STAB ("N_BROWS");
253: abort ();
254: #endif
255:
256: case N_BINCL:
257: UNKNOWN_STAB ("N_BINCL");
258: abort ();
259:
260: case N_EINCL:
261: UNKNOWN_STAB ("N_EINCL");
262: abort ();
263:
264: case N_EXCL:
265: UNKNOWN_STAB ("N_EXCL");
266: abort ();
267:
268: case N_LBRAC:
269: UNKNOWN_STAB ("N_LBRAC");
270: abort ();
271:
272: case N_RBRAC:
273: UNKNOWN_STAB ("N_RBRAC");
274: abort ();
275:
276: case N_BCOMM:
277: return C_BCOMM;
278: case N_ECOMM:
279: return C_ECOMM;
280: case N_ECOML:
281: return C_ECOML;
282:
283: case N_LENG:
284: UNKNOWN_STAB ("N_LENG");
285: abort ();
286:
287: case N_PC:
288: UNKNOWN_STAB ("N_PC");
289: abort ();
290:
291: case N_M2C:
292: UNKNOWN_STAB ("N_M2C");
293: abort ();
294:
295: case N_SCOPE:
296: UNKNOWN_STAB ("N_SCOPE");
297: abort ();
298:
299: case N_CATCH:
300: UNKNOWN_STAB ("N_CATCH");
301: abort ();
302:
303: default:
304: UNKNOWN_STAB ("default");
305: abort ();
306: }
307: }
308:
309: /* In XCOFF, we have to have this .bf before the function prologue.
310: Rely on the value of `dbx_begin_function_line' not to duplicate .bf. */
311:
312: void
313: xcoffout_output_first_source_line (file, last_linenum)
314: FILE *file;
315: int last_linenum;
316: {
317: ASM_OUTPUT_LFB (file, last_linenum);
318: dbxout_parms (DECL_ARGUMENTS (current_function_decl));
319: ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
320: }
321:
322: /* Output the symbols defined in block number DO_BLOCK.
323: Set NEXT_BLOCK_NUMBER to 0 before calling.
324:
325: This function works by walking the tree structure of blocks,
326: counting blocks until it finds the desired block. */
327:
328: static int do_block = 0;
329:
330: static int next_block_number;
331:
332: static void
333: xcoffout_block (block, depth, args)
334: register tree block;
335: int depth;
336: tree args;
337: {
338: while (block)
339: {
340: /* Ignore blocks never expanded or otherwise marked as real. */
341: if (TREE_USED (block))
342: {
343: /* When we reach the specified block, output its symbols. */
344: if (next_block_number == do_block)
345: {
346: /* Output the syms of the block. */
347: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
348: dbxout_syms (BLOCK_VARS (block));
349: if (args)
350: dbxout_reg_parms (args);
351:
352: /* We are now done with the block. Don't go to inner blocks. */
353: return;
354: }
355: /* If we are past the specified block, stop the scan. */
356: else if (next_block_number >= do_block)
357: return;
358:
359: next_block_number++;
360:
361: /* Output the subblocks. */
362: xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, 0);
363: }
364: block = BLOCK_CHAIN (block);
365: }
366: }
367:
368: /* Describe the beginning of an internal block within a function.
369: Also output descriptions of variables defined in this block.
370:
371: N is the number of the block, by order of beginning, counting from 1,
372: and not counting the outermost (function top-level) block.
373: The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
374: if the count starts at 0 for the outermost one. */
375:
376: void
377: xcoffout_begin_block (file, line, n)
378: FILE *file;
379: int line;
380: int n;
381: {
382: tree decl = current_function_decl;
383:
384: ASM_OUTPUT_LBB (file, line, n);
385:
386: do_block = n;
387: next_block_number = 0;
388: xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
389: }
390:
391: /* Describe the end line-number of an internal block within a function. */
392:
393: void
394: xcoffout_end_block (file, line, n)
395: FILE *file;
396: int line;
397: int n;
398: {
399: ASM_OUTPUT_LBE (file, line, n);
400: }
401:
1.1.1.2 ! root 402: /* Called at beginning of function (before prologue).
! 403: Declare function as needed for debugging. */
! 404:
! 405: void
! 406: xcoffout_declare_function (file, decl, name)
! 407: FILE *file;
! 408: tree decl;
! 409: char *name;
! 410: {
! 411: char *n = name;
! 412: int i;
! 413:
! 414: for (i = 0; name[i]; ++i)
! 415: {
! 416: if (name[i] == '[')
! 417: {
! 418: n = alloca (i + 1);
! 419: strncpy (n, name, i);
! 420: n[i] = '\0';
! 421: break;
! 422: }
! 423: }
! 424:
! 425: dbxout_symbol (decl, 0);
! 426: fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n);
! 427: }
! 428:
1.1 root 429: /* Called at beginning of function body (after prologue).
430: Record the function's starting line number, so we can output
431: relative line numbers for the other lines.
432: Record the file name that this function is contained in. */
433:
434: void
435: xcoffout_begin_function (file, last_linenum)
436: FILE *file;
437: int last_linenum;
438: {
439: ASM_OUTPUT_LFB (file, last_linenum);
440: }
441:
442: /* Called at end of function (before epilogue).
443: Describe end of outermost block. */
444:
445: void
446: xcoffout_end_function (file, last_linenum)
447: FILE *file;
448: int last_linenum;
449: {
450: ASM_OUTPUT_LFE (file, last_linenum);
451: }
452:
453: /* Output xcoff info for the absolute end of a function.
454: Called after the epilogue is output. */
455:
456: void
457: xcoffout_end_epilogue (file)
458: FILE *file;
459: {
460: /* We need to pass the correct function size to .function, otherwise,
461: the xas assembler can't figure out the correct size for the function
462: aux entry. So, we emit a label after the last instruction which can
1.1.1.2 ! root 463: be used by the .function pseudo op to calculate the function size. */
1.1 root 464:
465: char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
466: if (*fname == '*')
467: ++fname;
1.1.1.2 ! root 468: fprintf (file, "FE..");
1.1 root 469: ASM_OUTPUT_LABEL (file, fname);
470: }
471: #endif /* XCOFF_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.