OSDN Git Service

Rework specs to subtarget specs and EXTRA_SPECS
[pf3gnuchains/gcc-fork.git] / gcc / xcoffout.c
1 /* Output xcoff-format symbol table information from GNU compiler.
2    Copyright (C) 1992, 1994, 1995 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 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
56 static int xcoff_begin_function_line = -1;
57 static int xcoff_inlining = 0;
58
59 /* Name of the current include file.  */
60
61 char *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
68 static char *xcoff_current_function_file;
69
70 /* Names of bss and data sections.  These should be unique names for each
71    compilation unit.  */
72
73 char *xcoff_bss_section_name;
74 char *xcoff_private_data_section_name;
75 char *xcoff_read_only_section_name;
76
77 /* Last source file name mentioned in a NOTE insn.  */
78
79 char *xcoff_lastfile;
80 \f
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 \f
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
122 static void
123 assign_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
142 void
143 xcoff_output_standard_types (syms)
144      tree syms;
145 {
146   /* Handle built-in C types here.  */
147
148   assign_type_number (syms, "int", -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", -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
182 int
183 stab_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 \f
320 /* Output debugging info to FILE to switch to sourcefile FILENAME.
321    INLINE_P is true if this is from an inlined function.  */
322
323 void
324 xcoffout_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
357 void
358 xcoffout_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 \f
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
374 static int do_block = 0;
375
376 static int next_block_number;
377
378 static void
379 xcoffout_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
422 void
423 xcoffout_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
443 void
444 xcoffout_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
456 void
457 xcoffout_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
492 void
493 xcoffout_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
505 void
506 xcoffout_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
516 void
517 xcoffout_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 */