source: trunk/third/gcc/xcoffout.c @ 11288

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