LCOV - code coverage report
Current view: top level - gcc - dwarf2asm.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.9 % 333 296
Test Date: 2026-02-28 14:20:25 Functions: 95.8 % 24 23
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.