OSDN Git Service

Fix mips64vr4100-elf build failure.
[pf3gnuchains/gcc-fork.git] / gcc / xcoffout.c
1 /* Output xcoff-format symbol table information from GNU compiler.
2    Copyright (C) 1992, 1994, 1995, 1997 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, 59 Temple Place - Suite 330,
19 Boston, 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 "system.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 (HAVE_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
54 static int xcoff_begin_function_line = -1;
55 static int xcoff_inlining = 0;
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 static 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;
74
75 /* Last source file name mentioned in a NOTE insn.  */
76
77 char *xcoff_lastfile;
78 \f
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
115 static void assign_type_number          PROTO((tree, char *, int));
116 static void xcoffout_block              PROTO((tree, int, tree));
117 \f
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
123 static void
124 assign_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
143 void
144 xcoff_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
183 int
184 stab_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 \f
321 /* Output debugging info to FILE to switch to sourcefile FILENAME.
322    INLINE_P is true if this is from an inlined function.  */
323
324 void
325 xcoffout_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
358 void
359 xcoffout_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 \f
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
375 static int do_block = 0;
376
377 static int next_block_number;
378
379 static void
380 xcoffout_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
423 void
424 xcoffout_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
444 void
445 xcoffout_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
457 void
458 xcoffout_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
493 void
494 xcoffout_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
506 void
507 xcoffout_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
517 void
518 xcoffout_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 */