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