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

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