|
|
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: /* Line number of beginning of current function, minus one.
53: Negative means not in a function or not using xcoff. */
54:
55: int xcoff_begin_function_line = -1;
56:
57: /* Name of the current include file. */
58:
59: char *xcoff_current_include_file;
60:
61: /* Name of the current function file. This is the file the `.bf' is
62: emitted from. In case a line is emitted from a different file,
63: (by including that file of course), then the line number will be
64: absolute. */
65:
66: char *xcoff_current_function_file;
67:
68: /* Names of bss and data sections. These should be unique names for each
69: compilation unit. */
70:
71: char *xcoff_bss_section_name;
72: char *xcoff_private_data_section_name;
73: char *xcoff_read_only_section_name;
1.1.1.5 ! root 74:
! 75: /* Last source file name mentioned in a NOTE insn. */
! 76:
! 77: char *xcoff_lastfile;
1.1 root 78:
79: /* Macro definitions used below. */
1.1.1.5 ! root 80:
! 81: #define ABS_OR_RELATIVE_LINENO(LINENO) \
! 82: (xcoff_current_include_file ? (LINENO) : (LINENO) - xcoff_begin_function_line)
! 83:
! 84: /* Output source line numbers via ".line" rather than ".stabd". */
! 85: #define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM) \
! 86: do { \
! 87: if (xcoff_begin_function_line >= 0) \
! 88: fprintf (FILE, "\t.line\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)); \
! 89: } while (0)
1.1 root 90:
91: #define ASM_OUTPUT_LFB(FILE,LINENUM) \
92: { \
93: if (xcoff_begin_function_line == -1) \
94: { \
95: xcoff_begin_function_line = (LINENUM) - 1;\
96: fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \
97: } \
98: xcoff_current_function_file \
99: = (xcoff_current_include_file \
100: ? xcoff_current_include_file : main_input_filename); \
101: }
102:
103: #define ASM_OUTPUT_LFE(FILE,LINENUM) \
104: do { \
1.1.1.5 ! root 105: fprintf (FILE, "\t.ef\t%d\n", (LINENUM)); \
1.1 root 106: xcoff_begin_function_line = -1; \
107: } while (0)
108:
109: #define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \
1.1.1.5 ! root 110: fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
1.1 root 111:
112: #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
1.1.1.5 ! root 113: fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
1.1 root 114:
115: /* Support routines for XCOFF debugging info. */
116:
117: /* Assign NUMBER as the stabx type number for the type described by NAME.
118: Search all decls in the list SYMS to find the type NAME. */
119:
120: static void
121: assign_type_number (syms, name, number)
122: tree syms;
123: char *name;
124: int number;
125: {
126: tree decl;
127:
128: for (decl = syms; decl; decl = TREE_CHAIN (decl))
1.1.1.3 root 129: if (DECL_NAME (decl)
130: && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0)
1.1 root 131: {
132: TREE_ASM_WRITTEN (decl) = 1;
133: TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number;
134: }
135: }
136:
137: /* Setup gcc primitive types to use the XCOFF built-in type numbers where
138: possible. */
139:
140: void
141: xcoff_output_standard_types (syms)
142: tree syms;
143: {
144: /* Handle built-in C types here. */
145:
146: assign_type_number (syms, "int", -1);
147: assign_type_number (syms, "char", -2);
148: assign_type_number (syms, "short int", -3);
149: assign_type_number (syms, "long int", -4);
150: assign_type_number (syms, "unsigned char", -5);
151: assign_type_number (syms, "signed char", -6);
152: assign_type_number (syms, "short unsigned int", -7);
153: assign_type_number (syms, "unsigned int", -8);
154: /* No such type "unsigned". */
155: assign_type_number (syms, "long unsigned int", -10);
156: assign_type_number (syms, "void", -11);
157: assign_type_number (syms, "float", -12);
158: assign_type_number (syms, "double", -13);
159: assign_type_number (syms, "long double", -14);
160: /* Pascal and Fortran types run from -15 to -29. */
161: /* No such type "wchar". */
162:
163: /* "long long int", and "long long unsigned int", are not handled here,
164: because there are no predefined types that match them. */
165:
166: /* ??? Should also handle built-in C++ and Obj-C types. There perhaps
167: aren't any that C doesn't already have. */
168: }
169:
170: /* Print an error message for unrecognized stab codes. */
171:
172: #define UNKNOWN_STAB(STR) \
173: do { \
174: fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \
175: fflush (stderr); \
176: } while (0)
177:
178: /* Conversion routine from BSD stabs to AIX storage classes. */
179:
180: int
181: stab_to_sclass (stab)
182: int stab;
183: {
184: switch (stab)
185: {
186: case N_GSYM:
187: return C_GSYM;
188:
189: case N_FNAME:
190: UNKNOWN_STAB ("N_FNAME");
191: abort();
192:
193: case N_FUN:
194: return C_FUN;
195:
196: case N_STSYM:
197: case N_LCSYM:
198: return C_STSYM;
199:
1.1.1.4 root 200: #ifdef N_MAIN
1.1 root 201: case N_MAIN:
202: UNKNOWN_STAB ("N_MAIN");
203: abort ();
1.1.1.4 root 204: #endif
1.1 root 205:
206: case N_RSYM:
207: return C_RSYM;
208:
209: case N_SSYM:
210: UNKNOWN_STAB ("N_SSYM");
211: abort ();
212:
213: case N_RPSYM:
214: return C_RPSYM;
215:
216: case N_PSYM:
217: return C_PSYM;
218: case N_LSYM:
219: return C_LSYM;
220: case N_DECL:
221: return C_DECL;
222: case N_ENTRY:
223: return C_ENTRY;
224:
225: case N_SO:
226: UNKNOWN_STAB ("N_SO");
227: abort ();
228:
229: case N_SOL:
230: UNKNOWN_STAB ("N_SOL");
231: abort ();
232:
233: case N_SLINE:
234: UNKNOWN_STAB ("N_SLINE");
235: abort ();
236:
1.1.1.4 root 237: #ifdef N_DSLINE
1.1 root 238: case N_DSLINE:
239: UNKNOWN_STAB ("N_DSLINE");
240: abort ();
1.1.1.4 root 241: #endif
1.1 root 242:
1.1.1.4 root 243: #ifdef N_BSLINE
1.1 root 244: case N_BSLINE:
245: UNKNOWN_STAB ("N_BSLINE");
246: abort ();
1.1.1.4 root 247: #endif
1.1 root 248: #if 0
249: /* This has the same value as N_BSLINE. */
250: case N_BROWS:
251: UNKNOWN_STAB ("N_BROWS");
252: abort ();
253: #endif
254:
1.1.1.4 root 255: #ifdef N_BINCL
1.1 root 256: case N_BINCL:
257: UNKNOWN_STAB ("N_BINCL");
258: abort ();
1.1.1.4 root 259: #endif
1.1 root 260:
1.1.1.4 root 261: #ifdef N_EINCL
1.1 root 262: case N_EINCL:
263: UNKNOWN_STAB ("N_EINCL");
264: abort ();
1.1.1.4 root 265: #endif
1.1 root 266:
1.1.1.4 root 267: #ifdef N_EXCL
1.1 root 268: case N_EXCL:
269: UNKNOWN_STAB ("N_EXCL");
270: abort ();
1.1.1.4 root 271: #endif
1.1 root 272:
273: case N_LBRAC:
274: UNKNOWN_STAB ("N_LBRAC");
275: abort ();
276:
277: case N_RBRAC:
278: UNKNOWN_STAB ("N_RBRAC");
279: abort ();
280:
281: case N_BCOMM:
282: return C_BCOMM;
283: case N_ECOMM:
284: return C_ECOMM;
285: case N_ECOML:
286: return C_ECOML;
287:
288: case N_LENG:
289: UNKNOWN_STAB ("N_LENG");
290: abort ();
291:
292: case N_PC:
293: UNKNOWN_STAB ("N_PC");
294: abort ();
295:
1.1.1.4 root 296: #ifdef N_M2C
1.1 root 297: case N_M2C:
298: UNKNOWN_STAB ("N_M2C");
299: abort ();
1.1.1.4 root 300: #endif
1.1 root 301:
1.1.1.4 root 302: #ifdef N_SCOPE
1.1 root 303: case N_SCOPE:
304: UNKNOWN_STAB ("N_SCOPE");
305: abort ();
1.1.1.4 root 306: #endif
1.1 root 307:
308: case N_CATCH:
309: UNKNOWN_STAB ("N_CATCH");
310: abort ();
311:
312: default:
313: UNKNOWN_STAB ("default");
314: abort ();
315: }
316: }
1.1.1.5 ! root 317:
1.1 root 318: /* In XCOFF, we have to have this .bf before the function prologue.
319: Rely on the value of `dbx_begin_function_line' not to duplicate .bf. */
320:
321: void
322: xcoffout_output_first_source_line (file, last_linenum)
323: FILE *file;
324: int last_linenum;
325: {
326: ASM_OUTPUT_LFB (file, last_linenum);
327: dbxout_parms (DECL_ARGUMENTS (current_function_decl));
328: ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
329: }
330:
1.1.1.5 ! root 331: /* Output debugging info to FILE to switch to sourcefile FILENAME.
! 332: INLINE_P is true if this is from an inlined function. */
! 333:
! 334: void
! 335: xcoffout_source_file (file, filename, inline_p)
! 336: FILE *file;
! 337: char *filename;
! 338: int inline_p;
! 339: {
! 340: if (filename
! 341: && (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile)
! 342: || (inline_p && ! xcoff_current_include_file)
! 343: || (! inline_p && xcoff_current_include_file)))
! 344: {
! 345: if (xcoff_current_include_file)
! 346: {
! 347: fprintf (file, "\t.ei\t");
! 348: output_quoted_string (file, xcoff_current_include_file);
! 349: fprintf (file, "\n");
! 350: xcoff_current_include_file = NULL;
! 351: }
! 352: if (strcmp (main_input_filename, filename) || inline_p)
! 353: {
! 354: fprintf (file, "\t.bi\t");
! 355: output_quoted_string (file, filename);
! 356: fprintf (file, "\n");
! 357: xcoff_current_include_file = filename;
! 358: }
! 359:
! 360: xcoff_lastfile = filename;
! 361: }
! 362: }
! 363:
! 364: /* Output a line number symbol entry into output stream FILE,
! 365: for source file FILENAME and line number NOTE. */
! 366:
! 367: void
! 368: xcoffout_source_line (file, filename, note)
! 369: FILE *file;
! 370: char *filename;
! 371: rtx note;
! 372: {
! 373: xcoffout_source_file (file, filename, RTX_INTEGRATED_P (note));
! 374:
! 375: ASM_OUTPUT_SOURCE_LINE (file, NOTE_LINE_NUMBER (note));
! 376: }
! 377:
1.1 root 378: /* Output the symbols defined in block number DO_BLOCK.
379: Set NEXT_BLOCK_NUMBER to 0 before calling.
380:
381: This function works by walking the tree structure of blocks,
382: counting blocks until it finds the desired block. */
383:
384: static int do_block = 0;
385:
386: static int next_block_number;
387:
388: static void
389: xcoffout_block (block, depth, args)
390: register tree block;
391: int depth;
392: tree args;
393: {
394: while (block)
395: {
396: /* Ignore blocks never expanded or otherwise marked as real. */
397: if (TREE_USED (block))
398: {
399: /* When we reach the specified block, output its symbols. */
400: if (next_block_number == do_block)
401: {
402: /* Output the syms of the block. */
403: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
404: dbxout_syms (BLOCK_VARS (block));
405: if (args)
406: dbxout_reg_parms (args);
407:
408: /* We are now done with the block. Don't go to inner blocks. */
409: return;
410: }
411: /* If we are past the specified block, stop the scan. */
412: else if (next_block_number >= do_block)
413: return;
414:
415: next_block_number++;
416:
417: /* Output the subblocks. */
1.1.1.3 root 418: xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
1.1 root 419: }
420: block = BLOCK_CHAIN (block);
421: }
422: }
423:
424: /* Describe the beginning of an internal block within a function.
425: Also output descriptions of variables defined in this block.
426:
427: N is the number of the block, by order of beginning, counting from 1,
428: and not counting the outermost (function top-level) block.
429: The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
430: if the count starts at 0 for the outermost one. */
431:
432: void
433: xcoffout_begin_block (file, line, n)
434: FILE *file;
435: int line;
436: int n;
437: {
438: tree decl = current_function_decl;
439:
1.1.1.5 ! root 440:
! 441: /* The IBM AIX compiler does not emit a .bb for the function level scope,
! 442: so we avoid it here also. */
! 443: if (n != 1)
! 444: ASM_OUTPUT_LBB (file, line, n);
1.1 root 445:
446: do_block = n;
447: next_block_number = 0;
448: xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
449: }
450:
451: /* Describe the end line-number of an internal block within a function. */
452:
453: void
454: xcoffout_end_block (file, line, n)
455: FILE *file;
456: int line;
457: int n;
458: {
1.1.1.5 ! root 459: if (n != 1)
! 460: ASM_OUTPUT_LBE (file, line, n);
1.1 root 461: }
462:
1.1.1.2 root 463: /* Called at beginning of function (before prologue).
464: Declare function as needed for debugging. */
465:
466: void
467: xcoffout_declare_function (file, decl, name)
468: FILE *file;
469: tree decl;
470: char *name;
471: {
472: char *n = name;
473: int i;
474:
475: for (i = 0; name[i]; ++i)
476: {
477: if (name[i] == '[')
478: {
1.1.1.3 root 479: n = (char *) alloca (i + 1);
1.1.1.2 root 480: strncpy (n, name, i);
481: n[i] = '\0';
482: break;
483: }
484: }
485:
1.1.1.4 root 486: /* Any pending .bi or .ei must occur before the .function psuedo op.
487: Otherwise debuggers will think that the function is in the previous
488: file and/or at the wrong line number. */
1.1.1.5 ! root 489: xcoffout_source_file (file, DECL_SOURCE_FILE (decl), 0);
1.1.1.2 root 490: dbxout_symbol (decl, 0);
491: fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n);
492: }
493:
1.1 root 494: /* Called at beginning of function body (after prologue).
495: Record the function's starting line number, so we can output
496: relative line numbers for the other lines.
497: Record the file name that this function is contained in. */
498:
499: void
500: xcoffout_begin_function (file, last_linenum)
501: FILE *file;
502: int last_linenum;
503: {
504: ASM_OUTPUT_LFB (file, last_linenum);
505: }
506:
507: /* Called at end of function (before epilogue).
508: Describe end of outermost block. */
509:
510: void
511: xcoffout_end_function (file, last_linenum)
512: FILE *file;
513: int last_linenum;
514: {
515: ASM_OUTPUT_LFE (file, last_linenum);
516: }
517:
518: /* Output xcoff info for the absolute end of a function.
519: Called after the epilogue is output. */
520:
521: void
522: xcoffout_end_epilogue (file)
523: FILE *file;
524: {
525: /* We need to pass the correct function size to .function, otherwise,
526: the xas assembler can't figure out the correct size for the function
527: aux entry. So, we emit a label after the last instruction which can
1.1.1.2 root 528: be used by the .function pseudo op to calculate the function size. */
1.1 root 529:
530: char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
531: if (*fname == '*')
532: ++fname;
1.1.1.2 root 533: fprintf (file, "FE..");
1.1 root 534: ASM_OUTPUT_LABEL (file, fname);
535: }
536: #endif /* XCOFF_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.