OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2asm.c
index 6e6a5d0..eefc29f 100644 (file)
@@ -1,11 +1,12 @@
 /* Dwarf2 assembler output helper routines.
 /* Dwarf2 assembler output helper routines.
-   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -14,13 +15,14 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 #include "config.h"
 #include "system.h"
 
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "flags.h"
 #include "tree.h"
 #include "rtl.h"
 #include "flags.h"
 #include "tree.h"
 #include "rtl.h"
@@ -43,17 +45,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    to print a newline, since the caller may want to add a comment.  */
 
 void
    to print a newline, since the caller may want to add a comment.  */
 
 void
-dw2_assemble_integer (size, x)
-     int size;
-     rtx x;
+dw2_assemble_integer (int size, rtx x)
 {
   const char *op = integer_asm_op (size, FALSE);
 
   if (op)
     {
       fputs (op, asm_out_file);
 {
   const char *op = integer_asm_op (size, FALSE);
 
   if (op)
     {
       fputs (op, asm_out_file);
-      if (GET_CODE (x) == CONST_INT)
-       fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
+      if (CONST_INT_P (x))
+       fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX,
+                (unsigned HOST_WIDE_INT) INTVAL (x));
       else
        output_addr_const (asm_out_file, x);
     }
       else
        output_addr_const (asm_out_file, x);
     }
@@ -62,21 +63,52 @@ dw2_assemble_integer (size, x)
 }
 
 
 }
 
 
-/* Output an immediate constant in a given size.  */
+/* Output a value of a given size in target byte order.  */
 
 void
 
 void
-dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
-                             const char *comment, ...))
+dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, size);
-  VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
-  VA_FIXEDARG (ap, const char *, comment);
+  unsigned char bytes[8];
+  int i;
+
+  for (i = 0; i < 8; ++i)
+    {
+      bytes[i] = value & 0xff;
+      value >>= 8;
+    }
+
+  if (BYTES_BIG_ENDIAN)
+    {
+      for (i = size - 1; i > 0; --i)
+       fprintf (asm_out_file, "%#x,", bytes[i]);
+      fprintf (asm_out_file, "%#x", bytes[0]);
+    }
+  else
+    {
+      for (i = 0; i < size - 1; ++i)
+       fprintf (asm_out_file, "%#x,", bytes[i]);
+      fprintf (asm_out_file, "%#x", bytes[i]);
+    }
+}
+
+/* Output an immediate constant in a given SIZE in bytes.  */
+
+void
+dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
+                    const char *comment, ...)
+{
+  va_list ap;
+  const char *op = integer_asm_op (size, FALSE);
+
+  va_start (ap, comment);
 
   if (size * 8 < HOST_BITS_PER_WIDE_INT)
     value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
 
 
   if (size * 8 < HOST_BITS_PER_WIDE_INT)
     value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
 
-  dw2_assemble_integer (size, GEN_INT (value));
+  if (op)
+    fprintf (asm_out_file, "%s" HOST_WIDE_INT_PRINT_HEX, op, value);
+  else
+    assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
 
   if (flag_debug_asm && comment)
     {
 
   if (flag_debug_asm && comment)
     {
@@ -85,7 +117,7 @@ dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 /* Output the difference between two symbols in a given size.  */
 }
 
 /* Output the difference between two symbols in a given size.  */
@@ -95,47 +127,78 @@ dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
    symbol must appear after both symbols are defined.  */
 
 void
    symbol must appear after both symbols are defined.  */
 
 void
-dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
-                              const char *comment, ...))
+dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
+                     const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, size);
-  VA_FIXEDARG (ap, const char *, lab1);
-  VA_FIXEDARG (ap, const char *, lab2);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 
+#ifdef ASM_OUTPUT_DWARF_DELTA
+  ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
+#else
   dw2_assemble_integer (size,
                        gen_rtx_MINUS (Pmode,
                                       gen_rtx_SYMBOL_REF (Pmode, lab1),
                                       gen_rtx_SYMBOL_REF (Pmode, lab2)));
   dw2_assemble_integer (size,
                        gen_rtx_MINUS (Pmode,
                                       gen_rtx_SYMBOL_REF (Pmode, lab1),
                                       gen_rtx_SYMBOL_REF (Pmode, lab2)));
