]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/xcoffout.c
*** empty log message ***
[thirdparty/gcc.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 /* These are GNU extensions we need to reference in this file. */
53 #ifndef N_DSLINE
54 #define N_DSLINE 0x46
55 #endif
56 #ifndef N_BSLINE
57 #define N_BSLINE 0x48
58 #endif
59
60 /* Line number of beginning of current function, minus one.
61 Negative means not in a function or not using xcoff. */
62
63 int xcoff_begin_function_line = -1;
64
65 /* Name of the current include file. */
66
67 char *xcoff_current_include_file;
68
69 /* Name of the current function file. This is the file the `.bf' is
70 emitted from. In case a line is emitted from a different file,
71 (by including that file of course), then the line number will be
72 absolute. */
73
74 char *xcoff_current_function_file;
75
76 /* Names of bss and data sections. These should be unique names for each
77 compilation unit. */
78
79 char *xcoff_bss_section_name;
80 char *xcoff_private_data_section_name;
81 char *xcoff_read_only_section_name;
82 \f
83 /* Macro definitions used below. */
84 /* Ensure we don't output a negative line number. */
85 #define MAKE_LINE_SAFE(LINE) \
86 if (LINE <= xcoff_begin_function_line) \
87 LINE = xcoff_begin_function_line + 1 \
88
89 #define ASM_OUTPUT_LFB(FILE,LINENUM) \
90 { \
91 if (xcoff_begin_function_line == -1) \
92 { \
93 xcoff_begin_function_line = (LINENUM) - 1;\
94 fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \
95 } \
96 xcoff_current_function_file \
97 = (xcoff_current_include_file \
98 ? xcoff_current_include_file : main_input_filename); \
99 }
100
101 #define ASM_OUTPUT_LFE(FILE,LINENUM) \
102 do { \
103 int linenum = LINENUM; \
104 MAKE_LINE_SAFE (linenum); \
105 fprintf (FILE, "\t.ef\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
106 xcoff_begin_function_line = -1; \
107 } while (0)
108
109 #define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \
110 do { \
111 int linenum = LINENUM; \
112 MAKE_LINE_SAFE (linenum); \
113 fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
114 } while (0)
115
116 #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
117 do { \
118 int linenum = LINENUM; \
119 MAKE_LINE_SAFE (linenum); \
120 fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
121 } while (0)
122 \f
123 /* Support routines for XCOFF debugging info. */
124
125 /* Assign NUMBER as the stabx type number for the type described by NAME.
126 Search all decls in the list SYMS to find the type NAME. */
127
128 static void
129 assign_type_number (syms, name, number)
130 tree syms;
131 char *name;
132 int number;
133 {
134 tree decl;
135
136 for (decl = syms; decl; decl = TREE_CHAIN (decl))
137 if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name))
138 {
139 TREE_ASM_WRITTEN (decl) = 1;
140 TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number;
141 }
142 }
143
144 /* Setup gcc primitive types to use the XCOFF built-in type numbers where
145 possible. */
146
147 void
148 xcoff_output_standard_types (syms)
149 tree syms;
150 {
151 /* Handle built-in C types here. */
152
153 assign_type_number (syms, "int", -1);
154 assign_type_number (syms, "char", -2);
155 assign_type_number (syms, "short int", -3);
156 assign_type_number (syms, "long int", -4);
157 assign_type_number (syms, "unsigned char", -5);
158 assign_type_number (syms, "signed char", -6);
159 assign_type_number (syms, "short unsigned int", -7);
160 assign_type_number (syms, "unsigned int", -8);
161 /* No such type "unsigned". */
162 assign_type_number (syms, "long unsigned int", -10);
163 assign_type_number (syms, "void", -11);
164 assign_type_number (syms, "float", -12);
165 assign_type_number (syms, "double", -13);
166 assign_type_number (syms, "long double", -14);
167 /* Pascal and Fortran types run from -15 to -29. */
168 /* No such type "wchar". */
169
170 /* "long long int", and "long long unsigned int", are not handled here,
171 because there are no predefined types that match them. */
172
173 /* ??? Should also handle built-in C++ and Obj-C types. There perhaps
174 aren't any that C doesn't already have. */
175 }
176
177 /* Print an error message for unrecognized stab codes. */
178
179 #define UNKNOWN_STAB(STR) \
180 do { \
181 fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \
182 fflush (stderr); \
183 } while (0)
184
185 /* Conversion routine from BSD stabs to AIX storage classes. */
186
187 int
188 stab_to_sclass (stab)
189 int stab;
190 {
191 switch (stab)
192 {
193 case N_GSYM:
194 return C_GSYM;
195
196 case N_FNAME:
197 UNKNOWN_STAB ("N_FNAME");
198 abort();
199
200 case N_FUN:
201 return C_FUN;
202
203 case N_STSYM:
204 case N_LCSYM:
205 return C_STSYM;
206
207 case N_MAIN:
208 UNKNOWN_STAB ("N_MAIN");
209 abort ();
210
211 case N_RSYM:
212 return C_RSYM;
213
214 case N_SSYM:
215 UNKNOWN_STAB ("N_SSYM");
216 abort ();
217
218 case N_RPSYM:
219 return C_RPSYM;
220
221 case N_PSYM:
222 return C_PSYM;
223 case N_LSYM:
224 return C_LSYM;
225 case N_DECL:
226 return C_DECL;
227 case N_ENTRY:
228 return C_ENTRY;
229
230 case N_SO:
231 UNKNOWN_STAB ("N_SO");
232 abort ();
233
234 case N_SOL:
235 UNKNOWN_STAB ("N_SOL");
236 abort ();
237
238 case N_SLINE:
239 UNKNOWN_STAB ("N_SLINE");
240 abort ();
241
242 case N_DSLINE:
243 UNKNOWN_STAB ("N_DSLINE");
244 abort ();
245
246 case N_BSLINE:
247 UNKNOWN_STAB ("N_BSLINE");
248 abort ();
249 #if 0
250 /* This has the same value as N_BSLINE. */
251 case N_BROWS:
252 UNKNOWN_STAB ("N_BROWS");
253 abort ();
254 #endif
255
256 case N_BINCL:
257 UNKNOWN_STAB ("N_BINCL");
258 abort ();
259
260 case N_EINCL:
261 UNKNOWN_STAB ("N_EINCL");
262 abort ();
263
264 case N_EXCL:
265 UNKNOWN_STAB ("N_EXCL");
266 abort ();
267
268 case N_LBRAC:
269 UNKNOWN_STAB ("N_LBRAC");
270 abort ();
271
272 case N_RBRAC:
273 UNKNOWN_STAB ("N_RBRAC");
274 abort ();
275
276 case N_BCOMM:
277 return C_BCOMM;
278 case N_ECOMM:
279 return C_ECOMM;
280 case N_ECOML:
281 return C_ECOML;
282
283 case N_LENG:
284 UNKNOWN_STAB ("N_LENG");
285 abort ();
286
287 case N_PC:
288 UNKNOWN_STAB ("N_PC");
289 abort ();
290
291 case N_M2C:
292 UNKNOWN_STAB ("N_M2C");
293 abort ();
294
295 case N_SCOPE:
296 UNKNOWN_STAB ("N_SCOPE");
297 abort ();
298
299 case N_CATCH:
300 UNKNOWN_STAB ("N_CATCH");
301 abort ();
302
303 default:
304 UNKNOWN_STAB ("default");
305 abort ();
306 }
307 }
308
309 /* In XCOFF, we have to have this .bf before the function prologue.
310 Rely on the value of `dbx_begin_function_line' not to duplicate .bf. */
311
312 void
313 xcoffout_output_first_source_line (file, last_linenum)
314 FILE *file;
315 int last_linenum;
316 {
317 ASM_OUTPUT_LFB (file, last_linenum);
318 dbxout_parms (DECL_ARGUMENTS (current_function_decl));
319 ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
320 }
321
322 /* Output the symbols defined in block number DO_BLOCK.
323 Set NEXT_BLOCK_NUMBER to 0 before calling.
324
325 This function works by walking the tree structure of blocks,
326 counting blocks until it finds the desired block. */
327
328 static int do_block = 0;
329
330 static int next_block_number;
331
332 static void
333 xcoffout_block (block, depth, args)
334 register tree block;
335 int depth;
336 tree args;
337 {
338 while (block)
339 {
340 /* Ignore blocks never expanded or otherwise marked as real. */
341 if (TREE_USED (block))
342 {
343 /* When we reach the specified block, output its symbols. */
344 if (next_block_number == do_block)
345 {
346 /* Output the syms of the block. */
347 if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
348 dbxout_syms (BLOCK_VARS (block));
349 if (args)
350 dbxout_reg_parms (args);
351
352 /* We are now done with the block. Don't go to inner blocks. */
353 return;
354 }
355 /* If we are past the specified block, stop the scan. */
356 else if (next_block_number >= do_block)
357 return;
358
359 next_block_number++;
360
361 /* Output the subblocks. */
362 xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, 0);
363 }
364 block = BLOCK_CHAIN (block);
365 }
366 }
367
368 /* Describe the beginning of an internal block within a function.
369 Also output descriptions of variables defined in this block.
370
371 N is the number of the block, by order of beginning, counting from 1,
372 and not counting the outermost (function top-level) block.
373 The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
374 if the count starts at 0 for the outermost one. */
375
376 void
377 xcoffout_begin_block (file, line, n)
378 FILE *file;
379 int line;
380 int n;
381 {
382 tree decl = current_function_decl;
383
384 ASM_OUTPUT_LBB (file, line, n);
385
386 do_block = n;
387 next_block_number = 0;
388 xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
389 }
390
391 /* Describe the end line-number of an internal block within a function. */
392
393 void
394 xcoffout_end_block (file, line, n)
395 FILE *file;
396 int line;
397 int n;
398 {
399 ASM_OUTPUT_LBE (file, line, n);
400 }
401
402 /* Called at beginning of function body (after prologue).
403 Record the function's starting line number, so we can output
404 relative line numbers for the other lines.
405 Record the file name that this function is contained in. */
406
407 void
408 xcoffout_begin_function (file, last_linenum)
409 FILE *file;
410 int last_linenum;
411 {
412 ASM_OUTPUT_LFB (file, last_linenum);
413 }
414
415 /* Called at end of function (before epilogue).
416 Describe end of outermost block. */
417
418 void
419 xcoffout_end_function (file, last_linenum)
420 FILE *file;
421 int last_linenum;
422 {
423 ASM_OUTPUT_LFE (file, last_linenum);
424 }
425
426 /* Output xcoff info for the absolute end of a function.
427 Called after the epilogue is output. */
428
429 void
430 xcoffout_end_epilogue (file)
431 FILE *file;
432 {
433 /* We need to pass the correct function size to .function, otherwise,
434 the xas assembler can't figure out the correct size for the function
435 aux entry. So, we emit a label after the last instruction which can
436 be used by the .function pseudo op to calculate the function size. */
437
438 char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
439 if (*fname == '*')
440 ++fname;
441 fprintf (file, "L..end_");
442 ASM_OUTPUT_LABEL (file, fname);
443 }
444 #endif /* XCOFF_DEBUGGING_INFO */