Home | History | Annotate | Line # | Download | only in gcc
dwarf2asm.cc revision 1.1
      1  1.1  mrg /* Dwarf2 assembler output helper routines.
      2  1.1  mrg    Copyright (C) 2001-2022 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      7  1.1  mrg the terms of the GNU General Public License as published by the Free
      8  1.1  mrg Software Foundation; either version 3, or (at your option) any later
      9  1.1  mrg version.
     10  1.1  mrg 
     11  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg for more details.
     15  1.1  mrg 
     16  1.1  mrg You should have received a copy of the GNU General Public License
     17  1.1  mrg along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg 
     21  1.1  mrg #include "config.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg #include "coretypes.h"
     24  1.1  mrg #include "target.h"
     25  1.1  mrg #include "rtl.h"
     26  1.1  mrg #include "tree.h"
     27  1.1  mrg #include "memmodel.h"
     28  1.1  mrg #include "tm_p.h"
     29  1.1  mrg #include "stringpool.h"
     30  1.1  mrg #include "varasm.h"
     31  1.1  mrg #include "output.h"
     32  1.1  mrg #include "dwarf2asm.h"
     33  1.1  mrg #include "dwarf2.h"
     34  1.1  mrg #include "function.h"
     35  1.1  mrg #include "emit-rtl.h"
     36  1.1  mrg #include "fold-const.h"
     37  1.1  mrg 
     38  1.1  mrg #ifndef XCOFF_DEBUGGING_INFO
     39  1.1  mrg #define XCOFF_DEBUGGING_INFO 0
     40  1.1  mrg #endif
     41  1.1  mrg 
     42  1.1  mrg 
     43  1.1  mrg /* Output an unaligned integer with the given value and size.  Prefer not
     45  1.1  mrg    to print a newline, since the caller may want to add a comment.  */
     46  1.1  mrg 
     47  1.1  mrg void
     48  1.1  mrg dw2_assemble_integer (int size, rtx x)
     49  1.1  mrg {
     50  1.1  mrg   if (size == 2 * (int) DWARF2_ADDR_SIZE && !CONST_SCALAR_INT_P (x))
     51  1.1  mrg     {
     52  1.1  mrg       /* On 32-bit targets with -gdwarf64, DImode values with
     53  1.1  mrg 	 relocations usually result in assembler errors.  Assume
     54  1.1  mrg 	 all such values are positive and emit the relocation only
     55  1.1  mrg 	 in the least significant half.  */
     56  1.1  mrg       const char *op = integer_asm_op (DWARF2_ADDR_SIZE, FALSE);
     57  1.1  mrg       if (BYTES_BIG_ENDIAN)
     58  1.1  mrg 	{
     59  1.1  mrg 	  if (op)
     60  1.1  mrg 	    {
     61  1.1  mrg 	      fputs (op, asm_out_file);
     62  1.1  mrg 	      fprint_whex (asm_out_file, 0);
     63  1.1  mrg 	      fputs (", ", asm_out_file);
     64  1.1  mrg 	      output_addr_const (asm_out_file, x);
     65  1.1  mrg 	    }
     66  1.1  mrg 	  else
     67  1.1  mrg 	    {
     68  1.1  mrg 	      assemble_integer (const0_rtx, DWARF2_ADDR_SIZE,
     69  1.1  mrg 				BITS_PER_UNIT, 1);
     70  1.1  mrg 	      putc ('\n', asm_out_file);
     71  1.1  mrg 	      assemble_integer (x, DWARF2_ADDR_SIZE,
     72  1.1  mrg 				BITS_PER_UNIT, 1);
     73  1.1  mrg 	    }
     74  1.1  mrg 	}
     75  1.1  mrg       else
     76  1.1  mrg 	{
     77  1.1  mrg 	  if (op)
     78  1.1  mrg 	    {
     79  1.1  mrg 	      fputs (op, asm_out_file);
     80  1.1  mrg 	      output_addr_const (asm_out_file, x);
     81  1.1  mrg 	      fputs (", ", asm_out_file);
     82  1.1  mrg 	      fprint_whex (asm_out_file, 0);
     83  1.1  mrg 	    }
     84  1.1  mrg 	  else
     85  1.1  mrg 	    {
     86  1.1  mrg 	      assemble_integer (x, DWARF2_ADDR_SIZE,
     87  1.1  mrg 				BITS_PER_UNIT, 1);
     88  1.1  mrg 	      putc ('\n', asm_out_file);
     89  1.1  mrg 	      assemble_integer (const0_rtx, DWARF2_ADDR_SIZE,
     90  1.1  mrg 				BITS_PER_UNIT, 1);
     91  1.1  mrg 	    }
     92  1.1  mrg 	}
     93  1.1  mrg       return;
     94  1.1  mrg     }
     95  1.1  mrg 
     96  1.1  mrg   const char *op = integer_asm_op (size, FALSE);
     97  1.1  mrg 
     98  1.1  mrg   if (op)
     99  1.1  mrg     {
    100  1.1  mrg       fputs (op, asm_out_file);
    101  1.1  mrg       if (CONST_INT_P (x))
    102  1.1  mrg 	fprint_whex (asm_out_file, (unsigned HOST_WIDE_INT) INTVAL (x));
    103  1.1  mrg       else
    104  1.1  mrg 	output_addr_const (asm_out_file, x);
    105  1.1  mrg     }
    106  1.1  mrg   else
    107  1.1  mrg     assemble_integer (x, size, BITS_PER_UNIT, 1);
    108  1.1  mrg }
    109  1.1  mrg 
    110  1.1  mrg 
    111  1.1  mrg /* Output a value of a given size in target byte order.  */
    112  1.1  mrg 
    113  1.1  mrg void
    114  1.1  mrg dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value)
    115  1.1  mrg {
    116  1.1  mrg   unsigned char bytes[8];
    117  1.1  mrg   int i;
    118  1.1  mrg 
    119  1.1  mrg   for (i = 0; i < 8; ++i)
    120  1.1  mrg     {
    121  1.1  mrg       bytes[i] = value & 0xff;
    122  1.1  mrg       value >>= 8;
    123  1.1  mrg     }
    124  1.1  mrg 
    125  1.1  mrg   if (BYTES_BIG_ENDIAN)
    126  1.1  mrg     {
    127  1.1  mrg       for (i = size - 1; i > 0; --i)
    128  1.1  mrg 	fprintf (asm_out_file, "%#x,", bytes[i]);
    129  1.1  mrg       fprintf (asm_out_file, "%#x", bytes[0]);
    130  1.1  mrg     }
    131  1.1  mrg   else
    132  1.1  mrg     {
    133  1.1  mrg       for (i = 0; i < size - 1; ++i)
    134  1.1  mrg 	fprintf (asm_out_file, "%#x,", bytes[i]);
    135  1.1  mrg       fprintf (asm_out_file, "%#x", bytes[i]);
    136  1.1  mrg     }
    137  1.1  mrg }
    138  1.1  mrg 
    139  1.1  mrg /* Output an immediate constant in a given SIZE in bytes.  */
    140  1.1  mrg 
    141  1.1  mrg void
    142  1.1  mrg dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
    143  1.1  mrg 		     const char *comment, ...)
    144  1.1  mrg {
    145  1.1  mrg   va_list ap;
    146  1.1  mrg   const char *op = integer_asm_op (size, FALSE);
    147  1.1  mrg 
    148  1.1  mrg   va_start (ap, comment);
    149  1.1  mrg 
    150  1.1  mrg   if (size * 8 < HOST_BITS_PER_WIDE_INT)
    151  1.1  mrg     value &= ~(HOST_WIDE_INT_M1U << (size * 8));
    152  1.1  mrg 
    153  1.1  mrg   if (op)
    154  1.1  mrg     {
    155  1.1  mrg       fputs (op, asm_out_file);
    156  1.1  mrg       fprint_whex (asm_out_file, value);
    157  1.1  mrg     }
    158  1.1  mrg   else
    159  1.1  mrg     assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
    160  1.1  mrg 
    161  1.1  mrg   if (flag_debug_asm && comment)
    162  1.1  mrg     {
    163  1.1  mrg       fputs ("\t" ASM_COMMENT_START " ", asm_out_file);
    164  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    165  1.1  mrg     }
    166  1.1  mrg   putc ('\n', asm_out_file);
    167  1.1  mrg 
    168  1.1  mrg   va_end (ap);
    169  1.1  mrg }
    170  1.1  mrg 
    171  1.1  mrg /* Output the difference between two symbols in a given size.  */
    172  1.1  mrg /* ??? There appear to be assemblers that do not like such
    173  1.1  mrg    subtraction, but do support ASM_SET_OP.  It's unfortunately
    174  1.1  mrg    impossible to do here, since the ASM_SET_OP for the difference
    175  1.1  mrg    symbol must appear after both symbols are defined.  */
    176  1.1  mrg 
    177  1.1  mrg void
    178  1.1  mrg dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
    179  1.1  mrg 		      const char *comment, ...)
    180  1.1  mrg {
    181  1.1  mrg   va_list ap;
    182  1.1  mrg 
    183  1.1  mrg   va_start (ap, comment);
    184  1.1  mrg 
    185  1.1  mrg #ifdef ASM_OUTPUT_DWARF_DELTA
    186  1.1  mrg   ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
    187  1.1  mrg #else
    188  1.1  mrg   dw2_assemble_integer (size,
    189  1.1  mrg 			gen_rtx_MINUS (Pmode,
    190  1.1  mrg 				       gen_rtx_SYMBOL_REF (Pmode, lab1),
    191  1.1  mrg 				       gen_rtx_SYMBOL_REF (Pmode, lab2)));
    192  1.1  mrg #endif
    193  1.1  mrg   if (flag_debug_asm && comment)
    194  1.1  mrg     {
    195  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    196  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    197  1.1  mrg     }
    198  1.1  mrg   fputc ('\n', asm_out_file);
    199  1.1  mrg 
    200  1.1  mrg   va_end (ap);
    201  1.1  mrg }
    202  1.1  mrg 
    203  1.1  mrg #ifdef ASM_OUTPUT_DWARF_VMS_DELTA
    204  1.1  mrg /* Output the difference between two symbols in instruction units
    205  1.1  mrg    in a given size.  */
    206  1.1  mrg 
    207  1.1  mrg void
    208  1.1  mrg dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED,
    209  1.1  mrg 			  const char *lab1, const char *lab2,
    210  1.1  mrg 			  const char *comment, ...)
    211  1.1  mrg {
    212  1.1  mrg   va_list ap;
    213  1.1  mrg 
    214  1.1  mrg   va_start (ap, comment);
    215  1.1  mrg 
    216  1.1  mrg   ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2);
    217  1.1  mrg   if (flag_debug_asm && comment)
    218  1.1  mrg     {
    219  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    220  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    221  1.1  mrg     }
    222  1.1  mrg   fputc ('\n', asm_out_file);
    223  1.1  mrg 
    224  1.1  mrg   va_end (ap);
    225  1.1  mrg }
    226  1.1  mrg #endif
    227  1.1  mrg 
    228  1.1  mrg /* Output a section-relative reference to a LABEL, which was placed in
    229  1.1  mrg    BASE.  In general this can only be done for debugging symbols.
    230  1.1  mrg    E.g. on most targets with the GNU linker, this is accomplished with
    231  1.1  mrg    a direct reference and the knowledge that the debugging section
    232  1.1  mrg    will be placed at VMA 0.  Some targets have special relocations for
    233  1.1  mrg    this that we must use.  */
    234  1.1  mrg 
    235  1.1  mrg void
    236  1.1  mrg dw2_asm_output_offset (int size, const char *label,
    237  1.1  mrg 		       section *base ATTRIBUTE_UNUSED,
    238  1.1  mrg 		       const char *comment, ...)
    239  1.1  mrg {
    240  1.1  mrg   va_list ap;
    241  1.1  mrg 
    242  1.1  mrg   va_start (ap, comment);
    243  1.1  mrg 
    244  1.1  mrg #ifdef ASM_OUTPUT_DWARF_OFFSET
    245  1.1  mrg   ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, 0, base);
    246  1.1  mrg #else
    247  1.1  mrg   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
    248  1.1  mrg #endif
    249  1.1  mrg 
    250  1.1  mrg   if (flag_debug_asm && comment)
    251  1.1  mrg     {
    252  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    253  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    254  1.1  mrg     }
    255  1.1  mrg   fputc ('\n', asm_out_file);
    256  1.1  mrg 
    257  1.1  mrg   va_end (ap);
    258  1.1  mrg }
    259  1.1  mrg 
    260  1.1  mrg void
    261  1.1  mrg dw2_asm_output_offset (int size, const char *label, HOST_WIDE_INT offset,
    262  1.1  mrg 		       section *base ATTRIBUTE_UNUSED,
    263  1.1  mrg 		       const char *comment, ...)
    264  1.1  mrg {
    265  1.1  mrg   va_list ap;
    266  1.1  mrg 
    267  1.1  mrg   va_start (ap, comment);
    268  1.1  mrg 
    269  1.1  mrg #ifdef ASM_OUTPUT_DWARF_OFFSET
    270  1.1  mrg   ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, offset, base);
    271  1.1  mrg #else
    272  1.1  mrg   dw2_assemble_integer (size, gen_rtx_PLUS (Pmode,
    273  1.1  mrg 					    gen_rtx_SYMBOL_REF (Pmode, label),
    274  1.1  mrg 					    gen_int_mode (offset, Pmode)));
    275  1.1  mrg #endif
    276  1.1  mrg 
    277  1.1  mrg   if (flag_debug_asm && comment)
    278  1.1  mrg     {
    279  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    280  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    281  1.1  mrg     }
    282  1.1  mrg   fputc ('\n', asm_out_file);
    283  1.1  mrg 
    284  1.1  mrg   va_end (ap);
    285  1.1  mrg }
    286  1.1  mrg 
    287  1.1  mrg #if 0
    288  1.1  mrg 
    289  1.1  mrg /* Output a self-relative reference to a label, possibly in a
    290  1.1  mrg    different section or object file.  */
    291  1.1  mrg 
    292  1.1  mrg void
    293  1.1  mrg dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
    294  1.1  mrg 		      const char *label ATTRIBUTE_UNUSED,
    295  1.1  mrg 		      const char *comment, ...)
    296  1.1  mrg {
    297  1.1  mrg   va_list ap;
    298  1.1  mrg 
    299  1.1  mrg   va_start (ap, comment);
    300  1.1  mrg 
    301  1.1  mrg #ifdef ASM_OUTPUT_DWARF_PCREL
    302  1.1  mrg   ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
    303  1.1  mrg #else
    304  1.1  mrg   dw2_assemble_integer (size,
    305  1.1  mrg 			gen_rtx_MINUS (Pmode,
    306  1.1  mrg 				       gen_rtx_SYMBOL_REF (Pmode, label),
    307  1.1  mrg 				       pc_rtx));
    308  1.1  mrg #endif
    309  1.1  mrg 
    310  1.1  mrg   if (flag_debug_asm && comment)
    311  1.1  mrg     {
    312  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    313  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    314  1.1  mrg     }
    315  1.1  mrg   fputc ('\n', asm_out_file);
    316  1.1  mrg 
    317  1.1  mrg   va_end (ap);
    318  1.1  mrg }
    319  1.1  mrg #endif /* 0 */
    320  1.1  mrg 
    321  1.1  mrg /* Output an absolute reference to a label.  */
    322  1.1  mrg 
    323  1.1  mrg void
    324  1.1  mrg dw2_asm_output_addr (int size, const char *label,
    325  1.1  mrg 		     const char *comment, ...)
    326  1.1  mrg {
    327  1.1  mrg   va_list ap;
    328  1.1  mrg 
    329  1.1  mrg   va_start (ap, comment);
    330  1.1  mrg 
    331  1.1  mrg   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
    332  1.1  mrg 
    333  1.1  mrg   if (flag_debug_asm && comment)
    334  1.1  mrg     {
    335  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    336  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    337  1.1  mrg     }
    338  1.1  mrg   fputc ('\n', asm_out_file);
    339  1.1  mrg 
    340  1.1  mrg   va_end (ap);
    341  1.1  mrg }
    342  1.1  mrg 
    343  1.1  mrg /* Similar, but use an RTX expression instead of a text label.  */
    344  1.1  mrg 
    345  1.1  mrg void
    346  1.1  mrg dw2_asm_output_addr_rtx (int size, rtx addr,
    347  1.1  mrg 			 const char *comment, ...)
    348  1.1  mrg {
    349  1.1  mrg   va_list ap;
    350  1.1  mrg 
    351  1.1  mrg   va_start (ap, comment);
    352  1.1  mrg 
    353  1.1  mrg   dw2_assemble_integer (size, addr);
    354  1.1  mrg 
    355  1.1  mrg   if (flag_debug_asm && comment)
    356  1.1  mrg     {
    357  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    358  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    359  1.1  mrg     }
    360  1.1  mrg   fputc ('\n', asm_out_file);
    361  1.1  mrg 
    362  1.1  mrg   va_end (ap);
    363  1.1  mrg }
    364  1.1  mrg 
    365  1.1  mrg /* Output the first ORIG_LEN characters of STR as a string.
    366  1.1  mrg    If ORIG_LEN is equal to -1, ignore this parameter and output
    367  1.1  mrg    the entire STR instead.
    368  1.1  mrg    If COMMENT is not NULL and comments in the debug information
    369  1.1  mrg    have been requested by the user, append the given COMMENT
    370  1.1  mrg    to the generated output.  */
    371  1.1  mrg 
    372  1.1  mrg void
    373  1.1  mrg dw2_asm_output_nstring (const char *str, size_t orig_len,
    374  1.1  mrg 			const char *comment, ...)
    375  1.1  mrg {
    376  1.1  mrg   size_t i, len;
    377  1.1  mrg   va_list ap;
    378  1.1  mrg 
    379  1.1  mrg   va_start (ap, comment);
    380  1.1  mrg 
    381  1.1  mrg   len = orig_len;
    382  1.1  mrg 
    383  1.1  mrg   if (len == (size_t) -1)
    384  1.1  mrg     len = strlen (str);
    385  1.1  mrg 
    386  1.1  mrg   if (flag_debug_asm && comment)
    387  1.1  mrg     {
    388  1.1  mrg       if (XCOFF_DEBUGGING_INFO)
    389  1.1  mrg 	fputs ("\t.byte \"", asm_out_file);
    390  1.1  mrg       else
    391  1.1  mrg 	fputs ("\t.ascii \"", asm_out_file);
    392  1.1  mrg 
    393  1.1  mrg       for (i = 0; i < len; i++)
    394  1.1  mrg 	{
    395  1.1  mrg 	  int c = str[i];
    396  1.1  mrg 	  if (c == '\"')
    397  1.1  mrg 	    fputc (XCOFF_DEBUGGING_INFO ? '\"' : '\\', asm_out_file);
    398  1.1  mrg 	  else if (c == '\\')
    399  1.1  mrg 	    fputc ('\\', asm_out_file);
    400  1.1  mrg 	  if (ISPRINT (c))
    401  1.1  mrg 	    fputc (c, asm_out_file);
    402  1.1  mrg 	  else
    403  1.1  mrg 	    fprintf (asm_out_file, "\\%o", c);
    404  1.1  mrg 	}
    405  1.1  mrg       fprintf (asm_out_file, "\\0\"\t%s ", ASM_COMMENT_START);
    406  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    407  1.1  mrg       fputc ('\n', asm_out_file);
    408  1.1  mrg     }
    409  1.1  mrg   else
    410  1.1  mrg     {
    411  1.1  mrg       /* If an explicit length was given, we can't assume there
    412  1.1  mrg 	 is a null termination in the string buffer.  */
    413  1.1  mrg       if (orig_len == (size_t) -1)
    414  1.1  mrg 	len += 1;
    415  1.1  mrg       ASM_OUTPUT_ASCII (asm_out_file, str, len);
    416  1.1  mrg       if (orig_len != (size_t) -1)
    417  1.1  mrg 	assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
    418  1.1  mrg     }
    419  1.1  mrg 
    420  1.1  mrg   va_end (ap);
    421  1.1  mrg }
    422  1.1  mrg 
    423  1.1  mrg 
    425  1.1  mrg /* Return the size of an unsigned LEB128 quantity.  */
    426  1.1  mrg 
    427  1.1  mrg int
    428  1.1  mrg size_of_uleb128 (unsigned HOST_WIDE_INT value)
    429  1.1  mrg {
    430  1.1  mrg   int size = 0;
    431  1.1  mrg 
    432  1.1  mrg   do
    433  1.1  mrg     {
    434  1.1  mrg       value >>= 7;
    435  1.1  mrg       size += 1;
    436  1.1  mrg     }
    437  1.1  mrg   while (value != 0);
    438  1.1  mrg 
    439  1.1  mrg   return size;
    440  1.1  mrg }
    441  1.1  mrg 
    442  1.1  mrg /* Return the size of a signed LEB128 quantity.  */
    443  1.1  mrg 
    444  1.1  mrg int
    445  1.1  mrg size_of_sleb128 (HOST_WIDE_INT value)
    446  1.1  mrg {
    447  1.1  mrg   int size = 0, byte;
    448  1.1  mrg 
    449  1.1  mrg   do
    450  1.1  mrg     {
    451  1.1  mrg       byte = (value & 0x7f);
    452  1.1  mrg       value >>= 7;
    453  1.1  mrg       size += 1;
    454  1.1  mrg     }
    455  1.1  mrg   while (!((value == 0 && (byte & 0x40) == 0)
    456  1.1  mrg 	   || (value == -1 && (byte & 0x40) != 0)));
    457  1.1  mrg 
    458  1.1  mrg   return size;
    459  1.1  mrg }
    460  1.1  mrg 
    461  1.1  mrg /* Given an encoding, return the number of bytes the format occupies.
    462  1.1  mrg    This is only defined for fixed-size encodings, and so does not
    463  1.1  mrg    include leb128.  */
    464  1.1  mrg 
    465  1.1  mrg int
    466  1.1  mrg size_of_encoded_value (int encoding)
    467  1.1  mrg {
    468  1.1  mrg   if (encoding == DW_EH_PE_omit)
    469  1.1  mrg     return 0;
    470  1.1  mrg 
    471  1.1  mrg   switch (encoding & 0x07)
    472  1.1  mrg     {
    473  1.1  mrg     case DW_EH_PE_absptr:
    474  1.1  mrg       return POINTER_SIZE_UNITS;
    475  1.1  mrg     case DW_EH_PE_udata2:
    476  1.1  mrg       return 2;
    477  1.1  mrg     case DW_EH_PE_udata4:
    478  1.1  mrg       return 4;
    479  1.1  mrg     case DW_EH_PE_udata8:
    480  1.1  mrg       return 8;
    481  1.1  mrg     default:
    482  1.1  mrg       gcc_unreachable ();
    483  1.1  mrg     }
    484  1.1  mrg }
    485  1.1  mrg 
    486  1.1  mrg /* Yield a name for a given pointer encoding.  */
    487  1.1  mrg 
    488  1.1  mrg const char *
    489  1.1  mrg eh_data_format_name (int format)
    490  1.1  mrg {
    491  1.1  mrg #if HAVE_DESIGNATED_INITIALIZERS
    492  1.1  mrg #define S(p, v)		[p] = v,
    493  1.1  mrg #else
    494  1.1  mrg #define S(p, v)		case p: return v;
    495  1.1  mrg #endif
    496  1.1  mrg 
    497  1.1  mrg #if HAVE_DESIGNATED_INITIALIZERS
    498  1.1  mrg   __extension__ static const char * const format_names[256] = {
    499  1.1  mrg #else
    500  1.1  mrg   switch (format) {
    501  1.1  mrg #endif
    502  1.1  mrg 
    503  1.1  mrg   S(DW_EH_PE_absptr, "absolute")
    504  1.1  mrg   S(DW_EH_PE_omit, "omit")
    505  1.1  mrg   S(DW_EH_PE_aligned, "aligned absolute")
    506  1.1  mrg 
    507  1.1  mrg   S(DW_EH_PE_uleb128, "uleb128")
    508  1.1  mrg   S(DW_EH_PE_udata2, "udata2")
    509  1.1  mrg   S(DW_EH_PE_udata4, "udata4")
    510  1.1  mrg   S(DW_EH_PE_udata8, "udata8")
    511  1.1  mrg   S(DW_EH_PE_sleb128, "sleb128")
    512  1.1  mrg   S(DW_EH_PE_sdata2, "sdata2")
    513  1.1  mrg   S(DW_EH_PE_sdata4, "sdata4")
    514  1.1  mrg   S(DW_EH_PE_sdata8, "sdata8")
    515  1.1  mrg 
    516  1.1  mrg   S(DW_EH_PE_absptr | DW_EH_PE_pcrel, "pcrel")
    517  1.1  mrg   S(DW_EH_PE_uleb128 | DW_EH_PE_pcrel, "pcrel uleb128")
    518  1.1  mrg   S(DW_EH_PE_udata2 | DW_EH_PE_pcrel, "pcrel udata2")
    519  1.1  mrg   S(DW_EH_PE_udata4 | DW_EH_PE_pcrel, "pcrel udata4")
    520  1.1  mrg   S(DW_EH_PE_udata8 | DW_EH_PE_pcrel, "pcrel udata8")
    521  1.1  mrg   S(DW_EH_PE_sleb128 | DW_EH_PE_pcrel, "pcrel sleb128")
    522  1.1  mrg   S(DW_EH_PE_sdata2 | DW_EH_PE_pcrel, "pcrel sdata2")
    523  1.1  mrg   S(DW_EH_PE_sdata4 | DW_EH_PE_pcrel, "pcrel sdata4")
    524  1.1  mrg   S(DW_EH_PE_sdata8 | DW_EH_PE_pcrel, "pcrel sdata8")
    525  1.1  mrg 
    526  1.1  mrg   S(DW_EH_PE_absptr | DW_EH_PE_textrel, "textrel")
    527  1.1  mrg   S(DW_EH_PE_uleb128 | DW_EH_PE_textrel, "textrel uleb128")
    528  1.1  mrg   S(DW_EH_PE_udata2 | DW_EH_PE_textrel, "textrel udata2")
    529  1.1  mrg   S(DW_EH_PE_udata4 | DW_EH_PE_textrel, "textrel udata4")
    530  1.1  mrg   S(DW_EH_PE_udata8 | DW_EH_PE_textrel, "textrel udata8")
    531  1.1  mrg   S(DW_EH_PE_sleb128 | DW_EH_PE_textrel, "textrel sleb128")
    532  1.1  mrg   S(DW_EH_PE_sdata2 | DW_EH_PE_textrel, "textrel sdata2")
    533  1.1  mrg   S(DW_EH_PE_sdata4 | DW_EH_PE_textrel, "textrel sdata4")
    534  1.1  mrg   S(DW_EH_PE_sdata8 | DW_EH_PE_textrel, "textrel sdata8")
    535  1.1  mrg 
    536  1.1  mrg   S(DW_EH_PE_absptr | DW_EH_PE_datarel, "datarel")
    537  1.1  mrg   S(DW_EH_PE_uleb128 | DW_EH_PE_datarel, "datarel uleb128")
    538  1.1  mrg   S(DW_EH_PE_udata2 | DW_EH_PE_datarel, "datarel udata2")
    539  1.1  mrg   S(DW_EH_PE_udata4 | DW_EH_PE_datarel, "datarel udata4")
    540  1.1  mrg   S(DW_EH_PE_udata8 | DW_EH_PE_datarel, "datarel udata8")
    541  1.1  mrg   S(DW_EH_PE_sleb128 | DW_EH_PE_datarel, "datarel sleb128")
    542  1.1  mrg   S(DW_EH_PE_sdata2 | DW_EH_PE_datarel, "datarel sdata2")
    543  1.1  mrg   S(DW_EH_PE_sdata4 | DW_EH_PE_datarel, "datarel sdata4")
    544  1.1  mrg   S(DW_EH_PE_sdata8 | DW_EH_PE_datarel, "datarel sdata8")
    545  1.1  mrg 
    546  1.1  mrg   S(DW_EH_PE_absptr | DW_EH_PE_funcrel, "funcrel")
    547  1.1  mrg   S(DW_EH_PE_uleb128 | DW_EH_PE_funcrel, "funcrel uleb128")
    548  1.1  mrg   S(DW_EH_PE_udata2 | DW_EH_PE_funcrel, "funcrel udata2")
    549  1.1  mrg   S(DW_EH_PE_udata4 | DW_EH_PE_funcrel, "funcrel udata4")
    550  1.1  mrg   S(DW_EH_PE_udata8 | DW_EH_PE_funcrel, "funcrel udata8")
    551  1.1  mrg   S(DW_EH_PE_sleb128 | DW_EH_PE_funcrel, "funcrel sleb128")
    552  1.1  mrg   S(DW_EH_PE_sdata2 | DW_EH_PE_funcrel, "funcrel sdata2")
    553  1.1  mrg   S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
    554  1.1  mrg   S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
    555  1.1  mrg 
    556  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
    557  1.1  mrg 
    558  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
    559  1.1  mrg     "indirect pcrel")
    560  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
    561  1.1  mrg     "indirect pcrel uleb128")
    562  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel,
    563  1.1  mrg     "indirect pcrel udata2")
    564  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel,
    565  1.1  mrg     "indirect pcrel udata4")
    566  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel,
    567  1.1  mrg     "indirect pcrel udata8")
    568  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel,
    569  1.1  mrg     "indirect pcrel sleb128")
    570  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel,
    571  1.1  mrg     "indirect pcrel sdata2")
    572  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel,
    573  1.1  mrg     "indirect pcrel sdata4")
    574  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel,
    575  1.1  mrg     "indirect pcrel sdata8")
    576  1.1  mrg 
    577  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_textrel,
    578  1.1  mrg     "indirect textrel")
    579  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel,
    580  1.1  mrg     "indirect textrel uleb128")
    581  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel,
    582  1.1  mrg     "indirect textrel udata2")
    583  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel,
    584  1.1  mrg     "indirect textrel udata4")
    585  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel,
    586  1.1  mrg     "indirect textrel udata8")
    587  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel,
    588  1.1  mrg     "indirect textrel sleb128")
    589  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel,
    590  1.1  mrg     "indirect textrel sdata2")
    591  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel,
    592  1.1  mrg     "indirect textrel sdata4")
    593  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel,
    594  1.1  mrg     "indirect textrel sdata8")
    595  1.1  mrg 
    596  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_datarel,
    597  1.1  mrg     "indirect datarel")
    598  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel,
    599  1.1  mrg     "indirect datarel uleb128")
    600  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel,
    601  1.1  mrg     "indirect datarel udata2")
    602  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel,
    603  1.1  mrg     "indirect datarel udata4")
    604  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel,
    605  1.1  mrg     "indirect datarel udata8")
    606  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel,
    607  1.1  mrg     "indirect datarel sleb128")
    608  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel,
    609  1.1  mrg     "indirect datarel sdata2")
    610  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel,
    611  1.1  mrg     "indirect datarel sdata4")
    612  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel,
    613  1.1  mrg     "indirect datarel sdata8")
    614  1.1  mrg 
    615  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_funcrel,
    616  1.1  mrg     "indirect funcrel")
    617  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel,
    618  1.1  mrg     "indirect funcrel uleb128")
    619  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel,
    620  1.1  mrg     "indirect funcrel udata2")
    621  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel,
    622  1.1  mrg     "indirect funcrel udata4")
    623  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel,
    624  1.1  mrg     "indirect funcrel udata8")
    625  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel,
    626  1.1  mrg     "indirect funcrel sleb128")
    627  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel,
    628  1.1  mrg     "indirect funcrel sdata2")
    629  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel,
    630  1.1  mrg     "indirect funcrel sdata4")
    631  1.1  mrg   S(DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel,
    632  1.1  mrg     "indirect funcrel sdata8")
    633  1.1  mrg 
    634  1.1  mrg #if HAVE_DESIGNATED_INITIALIZERS
    635  1.1  mrg   };
    636  1.1  mrg 
    637  1.1  mrg   gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
    638  1.1  mrg 
    639  1.1  mrg   return format_names[format];
    640  1.1  mrg #else
    641  1.1  mrg   }
    642  1.1  mrg   gcc_unreachable ();
    643  1.1  mrg #endif
    644  1.1  mrg }
    645  1.1  mrg 
    646  1.1  mrg /* Output an unsigned LEB128 quantity, but only the byte values.  */
    647  1.1  mrg 
    648  1.1  mrg void
    649  1.1  mrg dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value)
    650  1.1  mrg {
    651  1.1  mrg   while (1)
    652  1.1  mrg     {
    653  1.1  mrg       int byte = (value & 0x7f);
    654  1.1  mrg       value >>= 7;
    655  1.1  mrg       if (value != 0)
    656  1.1  mrg 	/* More bytes to follow.  */
    657  1.1  mrg 	byte |= 0x80;
    658  1.1  mrg 
    659  1.1  mrg       fprintf (asm_out_file, "%#x", byte);
    660  1.1  mrg       if (value == 0)
    661  1.1  mrg 	break;
    662  1.1  mrg       fputc (',', asm_out_file);
    663  1.1  mrg     }
    664  1.1  mrg }
    665  1.1  mrg 
    666  1.1  mrg /* Output an unsigned LEB128 quantity.  */
    667  1.1  mrg 
    668  1.1  mrg void
    669  1.1  mrg dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
    670  1.1  mrg 			     const char *comment, ...)
    671  1.1  mrg {
    672  1.1  mrg   va_list ap;
    673  1.1  mrg 
    674  1.1  mrg   va_start (ap, comment);
    675  1.1  mrg 
    676  1.1  mrg   if (HAVE_AS_LEB128)
    677  1.1  mrg     {
    678  1.1  mrg       fputs ("\t.uleb128 ", asm_out_file);
    679  1.1  mrg       fprint_whex (asm_out_file, value);
    680  1.1  mrg 
    681  1.1  mrg       if (flag_debug_asm && comment)
    682  1.1  mrg 	{
    683  1.1  mrg 	  fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    684  1.1  mrg 	  vfprintf (asm_out_file, comment, ap);
    685  1.1  mrg 	}
    686  1.1  mrg     }
    687  1.1  mrg   else
    688  1.1  mrg     {
    689  1.1  mrg       unsigned HOST_WIDE_INT work = value;
    690  1.1  mrg       const char *byte_op = targetm.asm_out.byte_op;
    691  1.1  mrg 
    692  1.1  mrg       if (byte_op)
    693  1.1  mrg 	fputs (byte_op, asm_out_file);
    694  1.1  mrg       do
    695  1.1  mrg 	{
    696  1.1  mrg 	  int byte = (work & 0x7f);
    697  1.1  mrg 	  work >>= 7;
    698  1.1  mrg 	  if (work != 0)
    699  1.1  mrg 	    /* More bytes to follow.  */
    700  1.1  mrg 	    byte |= 0x80;
    701  1.1  mrg 
    702  1.1  mrg 	  if (byte_op)
    703  1.1  mrg 	    {
    704  1.1  mrg 	      fprintf (asm_out_file, "%#x", byte);
    705  1.1  mrg 	      if (work != 0)
    706  1.1  mrg 		fputc (',', asm_out_file);
    707  1.1  mrg 	    }
    708  1.1  mrg 	  else
    709  1.1  mrg 	    assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
    710  1.1  mrg 	}
    711  1.1  mrg       while (work != 0);
    712  1.1  mrg 
    713  1.1  mrg       if (flag_debug_asm)
    714  1.1  mrg 	{
    715  1.1  mrg 	  fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
    716  1.1  mrg 		   ASM_COMMENT_START, value);
    717  1.1  mrg 	  if (comment)
    718  1.1  mrg 	    {
    719  1.1  mrg 	      fputs ("; ", asm_out_file);
    720  1.1  mrg 	      vfprintf (asm_out_file, comment, ap);
    721  1.1  mrg 	    }
    722  1.1  mrg 	}
    723  1.1  mrg     }
    724  1.1  mrg 
    725  1.1  mrg   putc ('\n', asm_out_file);
    726  1.1  mrg 
    727  1.1  mrg   va_end (ap);
    728  1.1  mrg }
    729  1.1  mrg 
    730  1.1  mrg /* Output an signed LEB128 quantity, but only the byte values.  */
    731  1.1  mrg 
    732  1.1  mrg void
    733  1.1  mrg dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value)
    734  1.1  mrg {
    735  1.1  mrg   int byte, more;
    736  1.1  mrg 
    737  1.1  mrg   while (1)
    738  1.1  mrg     {
    739  1.1  mrg       byte = (value & 0x7f);
    740  1.1  mrg       value >>= 7;
    741  1.1  mrg       more = !((value == 0 && (byte & 0x40) == 0)
    742  1.1  mrg 		|| (value == -1 && (byte & 0x40) != 0));
    743  1.1  mrg       if (more)
    744  1.1  mrg 	byte |= 0x80;
    745  1.1  mrg 
    746  1.1  mrg       fprintf (asm_out_file, "%#x", byte);
    747  1.1  mrg       if (!more)
    748  1.1  mrg 	break;
    749  1.1  mrg       fputc (',', asm_out_file);
    750  1.1  mrg     }
    751  1.1  mrg }
    752  1.1  mrg 
    753  1.1  mrg /* Output a signed LEB128 quantity.  */
    754  1.1  mrg 
    755  1.1  mrg void
    756  1.1  mrg dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
    757  1.1  mrg 			     const char *comment, ...)
    758  1.1  mrg {
    759  1.1  mrg   va_list ap;
    760  1.1  mrg 
    761  1.1  mrg   va_start (ap, comment);
    762  1.1  mrg 
    763  1.1  mrg   if (HAVE_AS_LEB128)
    764  1.1  mrg     {
    765  1.1  mrg       fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
    766  1.1  mrg 
    767  1.1  mrg       if (flag_debug_asm && comment)
    768  1.1  mrg 	{
    769  1.1  mrg 	  fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    770  1.1  mrg 	  vfprintf (asm_out_file, comment, ap);
    771  1.1  mrg 	}
    772  1.1  mrg     }
    773  1.1  mrg   else
    774  1.1  mrg     {
    775  1.1  mrg       HOST_WIDE_INT work = value;
    776  1.1  mrg       int more, byte;
    777  1.1  mrg       const char *byte_op = targetm.asm_out.byte_op;
    778  1.1  mrg 
    779  1.1  mrg       if (byte_op)
    780  1.1  mrg 	fputs (byte_op, asm_out_file);
    781  1.1  mrg       do
    782  1.1  mrg 	{
    783  1.1  mrg 	  byte = (work & 0x7f);
    784  1.1  mrg 	  /* arithmetic shift */
    785  1.1  mrg 	  work >>= 7;
    786  1.1  mrg 	  more = !((work == 0 && (byte & 0x40) == 0)
    787  1.1  mrg 		   || (work == -1 && (byte & 0x40) != 0));
    788  1.1  mrg 	  if (more)
    789  1.1  mrg 	    byte |= 0x80;
    790  1.1  mrg 
    791  1.1  mrg 	  if (byte_op)
    792  1.1  mrg 	    {
    793  1.1  mrg 	      fprintf (asm_out_file, "%#x", byte);
    794  1.1  mrg 	      if (more)
    795  1.1  mrg 		fputc (',', asm_out_file);
    796  1.1  mrg 	    }
    797  1.1  mrg 	  else
    798  1.1  mrg 	    assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
    799  1.1  mrg 	}
    800  1.1  mrg       while (more);
    801  1.1  mrg 
    802  1.1  mrg       if (flag_debug_asm)
    803  1.1  mrg 	{
    804  1.1  mrg 	  fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
    805  1.1  mrg 		   ASM_COMMENT_START, value);
    806  1.1  mrg 	  if (comment)
    807  1.1  mrg 	    {
    808  1.1  mrg 	      fputs ("; ", asm_out_file);
    809  1.1  mrg 	      vfprintf (asm_out_file, comment, ap);
    810  1.1  mrg 	    }
    811  1.1  mrg 	}
    812  1.1  mrg     }
    813  1.1  mrg 
    814  1.1  mrg   fputc ('\n', asm_out_file);
    815  1.1  mrg 
    816  1.1  mrg   va_end (ap);
    817  1.1  mrg }
    818  1.1  mrg 
    819  1.1  mrg /* Output symbol LAB1 as an unsigned LEB128 quantity.  LAB1 should be
    820  1.1  mrg    an assembler-computed constant, e.g. a view number, because we
    821  1.1  mrg    can't have relocations in LEB128 quantities.  */
    822  1.1  mrg 
    823  1.1  mrg void
    824  1.1  mrg dw2_asm_output_symname_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
    825  1.1  mrg 				const char *comment, ...)
    826  1.1  mrg {
    827  1.1  mrg   va_list ap;
    828  1.1  mrg 
    829  1.1  mrg   va_start (ap, comment);
    830  1.1  mrg 
    831  1.1  mrg #ifdef HAVE_AS_LEB128
    832  1.1  mrg   fputs ("\t.uleb128 ", asm_out_file);
    833  1.1  mrg   assemble_name (asm_out_file, lab1);
    834  1.1  mrg #else
    835  1.1  mrg   gcc_unreachable ();
    836  1.1  mrg #endif
    837  1.1  mrg 
    838  1.1  mrg   if (flag_debug_asm && comment)
    839  1.1  mrg     {
    840  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    841  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    842  1.1  mrg     }
    843  1.1  mrg   fputc ('\n', asm_out_file);
    844  1.1  mrg 
    845  1.1  mrg   va_end (ap);
    846  1.1  mrg }
    847  1.1  mrg 
    848  1.1  mrg void
    849  1.1  mrg dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
    850  1.1  mrg 			      const char *lab2 ATTRIBUTE_UNUSED,
    851  1.1  mrg 			      const char *comment, ...)
    852  1.1  mrg {
    853  1.1  mrg   va_list ap;
    854  1.1  mrg 
    855  1.1  mrg   va_start (ap, comment);
    856  1.1  mrg 
    857  1.1  mrg   gcc_assert (HAVE_AS_LEB128);
    858  1.1  mrg 
    859  1.1  mrg   fputs ("\t.uleb128 ", asm_out_file);
    860  1.1  mrg   assemble_name (asm_out_file, lab1);
    861  1.1  mrg   putc ('-', asm_out_file);
    862  1.1  mrg   /* dwarf2out.cc might give us a label expression (e.g. .LVL548-1)
    863  1.1  mrg      as second argument.  If so, make it a subexpression, to make
    864  1.1  mrg      sure the substraction is done in the right order.  */
    865  1.1  mrg   if (strchr (lab2, '-') != NULL)
    866  1.1  mrg     {
    867  1.1  mrg       putc ('(', asm_out_file);
    868  1.1  mrg       assemble_name (asm_out_file, lab2);
    869  1.1  mrg       putc (')', asm_out_file);
    870  1.1  mrg     }
    871  1.1  mrg   else
    872  1.1  mrg     assemble_name (asm_out_file, lab2);
    873  1.1  mrg 
    874  1.1  mrg   if (flag_debug_asm && comment)
    875  1.1  mrg     {
    876  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    877  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    878  1.1  mrg     }
    879  1.1  mrg   fputc ('\n', asm_out_file);
    880  1.1  mrg 
    881  1.1  mrg   va_end (ap);
    882  1.1  mrg }
    883  1.1  mrg 
    884  1.1  mrg #if 0
    885  1.1  mrg 
    886  1.1  mrg void
    887  1.1  mrg dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
    888  1.1  mrg 			      const char *lab2 ATTRIBUTE_UNUSED,
    889  1.1  mrg 			      const char *comment, ...)
    890  1.1  mrg {
    891  1.1  mrg   va_list ap;
    892  1.1  mrg 
    893  1.1  mrg   va_start (ap, comment);
    894  1.1  mrg 
    895  1.1  mrg   gcc_assert (HAVE_AS_LEB128);
    896  1.1  mrg 
    897  1.1  mrg   fputs ("\t.sleb128 ", asm_out_file);
    898  1.1  mrg   assemble_name (asm_out_file, lab1);
    899  1.1  mrg   putc ('-', asm_out_file);
    900  1.1  mrg   assemble_name (asm_out_file, lab2);
    901  1.1  mrg 
    902  1.1  mrg   if (flag_debug_asm && comment)
    903  1.1  mrg     {
    904  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
    905  1.1  mrg       vfprintf (asm_out_file, comment, ap);
    906  1.1  mrg     }
    907  1.1  mrg   fputc ('\n', asm_out_file);
    908  1.1  mrg 
    909  1.1  mrg   va_end (ap);
    910  1.1  mrg }
    911  1.1  mrg #endif /* 0 */
    912  1.1  mrg 
    913  1.1  mrg static GTY(()) hash_map<const char *, tree> *indirect_pool;
    915  1.1  mrg 
    916  1.1  mrg static GTY(()) int dw2_const_labelno;
    917  1.1  mrg 
    918  1.1  mrg #if defined(HAVE_GAS_HIDDEN)
    919  1.1  mrg # define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY && !XCOFF_DEBUGGING_INFO)
    920  1.1  mrg #else
    921  1.1  mrg # define USE_LINKONCE_INDIRECT 0
    922  1.1  mrg #endif
    923  1.1  mrg 
    924  1.1  mrg /* Compare two std::pair<const char *, tree> by their first element.
    925  1.1  mrg    Returns <0, 0, or
    926  1.1  mrg    >0 to indicate whether K1 is less than, equal to, or greater than
    927  1.1  mrg    K2, respectively.  */
    928  1.1  mrg 
    929  1.1  mrg static int
    930  1.1  mrg compare_strings (const void *a, const void *b)
    931  1.1  mrg {
    932  1.1  mrg   const char *s1 = ((const std::pair<const char *, tree> *) a)->first;
    933  1.1  mrg   const char *s2 = ((const std::pair<const char *, tree> *) b)->first;
    934  1.1  mrg   int ret;
    935  1.1  mrg 
    936  1.1  mrg   if (s1 == s2)
    937  1.1  mrg     return 0;
    938  1.1  mrg 
    939  1.1  mrg   ret = strcmp (s1, s2);
    940  1.1  mrg 
    941  1.1  mrg   /* The strings are always those from IDENTIFIER_NODEs, and,
    942  1.1  mrg      therefore, we should never have two copies of the same
    943  1.1  mrg      string.  */
    944  1.1  mrg   gcc_assert (ret);
    945  1.1  mrg 
    946  1.1  mrg   return ret;
    947  1.1  mrg }
    948  1.1  mrg 
    949  1.1  mrg /* Put X, a SYMBOL_REF, in memory.  Return a SYMBOL_REF to the allocated
    950  1.1  mrg    memory.  Differs from force_const_mem in that a single pool is used for
    951  1.1  mrg    the entire unit of translation, and the memory is not guaranteed to be
    952  1.1  mrg    "near" the function in any interesting sense.  IS_PUBLIC controls whether
    953  1.1  mrg    the symbol can be shared across the entire application (or DSO).  */
    954  1.1  mrg 
    955  1.1  mrg rtx
    956  1.1  mrg dw2_force_const_mem (rtx x, bool is_public)
    957  1.1  mrg {
    958  1.1  mrg   const char *key;
    959  1.1  mrg   tree decl_id;
    960  1.1  mrg 
    961  1.1  mrg   if (! indirect_pool)
    962  1.1  mrg     indirect_pool = hash_map<const char *, tree>::create_ggc (64);
    963  1.1  mrg 
    964  1.1  mrg   gcc_assert (GET_CODE (x) == SYMBOL_REF);
    965  1.1  mrg 
    966  1.1  mrg   key = XSTR (x, 0);
    967  1.1  mrg   tree *slot = indirect_pool->get (key);
    968  1.1  mrg   if (slot)
    969  1.1  mrg     decl_id = *slot;
    970  1.1  mrg   else
    971  1.1  mrg     {
    972  1.1  mrg       tree id;
    973  1.1  mrg       const char *str = targetm.strip_name_encoding (key);
    974  1.1  mrg 
    975  1.1  mrg       if (is_public && USE_LINKONCE_INDIRECT)
    976  1.1  mrg 	{
    977  1.1  mrg 	  char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
    978  1.1  mrg 
    979  1.1  mrg 	  sprintf (ref_name, "DW.ref.%s", str);
    980  1.1  mrg 	  gcc_assert (!maybe_get_identifier (ref_name));
    981  1.1  mrg 	  decl_id = get_identifier (ref_name);
    982  1.1  mrg 	  TREE_PUBLIC (decl_id) = 1;
    983  1.1  mrg 	}
    984  1.1  mrg       else
    985  1.1  mrg 	{
    986  1.1  mrg 	  char label[32];
    987  1.1  mrg 
    988  1.1  mrg 	  ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
    989  1.1  mrg 	  ++dw2_const_labelno;
    990  1.1  mrg 	  gcc_assert (!maybe_get_identifier (label));
    991  1.1  mrg 	  decl_id = get_identifier (label);
    992  1.1  mrg 	}
    993  1.1  mrg 
    994  1.1  mrg       id = maybe_get_identifier (str);
    995  1.1  mrg       if (id)
    996  1.1  mrg 	TREE_SYMBOL_REFERENCED (id) = 1;
    997  1.1  mrg 
    998  1.1  mrg       indirect_pool->put (key, decl_id);
    999  1.1  mrg     }
   1000  1.1  mrg 
   1001  1.1  mrg   return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
   1002  1.1  mrg }
   1003  1.1  mrg 
   1004  1.1  mrg /* A helper function for dw2_output_indirect_constants.  Emit one queued
   1005  1.1  mrg    constant to memory.  */
   1006  1.1  mrg 
   1007  1.1  mrg static int
   1008  1.1  mrg dw2_output_indirect_constant_1 (const char *sym, tree id)
   1009  1.1  mrg {
   1010  1.1  mrg   rtx sym_ref;
   1011  1.1  mrg   tree decl;
   1012  1.1  mrg 
   1013  1.1  mrg   decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
   1014  1.1  mrg   SET_DECL_ASSEMBLER_NAME (decl, id);
   1015  1.1  mrg   DECL_ARTIFICIAL (decl) = 1;
   1016  1.1  mrg   DECL_IGNORED_P (decl) = 1;
   1017  1.1  mrg   DECL_INITIAL (decl) = build_fold_addr_expr (decl);
   1018  1.1  mrg   TREE_READONLY (decl) = 1;
   1019  1.1  mrg   TREE_STATIC (decl) = 1;
   1020  1.1  mrg 
   1021  1.1  mrg   if (TREE_PUBLIC (id))
   1022  1.1  mrg     {
   1023  1.1  mrg       TREE_PUBLIC (decl) = 1;
   1024  1.1  mrg       make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
   1025  1.1  mrg       if (USE_LINKONCE_INDIRECT)
   1026  1.1  mrg 	DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
   1027  1.1  mrg     }
   1028  1.1  mrg 
   1029  1.1  mrg   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
   1030  1.1  mrg   /* Disable ASan for decl because redzones cause ABI breakage between GCC and
   1031  1.1  mrg      libstdc++ for `.LDFCM*' variables.  See PR 78651 for details.  */
   1032  1.1  mrg   unsigned int save_flag_sanitize = flag_sanitize;
   1033  1.1  mrg   flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS
   1034  1.1  mrg 		     | SANITIZE_KERNEL_ADDRESS);
   1035  1.1  mrg   /* And also temporarily disable -fsection-anchors.  These indirect constants
   1036  1.1  mrg      are never referenced from code, so it doesn't make any sense to aggregate
   1037  1.1  mrg      them in blocks.  */
   1038  1.1  mrg   int save_flag_section_anchors = flag_section_anchors;
   1039  1.1  mrg   flag_section_anchors = 0;
   1040  1.1  mrg   assemble_variable (decl, 1, 1, 1);
   1041  1.1  mrg   flag_section_anchors = save_flag_section_anchors;
   1042  1.1  mrg   flag_sanitize = save_flag_sanitize;
   1043  1.1  mrg   assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
   1044  1.1  mrg   /* The following is a hack recognized by use_blocks_for_decl_p to disable
   1045  1.1  mrg      section anchor handling of the decl.  */
   1046  1.1  mrg   DECL_INITIAL (decl) = decl;
   1047  1.1  mrg 
   1048  1.1  mrg   return 0;
   1049  1.1  mrg }
   1050  1.1  mrg 
   1051  1.1  mrg /* Emit the constants queued through dw2_force_const_mem.  */
   1052  1.1  mrg 
   1053  1.1  mrg void
   1054  1.1  mrg dw2_output_indirect_constants (void)
   1055  1.1  mrg {
   1056  1.1  mrg   if (!indirect_pool)
   1057  1.1  mrg     return;
   1058  1.1  mrg 
   1059  1.1  mrg   auto_vec<std::pair<const char *, tree> > temp (indirect_pool->elements ());
   1060  1.1  mrg   for (hash_map<const char *, tree>::iterator iter = indirect_pool->begin ();
   1061  1.1  mrg        iter != indirect_pool->end (); ++iter)
   1062  1.1  mrg     temp.quick_push (*iter);
   1063  1.1  mrg 
   1064  1.1  mrg   temp.qsort (compare_strings);
   1065  1.1  mrg 
   1066  1.1  mrg   for (unsigned int i = 0; i < temp.length (); i++)
   1067  1.1  mrg     dw2_output_indirect_constant_1 (temp[i].first, temp[i].second);
   1068  1.1  mrg }
   1069  1.1  mrg 
   1070  1.1  mrg /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
   1071  1.1  mrg    If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
   1072  1.1  mrg    reference is shared across the entire application (or DSO).  */
   1073  1.1  mrg 
   1074  1.1  mrg void
   1075  1.1  mrg dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
   1076  1.1  mrg 				 const char *comment, ...)
   1077  1.1  mrg {
   1078  1.1  mrg   int size;
   1079  1.1  mrg   va_list ap;
   1080  1.1  mrg 
   1081  1.1  mrg   va_start (ap, comment);
   1082  1.1  mrg 
   1083  1.1  mrg   size = size_of_encoded_value (encoding);
   1084  1.1  mrg 
   1085  1.1  mrg   if (encoding == DW_EH_PE_aligned)
   1086  1.1  mrg     {
   1087  1.1  mrg       assemble_align (POINTER_SIZE);
   1088  1.1  mrg       assemble_integer (addr, size, POINTER_SIZE, 1);
   1089  1.1  mrg       va_end (ap);
   1090  1.1  mrg       return;
   1091  1.1  mrg     }
   1092  1.1  mrg 
   1093  1.1  mrg   /* NULL is _always_ represented as a plain zero, as is 1 for Ada's
   1094  1.1  mrg      "all others".  */
   1095  1.1  mrg   if (addr == const0_rtx || addr == const1_rtx)
   1096  1.1  mrg     assemble_integer (addr, size, BITS_PER_UNIT, 1);
   1097  1.1  mrg   else
   1098  1.1  mrg     {
   1099  1.1  mrg     restart:
   1100  1.1  mrg       /* Allow the target first crack at emitting this.  Some of the
   1101  1.1  mrg 	 special relocations require special directives instead of
   1102  1.1  mrg 	 just ".4byte" or whatever.  */
   1103  1.1  mrg #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
   1104  1.1  mrg       ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (asm_out_file, encoding, size,
   1105  1.1  mrg 					 addr, done);
   1106  1.1  mrg #endif
   1107  1.1  mrg 
   1108  1.1  mrg       /* Indirection is used to get dynamic relocations out of a
   1109  1.1  mrg 	 read-only section.  */
   1110  1.1  mrg       if (encoding & DW_EH_PE_indirect)
   1111  1.1  mrg 	{
   1112  1.1  mrg 	  /* It is very tempting to use force_const_mem so that we share data
   1113  1.1  mrg 	     with the normal constant pool.  However, we've already emitted
   1114  1.1  mrg 	     the constant pool for this function.  Moreover, we'd like to
   1115  1.1  mrg 	     share these constants across the entire unit of translation and
   1116  1.1  mrg 	     even, if possible, across the entire application (or DSO).  */
   1117  1.1  mrg 	  addr = dw2_force_const_mem (addr, is_public);
   1118  1.1  mrg 	  encoding &= ~DW_EH_PE_indirect;
   1119  1.1  mrg 	  goto restart;
   1120  1.1  mrg 	}
   1121  1.1  mrg 
   1122  1.1  mrg       switch (encoding & 0xF0)
   1123  1.1  mrg 	{
   1124  1.1  mrg 	case DW_EH_PE_absptr:
   1125  1.1  mrg 	  dw2_assemble_integer (size, addr);
   1126  1.1  mrg 	  break;
   1127  1.1  mrg 
   1128  1.1  mrg #ifdef ASM_OUTPUT_DWARF_DATAREL
   1129  1.1  mrg 	case DW_EH_PE_datarel:
   1130  1.1  mrg 	  gcc_assert (GET_CODE (addr) == SYMBOL_REF);
   1131  1.1  mrg 	  ASM_OUTPUT_DWARF_DATAREL (asm_out_file, size, XSTR (addr, 0));
   1132  1.1  mrg 	  break;
   1133  1.1  mrg #endif
   1134  1.1  mrg 
   1135  1.1  mrg 	case DW_EH_PE_pcrel:
   1136  1.1  mrg 	  gcc_assert (GET_CODE (addr) == SYMBOL_REF);
   1137  1.1  mrg #ifdef ASM_OUTPUT_DWARF_PCREL
   1138  1.1  mrg 	  ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
   1139  1.1  mrg #else
   1140  1.1  mrg 	  dw2_assemble_integer (size, gen_rtx_MINUS (Pmode, addr, pc_rtx));
   1141  1.1  mrg #endif
   1142  1.1  mrg 	  break;
   1143  1.1  mrg 
   1144  1.1  mrg 	default:
   1145  1.1  mrg 	  /* Other encodings should have been handled by
   1146  1.1  mrg 	     ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX.  */
   1147  1.1  mrg 	  gcc_unreachable ();
   1148  1.1  mrg 	}
   1149  1.1  mrg 
   1150  1.1  mrg #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
   1151  1.1  mrg     done:;
   1152  1.1  mrg #endif
   1153  1.1  mrg     }
   1154  1.1  mrg 
   1155  1.1  mrg   if (flag_debug_asm && comment)
   1156  1.1  mrg     {
   1157  1.1  mrg       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
   1158  1.1  mrg       vfprintf (asm_out_file, comment, ap);
   1159  1.1  mrg     }
   1160  1.1  mrg   fputc ('\n', asm_out_file);
   1161  1.1  mrg 
   1162  1.1  mrg   va_end (ap);
   1163           }
   1164           
   1165           #include "gt-dwarf2asm.h"
   1166