+#endif
+  if (flag_debug_asm && comment)
+    {
+      fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
+      vfprintf (asm_out_file, comment, ap);
+    }
+  fputc ('\n', asm_out_file);
+
+  va_end (ap);
+}
+
+/* Output the difference between two symbols in instruction units
+   in a given size.  */
+
+void
+dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED,
+                         const char *lab1, const char *lab2,
+                         const char *comment, ...)
+{
+  va_list ap;
 
 
+  va_start (ap, comment);
+
+#ifndef ASM_OUTPUT_DWARF_VMS_DELTA
+  /* VMS Delta is only special on ia64-vms, but this funtion also gets
+     called on alpha-vms so it has to do something sane.  */
+  dw2_asm_output_delta (size, lab1, lab2, comment);
+#else
+  ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2);
   if (flag_debug_asm && comment)
     {
       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
       vfprintf (asm_out_file, comment, ap);
     }
   fputc ('\n', asm_out_file);
   if (flag_debug_asm && comment)
     {
       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
       vfprintf (asm_out_file, comment, ap);
     }
   fputc ('\n', asm_out_file);
+#endif
 
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 }
 
-/* Output a section-relative reference to a label.  In general this
-   can only be done for debugging symbols.  E.g. on most targets with
-   the GNU linker, this is accomplished with a direct reference and
-   the knowledge that the debugging section will be placed at VMA 0.
-   Some targets have special relocations for this that we must use.  */
+/* Output a section-relative reference to a LABEL, which was placed in
+   BASE.  In general this can only be done for debugging symbols.
+   E.g. on most targets with the GNU linker, this is accomplished with
+   a direct reference and the knowledge that the debugging section
+   will be placed at VMA 0.  Some targets have special relocations for
+   this that we must use.  */
 
 void
 
 void
-dw2_asm_output_offset VPARAMS ((int size, const char *label,
-                              const char *comment, ...))
+dw2_asm_output_offset (int size, const char *label,
+                      section *base ATTRIBUTE_UNUSED,
+                      const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, size);
-  VA_FIXEDARG (ap, const char *, label);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 #ifdef ASM_OUTPUT_DWARF_OFFSET
 
 #ifdef ASM_OUTPUT_DWARF_OFFSET
-  ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
+  ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, base);
 #else
   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
 #endif
 #else
   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
 #endif
@@ -147,21 +210,22 @@ dw2_asm_output_offset VPARAMS ((int size, const char *label,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 }
 
+#if 0
+
 /* Output a self-relative reference to a label, possibly in a
    different section or object file.  */
 
 void
 /* Output a self-relative reference to a label, possibly in a
    different section or object file.  */
 
 void
-dw2_asm_output_pcrel VPARAMS ((int size ATTRIBUTE_UNUSED,
-                              const char *label ATTRIBUTE_UNUSED,
-                              const char *comment, ...))
+dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
+                     const char *label ATTRIBUTE_UNUSED,
+                     const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, size);
-  VA_FIXEDARG (ap, const char *, label);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 #ifdef ASM_OUTPUT_DWARF_PCREL
   ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
 
 #ifdef ASM_OUTPUT_DWARF_PCREL
   ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
@@ -179,19 +243,19 @@ dw2_asm_output_pcrel VPARAMS ((int size ATTRIBUTE_UNUSED,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 }
+#endif /* 0 */
 
 /* Output an absolute reference to a label.  */
 
 void
 
 /* Output an absolute reference to a label.  */
 
 void
-dw2_asm_output_addr VPARAMS ((int size, const char *label,
-                             const char *comment, ...))
+dw2_asm_output_addr (int size, const char *label,
+                    const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, size);
-  VA_FIXEDARG (ap, const char *, label);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
 
 
   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
 
@@ -202,19 +266,18 @@ dw2_asm_output_addr VPARAMS ((int size, const char *label,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 /* Similar, but use an RTX expression instead of a text label.  */
 
 void
 }
 
 /* Similar, but use an RTX expression instead of a text label.  */
 
 void
-dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
-                                 const char *comment, ...))
+dw2_asm_output_addr_rtx (int size, rtx addr,
+                        const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, size);
-  VA_FIXEDARG (ap, rtx, addr);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
   dw2_assemble_integer (size, addr);
 
 
   dw2_assemble_integer (size, addr);
 
