|
|
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))
1.1.1.3 ! root 137: if (DECL_NAME (decl)
! 138: && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0)
1.1 root 139: {
140: TREE_ASM_WRITTEN (decl) = 1;
141: TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number;
142: }
143: }
144:
145: /* Setup gcc primitive types to use the XCOFF built-in type numbers where
146: possible. */
147:
148: void
149: xcoff_output_standard_types (syms)
150: tree syms;
151: {
152: /* Handle built-in C types here. */
153:
154: assign_type_number (syms, "int", -1);
155: assign_type_number (syms, "char", -2);
156: assign_type_number (syms, "short int", -3);
157: assign_type_number (syms, "long int", -4);
158: assign_type_number (syms, "unsigned char", -5);
159: assign_type_number (syms, "signed char", -6);
160: assign_type_number (syms, "short unsigned int", -7);
161: assign_type_number (syms, "unsigned int", -8);
162: /* No such type "unsigned". */
163: assign_type_number (syms, "long unsigned int", -10);
164: assign_type_number (syms, "void", -11);
165: assign_type_number (syms, "float", -12);
166: assign_type_number (syms, "double", -13);
167: assign_type_number (syms, "long double", -14);
168: /* Pascal and Fortran types run from -15 to -29. */
169: /* No such type "wchar". */
170:
171: /* "long long int", and "long long unsigned int", are not handled here,
172: because there are no predefined types that match them. */
173:
174: /* ??? Should also handle built-in C++ and Obj-C types. There perhaps
175: aren't any that C doesn't already have. */
176: }
177:
178: /* Print an error message for unrecognized stab codes. */
179:
180: #define UNKNOWN_STAB(STR) \
181: do { \
182: fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \
183: fflush (stderr); \
184: } while (0)
185:
186: /* Conversion routine from BSD stabs to AIX storage classes. */
187:
188: int
189: stab_to_sclass (stab)
190: int stab;
191: {
192: switch (stab)
193: {
194: case N_GSYM:
195: return C_GSYM;
196:
197: case N_FNAME:
198: UNKNOWN_STAB ("N_FNAME");
199: abort();
200:
201: case N_FUN:
202: return C_FUN;
203:
204: case N_STSYM:
205: case N_LCSYM:
206: return C_STSYM;
207:
208: case N_MAIN:
209: UNKNOWN_STAB ("N_MAIN");
210: abort ();
211:
212: case N_RSYM:
213: return C_RSYM;
214:
215: case N_SSYM:
216: UNKNOWN_STAB ("N_SSYM");
217: abort ();
218:
219: case N_RPSYM:
220: return C_RPSYM;
221:
222: case N_PSYM:
223: return C_PSYM;
224: case N_LSYM:
225: return C_LSYM;
226: case N_DECL:
227: return C_DECL;
228: case N_ENTRY:
229: return C_ENTRY;
230:
231: case N_SO:
232: UNKNOWN_STAB ("N_SO");
233: abort ();
234:
235: case N_SOL:
236: UNKNOWN_STAB ("N_SOL");
237: abort ();
238:
239: case N_SLINE:
240: UNKNOWN_STAB ("N_SLINE");
241: abort ();
242:
243: case N_DSLINE:
244: UNKNOWN_STAB ("N_DSLINE");
245: abort ();
246:
247: case N_BSLINE:
248: UNKNOWN_STAB ("N_BSLINE");
249: abort ();
250: #if 0
251: /* This has the same value as N_BSLINE. */
252: case N_BROWS:
253: UNKNOWN_STAB ("N_BROWS");
254: abort ();
255: #endif
256:
257: case N_BINCL:
258: UNKNOWN_STAB ("N_BINCL");
259: abort ();
260:
261: case N_EINCL:
262: UNKNOWN_STAB ("N_EINCL");
263: abort ();
264:
265: case N_EXCL:
266: UNKNOWN_STAB ("N_EXCL");
267: abort ();
268:
269: case N_LBRAC:
270: UNKNOWN_STAB ("N_LBRAC");
271: abort ();
272:
273: case N_RBRAC:
274: UNKNOWN_STAB ("N_RBRAC");
275: abort ();
276:
277: case N_BCOMM:
278: return C_BCOMM;
279: case N_ECOMM:
280: return C_ECOMM;
281: case N_ECOML:
282: return C_ECOML;
283:
284: case N_LENG:
285: UNKNOWN_STAB ("N_LENG");
286: abort ();
287:
288: case N_PC:
289: UNKNOWN_STAB ("N_PC");
290: abort ();
291:
292: case N_M2C:
293: UNKNOWN_STAB ("N_M2C");
294: abort ();
295:
296: case N_SCOPE:
297: UNKNOWN_STAB ("N_SCOPE");
298: abort ();
299:
300: case N_CATCH:
301: UNKNOWN_STAB ("N_CATCH");
302: abort ();
303:
304: default:
305: UNKNOWN_STAB ("default");
306: abort ();
307: }
308: }
309:
310: /* In XCOFF, we have to have this .bf before the function prologue.
311: Rely on the value of `dbx_begin_function_line' not to duplicate .bf. */
312:
313: void
314: xcoffout_output_first_source_line (file, last_linenum)
315: FILE *file;
316: int last_linenum;
317: {
318: ASM_OUTPUT_LFB (file, last_linenum);
319: dbxout_parms (DECL_ARGUMENTS (current_function_decl));
320: ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
321: }
322:
323: /* Output the symbols defined in block number DO_BLOCK.
324: Set NEXT_BLOCK_NUMBER to 0 before calling.
325:
326: This function works by walking the tree structure of blocks,
327: counting blocks until it finds the desired block. */
328:
329: static int do_block = 0;
330:
331: static int next_block_number;
332:
333: static void
334: xcoffout_block (block, depth, args)
335: register tree block;
336: int depth;
337: tree args;
338: {
339: while (block)
340: {
341: /* Ignore blocks never expanded or otherwise marked as real. */
342: if (TREE_USED (block))
343: {
344: /* When we reach the specified block, output its symbols. */
345: if (next_block_number == do_block)
346: {
347: /* Output the syms of the block. */
348: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
349: dbxout_syms (BLOCK_VARS (block));
350: if (args)
351: dbxout_reg_parms (args);
352:
353: /* We are now done with the block. Don't go to inner blocks. */
354: return;
355: }
356: /* If we are past the specified block, stop the scan. */
357: else if (next_block_number >= do_block)
358: return;
359:
360: next_block_number++;
361:
362: /* Output the subblocks. */
1.1.1.3 ! root 363: xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
1.1 root 364: }
365: block = BLOCK_CHAIN (block);
366: }
367: }
368:
369: /* Describe the beginning of an internal block within a function.
370: Also output descriptions of variables defined in this block.
371:
372: N is the number of the block, by order of beginning, counting from 1,
373: and not counting the outermost (function top-level) block.
374: The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
375: if the count starts at 0 for the outermost one. */
376:
377: void
378: xcoffout_begin_block (file, line, n)
379: FILE *file;
380: int line;
381: int n;
382: {
383: tree decl = current_function_decl;
384:
385: ASM_OUTPUT_LBB (file, line, n);
386:
387: do_block = n;
388: next_block_number = 0;
389: xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
390: }
391:
392: /* Describe the end line-number of an internal block within a function. */
393:
394: void
395: xcoffout_end_block (file, line, n)
396: FILE *file;
397: int line;
398: int n;
399: {
400: ASM_OUTPUT_LBE (file, line, n);
401: }
402:
1.1.1.2 root 403: /* Called at beginning of function (before prologue).
404: Declare function as needed for debugging. */
405:
406: void
407: xcoffout_declare_function (file, decl, name)
408: FILE *file;
409: tree decl;
410: char *name;
411: {
412: char *n = name;
413: int i;
414:
415: for (i = 0; name[i]; ++i)
416: {
417: if (name[i] == '[')
418: {
1.1.1.3 ! root 419: n = (char *) alloca (i + 1);
1.1.1.2 root 420: strncpy (n, name, i);
421: n[i] = '\0';
422: break;
423: }
424: }
425:
426: dbxout_symbol (decl, 0);
427: fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n);
428: }
429:
1.1 root 430: /* Called at beginning of function body (after prologue).
431: Record the function's starting line number, so we can output
432: relative line numbers for the other lines.
433: Record the file name that this function is contained in. */
434:
435: void
436: xcoffout_begin_function (file, last_linenum)
437: FILE *file;
438: int last_linenum;
439: {
440: ASM_OUTPUT_LFB (file, last_linenum);
441: }
442:
443: /* Called at end of function (before epilogue).
444: Describe end of outermost block. */
445:
446: void
447: xcoffout_end_function (file, last_linenum)
448: FILE *file;
449: int last_linenum;
450: {
451: ASM_OUTPUT_LFE (file, last_linenum);
452: }
453:
454: /* Output xcoff info for the absolute end of a function.
455: Called after the epilogue is output. */
456:
457: void
458: xcoffout_end_epilogue (file)
459: FILE *file;
460: {
461: /* We need to pass the correct function size to .function, otherwise,
462: the xas assembler can't figure out the correct size for the function
463: aux entry. So, we emit a label after the last instruction which can
1.1.1.2 root 464: be used by the .function pseudo op to calculate the function size. */
1.1 root 465:
466: char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
467: if (*fname == '*')
468: ++fname;
1.1.1.2 root 469: fprintf (file, "FE..");
1.1 root 470: ASM_OUTPUT_LABEL (file, fname);
471: }
472: #endif /* XCOFF_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.