OSDN Git Service

(xcoff_lastfile): New variable.
[pf3gnuchains/gcc-fork.git] / gcc / xcoffout.c
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;
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_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)
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 \f
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))
129     if (DECL_NAME (decl)
130         && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0)
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
200 #ifdef N_MAIN
201     case N_MAIN:
202       UNKNOWN_STAB ("N_MAIN"); 
203       abort ();
204 #endif
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
237 #ifdef N_DSLINE
238     case N_DSLINE:
239       UNKNOWN_STAB ("N_DSLINE"); 
240       abort ();
241 #endif
242
243 #ifdef N_BSLINE
244     case N_BSLINE:
245       UNKNOWN_STAB ("N_BSLINE"); 
246       abort ();
247 #endif
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
255 #ifdef N_BINCL
256     case N_BINCL:
257       UNKNOWN_STAB ("N_BINCL"); 
258       abort ();
259 #endif
260
261 #ifdef N_EINCL
262     case N_EINCL:
263       UNKNOWN_STAB ("N_EINCL"); 
264       abort ();
265 #endif
266
267 #ifdef N_EXCL
268     case N_EXCL:
269       UNKNOWN_STAB ("N_EXCL"); 
270       abort ();
271 #endif
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
296 #ifdef N_M2C
297     case N_M2C:
298       UNKNOWN_STAB ("N_M2C"); 
299       abort ();
300 #endif
301
302 #ifdef N_SCOPE
303     case N_SCOPE:
304       UNKNOWN_STAB ("N_SCOPE"); 
305       abort ();
306 #endif
307
308     case N_CATCH:
309       UNKNOWN_STAB ("N_CATCH"); 
310       abort ();
311
312     default:
313       UNKNOWN_STAB ("default"); 
314       abort ();
315   }
316 }
317 \f
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
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 \f
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.  */
418           xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
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
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);
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 {
459   if (n != 1)
460     ASM_OUTPUT_LBE (file, line, n);
461 }
462
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         {
479           n = (char *) alloca (i + 1);
480           strncpy (n, name, i);
481           n[i] = '\0';
482           break;
483         }
484     }
485
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.  */
489   xcoffout_source_file (file, DECL_SOURCE_FILE (decl), 0);
490   dbxout_symbol (decl, 0);
491   fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n);
492 }
493
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
528      be used by the .function pseudo op to calculate the function size.  */
529
530   char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
531   if (*fname == '*')
532     ++fname;
533   fprintf (file, "FE..");
534   ASM_OUTPUT_LABEL (file, fname);
535 }
536 #endif /* XCOFF_DEBUGGING_INFO */