@@ -225,19 +288,24 @@ dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 }
 
+/* Output the first ORIG_LEN characters of STR as a string.
+   If ORIG_LEN is equal to -1, ignore this parameter and output
+   the entire STR instead.
+   If COMMENT is not NULL and comments in the debug information
+   have been requested by the user, append the given COMMENT
+   to the generated output.  */
+
 void
 void
-dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
-                                const char *comment, ...))
+dw2_asm_output_nstring (const char *str, size_t orig_len,
+                       const char *comment, ...)
 {
   size_t i, len;
 {
   size_t i, len;
+  va_list ap;
 
 
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, const char *, str);
-  VA_FIXEDARG (ap, size_t, orig_len);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_start (ap, comment);
 
   len = orig_len;
 
 
   len = orig_len;
 
@@ -272,21 +340,19 @@ dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
        assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
     }
 
        assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
     }
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 \f
 
 /* Return the size of an unsigned LEB128 quantity.  */
 
 int
 }
 \f
 
 /* Return the size of an unsigned LEB128 quantity.  */
 
 int
-size_of_uleb128 (value)
-     unsigned HOST_WIDE_INT value;
+size_of_uleb128 (unsigned HOST_WIDE_INT value)
 {
 {
-  int size = 0, byte;
+  int size = 0;
 
   do
     {
 
   do
     {
-      byte = (value & 0x7f);
       value >>= 7;
       size += 1;
     }
       value >>= 7;
       size += 1;
     }
@@ -298,8 +364,7 @@ size_of_uleb128 (value)
 /* Return the size of a signed LEB128 quantity.  */
 
 int
 /* Return the size of a signed LEB128 quantity.  */
 
 int
-size_of_sleb128 (value)
-     HOST_WIDE_INT value;
+size_of_sleb128 (HOST_WIDE_INT value)
 {
   int size = 0, byte;
 
 {
   int size = 0, byte;
 
@@ -320,8 +385,7 @@ size_of_sleb128 (value)
    include leb128.  */
 
 int
    include leb128.  */
 
 int
-size_of_encoded_value (encoding)
-     int encoding;
+size_of_encoded_value (int encoding)
 {
   if (encoding == DW_EH_PE_omit)
     return 0;
 {
   if (encoding == DW_EH_PE_omit)
     return 0;
@@ -336,15 +400,15 @@ size_of_encoded_value (encoding)
       return 4;
     case DW_EH_PE_udata8:
       return 8;
       return 4;
     case DW_EH_PE_udata8:
       return 8;
+    default:
+      gcc_unreachable ();
     }
     }
-  abort ();
 }
 
 /* Yield a name for a given pointer encoding.  */
 
 const char *
 }
 
 /* Yield a name for a given pointer encoding.  */
 
 const char *
-eh_data_format_name (format)
-     int format;
+eh_data_format_name (int format)
 {
 #if HAVE_DESIGNATED_INITIALIZERS
 #define S(p, v)                [p] = v,
 {
 #if HAVE_DESIGNATED_INITIALIZERS
 #define S(p, v)                [p] = v,
@@ -411,6 +475,8 @@ eh_data_format_name (format)
   S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
   S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
 
   S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
   S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
 
+  S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
+
   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
     "indirect pcrel")
   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
   S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
     "indirect pcrel")
   S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
@@ -490,28 +556,47 @@ eh_data_format_name (format)
 #if HAVE_DESIGNATED_INITIALIZERS
   };
 
 #if HAVE_DESIGNATED_INITIALIZERS
   };
 
-  if (format < 0 || format > 0xff || format_names[format] == NULL)
-    abort ();
+  gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
+
   return format_names[format];
 #else
   }
   return format_names[format];
 #else
   }
-  abort ();
+  gcc_unreachable ();
 #endif
 }
 
 #endif
 }
 
+/* Output an unsigned LEB128 quantity, but only the byte values.  */
+
+void
+dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value)
+{
+  while (1)
+    {
+      int byte = (value & 0x7f);
+      value >>= 7;
+      if (value != 0)
+       /* More bytes to follow.  */
+       byte |= 0x80;
+
+      fprintf (asm_out_file, "%#x", byte);
+      if (value == 0)
+       break;
+      fputc (',', asm_out_file);
+    }
+}
+
 /* Output an unsigned LEB128 quantity.  */
 
 void
 /* Output an unsigned LEB128 quantity.  */
 
 void
-dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
-                                     const char *comment, ...))
+dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
+                            const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 #ifdef HAVE_AS_LEB128
 
 #ifdef HAVE_AS_LEB128
-  fputs ("\t.uleb128 ", asm_out_file);
-  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
+  fprintf (asm_out_file, "\t.uleb128 " HOST_WIDE_INT_PRINT_HEX , value);
 
   if (flag_debug_asm && comment)
     {
 
   if (flag_debug_asm && comment)
     {
@@ -535,7 +620,7 @@ dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
 
        if (byte_op)
          {
 
        if (byte_op)
          {
-           fprintf (asm_out_file, "0x%x", byte);
+           fprintf (asm_out_file, "%#x", byte);
            if (work != 0)
              fputc (',', asm_out_file);
          }
            if (work != 0)
              fputc (',', asm_out_file);
          }
@@ -546,8 +631,8 @@ dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
 
   if (flag_debug_asm)
     {
 
   if (flag_debug_asm)
     {
-      fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
-      fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
+      fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
+              ASM_COMMENT_START, value);
       if (comment)
        {
          fputs ("; ", asm_out_file);
       if (comment)
        {
          fputs ("; ", asm_out_file);
@@ -558,22 +643,44 @@ dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
 #endif
   fputc ('\n', asm_out_file);
 
 #endif
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
+}
+
+/* Output an signed LEB128 quantity, but only the byte values.  */
+
+void
+dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value)
+{
+  int byte, more;
+
+  while (1)
+    {
+      byte = (value & 0x7f);
+      value >>= 7;
+      more = !((value == 0 && (byte & 0x40) == 0)
+               || (value == -1 && (byte & 0x40) != 0));
+      if (more)
+       byte |= 0x80;
+
+      fprintf (asm_out_file, "%#x", byte);
+      if (!more)
+       break;
+      fputc (',', asm_out_file);
+    }
 }
 
 }
 
-/* Output an signed LEB128 quantity.  */
+/* Output a signed LEB128 quantity.  */
 
 void
 
 void
-dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
-                                     const char *comment, ...))
+dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
+                            const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, HOST_WIDE_INT, value);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 #ifdef HAVE_AS_LEB128
 
 #ifdef HAVE_AS_LEB128
-  fputs ("\t.sleb128 ", asm_out_file);
-  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
+  fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
 
   if (flag_debug_asm && comment)
     {
 
   if (flag_debug_asm && comment)
     {
@@ -600,7 +707,7 @@ dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
 
        if (byte_op)
          {
 
        if (byte_op)
          {
-           fprintf (asm_out_file, "0x%x", byte);
+           fprintf (asm_out_file, "%#x", byte);
            if (more)
              fputc (',', asm_out_file);
          }
            if (more)
              fputc (',', asm_out_file);
          }
@@ -611,8 +718,8 @@ dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
 
   if (flag_debug_asm)
     {
 
   if (flag_debug_asm)
     {
-      fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
-      fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
+      fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
+              ASM_COMMENT_START, value);
       if (comment)
        {
          fputs ("; ", asm_out_file);
       if (comment)
        {
          fputs ("; ", asm_out_file);
@@ -623,18 +730,17 @@ dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
 #endif
   fputc ('\n', asm_out_file);
 
 #endif
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 void
 }
 
 void
-dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
-                                      const char *lab2 ATTRIBUTE_UNUSED,
-                                      const char *comment, ...))
+dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
+                             const char *lab2 ATTRIBUTE_UNUSED,
+                             const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, const char *, lab1);
-  VA_FIXEDARG (ap, const char *, lab2);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 #ifdef HAVE_AS_LEB128
   fputs ("\t.uleb128 ", asm_out_file);
 
 #ifdef HAVE_AS_LEB128
   fputs ("\t.uleb128 ", asm_out_file);
@@ -642,7 +748,7 @@ dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
   fputc ('-', asm_out_file);
   assemble_name (asm_out_file, lab2);
 #else
   fputc ('-', asm_out_file);
   assemble_name (asm_out_file, lab2);
 #else
-  abort ();
+  gcc_unreachable ();
 #endif
 
   if (flag_debug_asm && comment)
 #endif
 
   if (flag_debug_asm && comment)
@@ -652,18 +758,19 @@ dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 }
 
