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