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