+#if 0
+
 void
 void
-dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
-                                      const char *lab2 ATTRIBUTE_UNUSED,
-                                      const char *comment, ...))
+dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
+                             const char *lab2 ATTRIBUTE_UNUSED,
+                             const char *comment, ...)
 {
 {
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, const char *, lab1);
-  VA_FIXEDARG (ap, const char *, lab2);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_list ap;
+
+  va_start (ap, comment);
 
 #ifdef HAVE_AS_LEB128
   fputs ("\t.sleb128 ", asm_out_file);
 
 #ifdef HAVE_AS_LEB128
   fputs ("\t.sleb128 ", asm_out_file);
@@ -671,7 +778,7 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
   fputc ('-', asm_out_file);
   assemble_name (asm_out_file, lab2);
 #else
   fputc ('-', asm_out_file);
   assemble_name (asm_out_file, lab2);
 #else
-  abort ();
+  gcc_unreachable ();
 #endif
 
   if (flag_debug_asm && comment)
 #endif
 
   if (flag_debug_asm && comment)
@@ -681,125 +788,141 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 }
+#endif /* 0 */
 \f
 \f
-static int mark_indirect_pool_entry PARAMS ((splay_tree_node, void *));
-static void mark_indirect_pool PARAMS ((PTR arg));
-static rtx dw2_force_const_mem PARAMS ((rtx));
-static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *));
+static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
+
+static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
 
 
-static splay_tree indirect_pool;
+static GTY(()) int dw2_const_labelno;
 
 
-#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
-# define USE_LINKONCE_INDIRECT 1
+#if defined(HAVE_GAS_HIDDEN)
+# define USE_LINKONCE_INDIRECT (SUPPORTS_ONE_ONLY)
 #else
 # define USE_LINKONCE_INDIRECT 0
 #endif
 
 #else
 # define USE_LINKONCE_INDIRECT 0
 #endif
 
-/* Mark all indirect constants for GC.  */
+/* Comparison function for a splay tree in which the keys are strings.
+   K1 and K2 have the dynamic type "const char *".  Returns <0, 0, or
+   >0 to indicate whether K1 is less than, equal to, or greater than
+   K2, respectively.  */
 
 static int
 
 static int
-mark_indirect_pool_entry (node, data)
-     splay_tree_node node;
-     void* data ATTRIBUTE_UNUSED;
+splay_tree_compare_strings (splay_tree_key k1, splay_tree_key k2)
 {
 {
-  ggc_mark_tree ((tree) node->value);
-  return 0;
-}
+  const char *s1 = (const char *)k1;
+  const char *s2 = (const char *)k2;
+  int ret;
 
 
-/* Mark all indirect constants for GC.  */
+  if (s1 == s2)
+    return 0;
 
 
-static void
-mark_indirect_pool (arg)
-     PTR arg ATTRIBUTE_UNUSED;
-{
-  splay_tree_foreach (indirect_pool, mark_indirect_pool_entry, NULL);
+  ret = strcmp (s1, s2);
+
+  /* The strings are always those from IDENTIFIER_NODEs, and,
+     therefore, we should never have two copies of the same
+     string.  */
+  gcc_assert (ret);
+
+  return ret;
 }
 
 /* Put X, a SYMBOL_REF, in memory.  Return a SYMBOL_REF to the allocated
    memory.  Differs from force_const_mem in that a single pool is used for
    the entire unit of translation, and the memory is not guaranteed to be
 }
 
 /* Put X, a SYMBOL_REF, in memory.  Return a SYMBOL_REF to the allocated
    memory.  Differs from force_const_mem in that a single pool is used for
    the entire unit of translation, and the memory is not guaranteed to be
-   "near" the function in any interesting sense.  */
+   "near" the function in any interesting sense.  IS_PUBLIC controls whether
+   the symbol can be shared across the entire application (or DSO).  */
 
 
-static rtx
-dw2_force_const_mem (x)
-     rtx x;
+rtx
+dw2_force_const_mem (rtx x, bool is_public)
 {
   splay_tree_node node;
 {
   splay_tree_node node;
-  const char *str;
-  tree decl;
+  const char *key;
+  tree decl_id;
 
   if (! indirect_pool)
 
   if (! indirect_pool)
-    {
-      indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
-      ggc_add_root (&indirect_pool, 1, sizeof indirect_pool, mark_indirect_pool);
-    }
+    /* We use strcmp, rather than just comparing pointers, so that the
+       sort order will not depend on the host system.  */
+    indirect_pool = splay_tree_new_ggc (splay_tree_compare_strings,
+                                       ggc_alloc_splay_tree_str_tree_node_splay_tree_s,
+                                       ggc_alloc_splay_tree_str_tree_node_splay_tree_node_s);
 
 
-  if (GET_CODE (x) != SYMBOL_REF)
-    abort ();
+  gcc_assert (GET_CODE (x) == SYMBOL_REF);
 
 
-  str = (* targetm.strip_name_encoding) (XSTR (x, 0));
-  node = splay_tree_lookup (indirect_pool, (splay_tree_key) str);
+  key = XSTR (x, 0);
+  node = splay_tree_lookup (indirect_pool, (splay_tree_key) key);
   if (node)
   if (node)
-    decl = (tree) node->value;
+    decl_id = (tree) node->value;
   else
     {
       tree id;
   else
     {
       tree id;
+      const char *str = targetm.strip_name_encoding (key);
 
 
-      if (USE_LINKONCE_INDIRECT)
+      if (is_public && USE_LINKONCE_INDIRECT)
        {
        {
-         char *ref_name = alloca (strlen (str) + sizeof "DW.ref.");
+         char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
 
          sprintf (ref_name, "DW.ref.%s", str);
 
          sprintf (ref_name, "DW.ref.%s", str);
-         id = get_identifier (ref_name);
-         decl = build_decl (VAR_DECL, id, ptr_type_node);
-         DECL_ARTIFICIAL (decl) = 1;
-         TREE_PUBLIC (decl) = 1;
-         DECL_INITIAL (decl) = decl;
-         make_decl_one_only (decl);
+         gcc_assert (!maybe_get_identifier (ref_name));
+         decl_id = get_identifier (ref_name);
+         TREE_PUBLIC (decl_id) = 1;
        }
       else
        {
        }
       else
        {
-         extern int const_labelno;
          char label[32];
 
          char label[32];
 
-         ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
-         ++const_labelno;
-         id = get_identifier (label);
-         decl = build_decl (VAR_DECL, id, ptr_type_node);
-         DECL_ARTIFICIAL (decl) = 1;
-         TREE_STATIC (decl) = 1;
-         DECL_INITIAL (decl) = decl;
+         ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
+         ++dw2_const_labelno;
+         gcc_assert (!maybe_get_identifier (label));
+         decl_id = get_identifier (label);
        }
 
       id = maybe_get_identifier (str);
       if (id)
        TREE_SYMBOL_REFERENCED (id) = 1;
 
        }
 
       id = maybe_get_identifier (str);
       if (id)
        TREE_SYMBOL_REFERENCED (id) = 1;
 
-      splay_tree_insert (indirect_pool, (splay_tree_key) str,
-                        (splay_tree_value) decl);
+      splay_tree_insert (indirect_pool, (splay_tree_key) key,
+                        (splay_tree_value) decl_id);
     }
 
     }
 
-  return XEXP (DECL_RTL (decl), 0);
+  return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
 }
 
 /* A helper function for dw2_output_indirect_constants called through
    splay_tree_foreach.  Emit one queued constant to memory.  */
 
 static int
 }
 
 /* A helper function for dw2_output_indirect_constants called through
    splay_tree_foreach.  Emit one queued constant to memory.  */
 
 static int
-dw2_output_indirect_constant_1 (node, data)
-     splay_tree_node node;
-     void* data ATTRIBUTE_UNUSED;
+dw2_output_indirect_constant_1 (splay_tree_node node,
+                               void *data ATTRIBUTE_UNUSED)
 {
   const char *sym;
   rtx sym_ref;
 {
   const char *sym;
   rtx sym_ref;
+  tree id, decl;
 
   sym = (const char *) node->key;
 
   sym = (const char *) node->key;
+  id = (tree) node->value;
+
+  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
+  DECL_ARTIFICIAL (decl) = 1;
+  DECL_IGNORED_P (decl) = 1;
+  DECL_INITIAL (decl) = decl;
+  TREE_READONLY (decl) = 1;
+
+  if (TREE_PUBLIC (id))
+    {
+      TREE_PUBLIC (decl) = 1;
+      make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
+    }
+  else
+    TREE_STATIC (decl) = 1;
+
   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
-  if (USE_LINKONCE_INDIRECT)
-    fprintf (asm_out_file, "\t.hidden DW.ref.%s\n", sym);
-  assemble_variable ((tree) node->value, 1, 1, 1);
+  sym = targetm.strip_name_encoding (sym);
+  if (TREE_PUBLIC (decl) && USE_LINKONCE_INDIRECT)
+    fprintf (asm_out_file, "\t.hidden %sDW.ref.%s\n", user_label_prefix, sym);
+  assemble_variable (decl, 1, 1, 1);
   assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
 
   return 0;
   assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
 
   return 0;
@@ -808,25 +931,24 @@ dw2_output_indirect_constant_1 (node, data)
 /* Emit the constants queued through dw2_force_const_mem.  */
 
 void
 /* Emit the constants queued through dw2_force_const_mem.  */
 
 void
-dw2_output_indirect_constants ()
+dw2_output_indirect_constants (void)
 {
   if (indirect_pool)
     splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
 }
 
 {
   if (indirect_pool)
     splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
 }
 
-/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.  */
+/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed.
+   If PUBLIC is set and the encoding is DW_EH_PE_indirect, the indirect
+   reference is shared across the entire application (or DSO).  */
 
 void
 
 void
-dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
-                                         rtx addr,
-                                         const char *comment, ...))
+dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
+                                const char *comment, ...)
 {
   int size;
 {
   int size;
+  va_list ap;
 
 
-  VA_OPEN (ap, comment);
-  VA_FIXEDARG (ap, int, encoding);
-  VA_FIXEDARG (ap, rtx, addr);
-  VA_FIXEDARG (ap, const char *, comment);
+  va_start (ap, comment);
 
   size = size_of_encoded_value (encoding);
 
 
   size = size_of_encoded_value (encoding);
 
@@ -859,9 +981,9 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
          /* It is very tempting to use force_const_mem so that we share data
             with the normal constant pool.  However, we've already emitted
             the constant pool for this function.  Moreover, we'd like to
          /* It is very tempting to use force_const_mem so that we share data
             with the normal constant pool.  However, we've already emitted
             the constant pool for this function.  Moreover, we'd like to
-            share these constants across the entire unit of translation,
-            or better, across the entire application (or DSO).  */
-         addr = dw2_force_const_mem (addr);
+            share these constants across the entire unit of translation and
+            even, if possible, across the entire application (or DSO).  */
+         addr = dw2_force_const_mem (addr, is_public);
          encoding &= ~DW_EH_PE_indirect;
          goto restart;
        }
          encoding &= ~DW_EH_PE_indirect;
          goto restart;
        }
@@ -873,8 +995,7 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
          break;
 
        case DW_EH_PE_pcrel:
          break;
 
        case DW_EH_PE_pcrel:
-         if (GET_CODE (addr) != SYMBOL_REF)
-           abort ();
+         gcc_assert (GET_CODE (addr) == SYMBOL_REF);
 #ifdef ASM_OUTPUT_DWARF_PCREL
          ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
 #else
 #ifdef ASM_OUTPUT_DWARF_PCREL
          ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, XSTR (addr, 0));
 #else
@@ -885,7 +1006,7 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
        default:
          /* Other encodings should have been handled by
             ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX.  */
        default:
          /* Other encodings should have been handled by
             ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX.  */
-         abort ();
+         gcc_unreachable ();
        }
 
 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
        }
 
 #ifdef ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
@@ -900,5 +1021,7 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
     }
   fputc ('\n', asm_out_file);
 
     }
   fputc ('\n', asm_out_file);
 
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 }
+
+#include "gt-dwarf2asm.h"