Use CRTs provided by Solaris
authorRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Thu, 24 Sep 2015 08:51:39 +0000 (08:51 +0000)
committerRainer Orth <ro@gcc.gnu.org>
Thu, 24 Sep 2015 08:51:39 +0000 (08:51 +0000)
gcc:
* configure.ac (gcc_cv_solaris_crts): New test.
* configure. Regenerate.
* config.in: Regenerate.
* config/sol2.h (STARTFILE_SPEC): Simplify, provide
HAVE_SOLARIS_CRTS variant.

libgcc:
* configure.ac (libgcc_cv_solaris_crts): New test.
* configure: Regenerate.
* config.in: Regenerate.
* config/sol2/crtp.c, config/sol2/crtpg.c: New files.
* config/gmon-sol2.c: Rename to ...
* config/sol2/gmon.c: ... this.
Include auto-target.h.
(internal_mcount): Wrap setup handling in !HAVE_SOLARIS_CRTS.
* config/t-sol2: Rename to ...
* config/sol2/t-sol2: ... this.
(gmon.o): Reflect renaming.
(crtp.o, crtpg.o): New rules.
* config.host (*-*-solaris2*): Reflect renaming.
Use system CRTs if present.
Remove default CRT case.

From-SVN: r228077

16 files changed:
gcc/ChangeLog
gcc/config.in
gcc/config/sol2.h
gcc/configure
gcc/configure.ac
libgcc/ChangeLog
libgcc/config.host
libgcc/config.in
libgcc/config/gmon-sol2.c [deleted file]
libgcc/config/sol2/crtp.c [new file with mode: 0644]
libgcc/config/sol2/crtpg.c [new file with mode: 0644]
libgcc/config/sol2/gmon.c [new file with mode: 0644]
libgcc/config/sol2/t-sol2 [new file with mode: 0644]
libgcc/config/t-sol2 [deleted file]
libgcc/configure
libgcc/configure.ac

index e3120f30d2082e1fe34afd86fb7e03d1bc59c0b6..e549506e6a9168eda053c9e8eefebe2adf7b7971 100644 (file)
@@ -1,3 +1,11 @@
+2015-09-24  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
+
+       * configure.ac (gcc_cv_solaris_crts): New test.
+       * configure. Regenerate.
+       * config.in: Regenerate.
+       * config/sol2.h (STARTFILE_SPEC): Simplify, provide
+       HAVE_SOLARIS_CRTS variant.
+
 2015-09-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * tree-inline.h (count_insns_seq): Delete prototype.
index c5c1be4e488d45eb1c1652bb46ac7d0d0fb41a11..a1987cc9bd9bdde9db85741c5bb557d350df2ef1 100644 (file)
 #endif
 
 
+/* Define if the system-provided CRTs are present on Solaris. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_SOLARIS_CRTS
+#endif
+
+
 /* Define to 1 if you have the <stddef.h> header file. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_STDDEF_H
index adf6f3b9fbe06347479d4445e33c3cfe1c8ebd22..d31a25133766d8fcba8629e7bec647b0f4a91907 100644 (file)
@@ -156,14 +156,24 @@ along with GCC; see the file COPYING3.  If not see
 
 /* We don't use the standard svr4 STARTFILE_SPEC because it's wrong for us.  */
 #undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{!shared: \
-                        %{!symbolic: \
-                         %{p:mcrt1.o%s} \
-                          %{!p: \
-                           %{pg:gcrt1.o%s gmon.o%s} \
-                            %{!pg:crt1.o%s}}}} \
+#ifdef HAVE_SOLARIS_CRTS
+/* Since Solaris 11.x and Solaris 12, the OS delivers crt1.o, crti.o, and
+   crtn.o, with a hook for compiler-dependent stuff like profile handling.  */
+#define STARTFILE_SPEC "%{!shared:%{!symbolic: \
+                         crt1.o%s \
+                         %{p:%e-p is not supported; \
+                           pg:crtpg.o%s gmon.o%s; \
+                             :crtp.o%s}}} \
                        crti.o%s %(startfile_arch) \
                        crtbegin.o%s"
+#else
+#define STARTFILE_SPEC "%{!shared:%{!symbolic: \
+                         %{p:mcrt1.o%s; \
+                            pg:gcrt1.o%s gmon.o%s; \
+                              :crt1.o%s}}} \
+                       crti.o%s %(startfile_arch) \
+                       crtbegin.o%s"
+#endif
 
 #undef  ENDFILE_SPEC
 #define ENDFILE_SPEC \
index 7493c800f48fab780755290560b1ce83efa9e771..a32bb64948d797a211a2e298ea542f58a01a85ea 100755 (executable)
@@ -28025,6 +28025,44 @@ $as_echo "#define HAVE_LD_SYSROOT 1" >>confdefs.h
 
 fi
 
+case $target in
+*-*-solaris2*)
+  # Check for system-provided CRTs on Solaris 11.x and Solaris 12.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking system-provided CRTs on Solaris" >&5
+$as_echo_n "checking system-provided CRTs on Solaris... " >&6; }
+if test "${gcc_cv_solaris_crts+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_solaris_crts=no
+     if test x$host != x$target; then
+       if test "x$with_sysroot" = xyes; then
+         target_sysroot="${test_exec_prefix}/${target_noncanonical}/sys-root"
+       else
+         target_sysroot="${with_sysroot}"
+       fi
+     fi
+     target_libdir="$target_sysroot/usr/lib"
+     # At the time they were added, gcrt1.o became a symlink for backwards
+     # compatibility on x86, while crt1.o was added on sparc, so check for that.
+     case $target in
+       i?86-*-solaris2* | x86_64-*-solaris2*)
+         if test -h "$target_libdir/gcrt1.o"; then gcc_cv_solaris_crts=yes; fi
+        ;;
+       sparc*-*-solaris2*)
+         if test -f "$target_libdir/crt1.o"; then gcc_cv_solaris_crts=yes; fi
+        ;;
+     esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_solaris_crts" >&5
+$as_echo "$gcc_cv_solaris_crts" >&6; }
+  ;;
+esac
+if test x$gcc_cv_solaris_crts = xyes; then
+
+$as_echo "#define HAVE_SOLARIS_CRTS 1" >>confdefs.h
+
+fi
+
 # Test for stack protector support in target C library.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking __stack_chk_fail in target C library" >&5
 $as_echo_n "checking __stack_chk_fail in target C library... " >&6; }
index 9d1f6f18ebae8e02f75385d8a49266ef51f19c81..4f8a44e51f140483da6a25583ada104931511222 100644 (file)
@@ -5281,6 +5281,37 @@ if test x"$gcc_cv_ld_sysroot" = xyes; then
   [Define if your linker supports --sysroot.])
 fi       
 
+case $target in
+*-*-solaris2*)
+  # Check for system-provided CRTs on Solaris 11.x and Solaris 12.
+  AC_CACHE_CHECK([system-provided CRTs on Solaris],
+    gcc_cv_solaris_crts,
+    [gcc_cv_solaris_crts=no
+     if test x$host != x$target; then
+       if test "x$with_sysroot" = xyes; then
+         target_sysroot="${test_exec_prefix}/${target_noncanonical}/sys-root"
+       else
+         target_sysroot="${with_sysroot}"
+       fi
+     fi
+     target_libdir="$target_sysroot/usr/lib"
+     # At the time they were added, gcrt1.o became a symlink for backwards
+     # compatibility on x86, while crt1.o was added on sparc, so check for that.
+     case $target in
+       i?86-*-solaris2* | x86_64-*-solaris2*)
+         if test -h "$target_libdir/gcrt1.o"; then gcc_cv_solaris_crts=yes; fi
+        ;;
+       sparc*-*-solaris2*)
+         if test -f "$target_libdir/crt1.o"; then gcc_cv_solaris_crts=yes; fi
+        ;;
+     esac])
+  ;;
+esac
+if test x$gcc_cv_solaris_crts = xyes; then
+  AC_DEFINE(HAVE_SOLARIS_CRTS, 1,
+           [Define if the system-provided CRTs are present on Solaris.])
+fi
+
 # Test for stack protector support in target C library.
 AC_CACHE_CHECK(__stack_chk_fail in target C library,
       gcc_cv_libc_provides_ssp,
index f4c13aa0077bc2649ae17ab08013c7e60470e6cb..559f7726f7fb41b2036d565576b4ed13cb43fb1f 100644 (file)
@@ -1,3 +1,21 @@
+2015-09-24  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
+
+       * configure.ac (libgcc_cv_solaris_crts): New test.
+       * configure: Regenerate.
+       * config.in: Regenerate.
+       * config/sol2/crtp.c, config/sol2/crtpg.c: New files.
+       * config/gmon-sol2.c: Rename to ...
+       * config/sol2/gmon.c: ... this.
+       Include auto-target.h.
+       (internal_mcount): Wrap setup handling in !HAVE_SOLARIS_CRTS.
+       * config/t-sol2: Rename to ...
+       * config/sol2/t-sol2: ... this.
+       (gmon.o): Reflect renaming.
+       (crtp.o, crtpg.o): New rules.
+       * config.host (*-*-solaris2*): Reflect renaming.
+       Use system CRTs if present.
+       Remove default CRT case.
+
 2015-09-23  John David Anglin  <danglin@gcc.gnu.org>
 
        * config/pa/linux-atomic.c (__kernel_cmpxchg2): Reorder error checks.
index 140aa227c499dc01d140d0498a748372c90f8392..6c8b97bfc013cc4c13697ed5f1140ab21f5e2984 100644 (file)
@@ -267,7 +267,7 @@ case ${host} in
 *-*-solaris2*)
   # Unless linker support and dl_iterate_phdr are present,
   # unwind-dw2-fde-dip.c automatically falls back to unwind-dw2-fde.c.
-  tmake_file="$tmake_file t-sol2 t-eh-dw2-dip t-libgcc-pic t-slibgcc t-slibgcc-elf-ver"
+  tmake_file="$tmake_file sol2/t-sol2 t-eh-dw2-dip t-libgcc-pic t-slibgcc t-slibgcc-elf-ver"
   if test $with_gnu_ld = yes; then
     tmake_file="$tmake_file t-slibgcc-gld"
   else
@@ -276,19 +276,22 @@ case ${host} in
   # Add cpu-specific t-sol2 after t-slibgcc-* so it can augment SHLIB_MAPFILES.
   tmake_file="$tmake_file $cpu_type/t-sol2"
   extra_parts="gmon.o crtbegin.o crtend.o"
-  case ${host} in
-    i?86-*-solaris2.1[0-9]* | x86_64-*-solaris2.1[0-9]*)
-      # Solaris 10+/x86 provides crt1.o, crti.o, crtn.o, and gcrt1.o as
-      # part of the base system.
-      ;;
-    sparc*-*-solaris2.1[0-9]*)
-      # Solaris 10+/SPARC lacks crt1.o and gcrt1.o.
-      extra_parts="$extra_parts crt1.o gcrt1.o"
-      ;;
-    *)
-      extra_parts="$extra_parts crt1.o crti.o crtn.o gcrt1.o"
-      ;;
-  esac
+  if test "${libgcc_cv_solaris_crts}" = yes; then
+    # Solaris 11.x and 12 provide crt1.o, crti.o, and crtn.o as part of the
+    # base system.  crtp.o and crtpg.o implement the compiler-dependent parts.
+    extra_parts="$extra_parts crtp.o crtpg.o"
+  else
+    case ${host} in
+      i?86-*-solaris2.1[0-9]* | x86_64-*-solaris2.1[0-9]*)
+        # Solaris 10+/x86 provides crt1.o, crti.o, crtn.o, and gcrt1.o as
+        # part of the base system.
+        ;;
+      sparc*-*-solaris2.1[0-9]*)
+        # Solaris 10+/SPARC lacks crt1.o and gcrt1.o.
+        extra_parts="$extra_parts crt1.o gcrt1.o"
+        ;;
+    esac
+  fi
   ;;
 *-*-uclinux*)
   extra_parts="crtbegin.o crtend.o"
index 59a79618c0e9af7fd614f337d234332cf028e2b9..25aa0d93bab8660e2e836caab1565860dee94ea9 100644 (file)
@@ -18,6 +18,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define if the system-provided CRTs are present on Solaris. */
+#undef HAVE_SOLARIS_CRTS
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff --git a/libgcc/config/gmon-sol2.c b/libgcc/config/gmon-sol2.c
deleted file mode 100644 (file)
index 7d61496..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. [rescinded 22 July 1999]
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* Mangled into a form that works on Solaris 2/SPARC by Mark Eichin
- * for Cygnus Support, July 1992.
- *
- * Modified to support Solaris 2/x86 by J.W.Hawtin <oolon@ankh.org>, 14/8/96.
- *
- * It must be used in conjunction with sol2-gc1.S, which is used to start
- * and stop process monitoring.
- */
-
-#include "tconfig.h"
-#include "tsystem.h"
-#include <fcntl.h>             /* For creat.  */
-
-extern void monstartup (char *, char *);
-extern void _mcleanup (void);
-#ifdef __i386__
-static void internal_mcount (void) __attribute__ ((used));
-#else
-static void internal_mcount (char *, unsigned short *) __attribute__ ((used));
-#endif
-static void moncontrol (int);
-
-struct phdr {
-  char *lpc;
-  char *hpc;
-  int ncnt;
-};
-
-#define HISTFRACTION   2
-#define HISTCOUNTER    unsigned short
-#define HASHFRACTION   1
-#define ARCDENSITY     2
-#define MINARCS                50
-
-struct tostruct {
-  char *selfpc;
-  long count;
-  unsigned short link;
-};
-
-struct rawarc {
-  unsigned long raw_frompc;
-  unsigned long raw_selfpc;
-  long raw_count;
-};
-
-#define ROUNDDOWN(x, y)        (((x) / (y)) * (y))
-#define ROUNDUP(x, y)  ((((x) + (y) - 1) / (y)) * (y))
-
-/* froms is actually a bunch of unsigned shorts indexing tos.  */
-static int profiling = 3;
-static unsigned short *froms;
-static struct tostruct *tos = NULL;
-static long tolimit = 0;
-static char *s_lowpc = NULL;
-static char *s_highpc = NULL;
-static size_t s_textsize = 0;
-
-static int ssiz;
-static char *sbuf;
-static int s_scale;
-/* See profil(2) where this is describe (incorrectly).  */
-#define        SCALE_1_TO_1    0x10000L
-
-#define        MSG "No space for profiling buffer(s)\n"
-
-void
-monstartup (char *lowpc, char *highpc)
-{
-  size_t monsize;
-  char *buffer;
-  size_t o;
-
-  /* Round lowpc and highpc to multiples of the density we're using
-     so the rest of the scaling (here and in gprof) stays in ints.  */
-  lowpc = (char *) ROUNDDOWN ((size_t) lowpc,
-                             HISTFRACTION * sizeof (HISTCOUNTER));
-  s_lowpc = lowpc;
-  highpc = (char *) ROUNDUP ((size_t) highpc,
-                            HISTFRACTION * sizeof (HISTCOUNTER));
-  s_highpc = highpc;
-  s_textsize = highpc - lowpc;
-  monsize = (s_textsize / HISTFRACTION) + sizeof (struct phdr);
-  buffer = sbrk (monsize);
-  if (buffer == (void *) -1) {
-    write (STDERR_FILENO, MSG, sizeof (MSG));
-    return;
-  }
-  froms = sbrk (s_textsize / HASHFRACTION);
-  if (froms == (void *) -1) {
-    write (STDERR_FILENO, MSG, sizeof (MSG));
-    froms = NULL;
-    return;
-  }
-  tolimit = s_textsize * ARCDENSITY / 100;
-  if (tolimit < MINARCS) {
-    tolimit = MINARCS;
-  } else if (tolimit > 65534) {
-    tolimit = 65534;
-  }
-  tos = sbrk (tolimit * sizeof (struct tostruct));
-  if (tos == (void *) -1) {
-    write (STDERR_FILENO, MSG, sizeof (MSG));
-    froms = NULL;
-    tos = NULL;
-    return;
-  }
-  tos[0].link = 0;
-  sbuf = buffer;
-  ssiz = monsize;
-  ((struct phdr *) buffer)->lpc = lowpc;
-  ((struct phdr *) buffer)->hpc = highpc;
-  ((struct phdr *) buffer)->ncnt = ssiz;
-  monsize -= sizeof (struct phdr);
-  if (monsize <= 0)
-    return;
-  o = highpc - lowpc;
-  if(monsize < o)
-    s_scale = ((float) monsize / o) * SCALE_1_TO_1;
-  else
-    s_scale = SCALE_1_TO_1;
-  moncontrol (1);
-}
-
-void
-_mcleanup (void)
-{
-  int fd;
-  int fromindex;
-  int endfrom;
-  char *frompc;
-  int toindex;
-  struct rawarc        rawarc;
-  char *profdir;
-  const char *proffile;
-  char *progname;
-  char buf[PATH_MAX];
-  extern char **___Argv;
-
-  moncontrol (0);
-
-  if ((profdir = getenv ("PROFDIR")) != NULL) {
-    /* If PROFDIR contains a null value, no profiling output is produced.  */
-    if (*profdir == '\0') {
-      return;
-    }
-
-    progname = strrchr (___Argv[0], '/');
-    if (progname == NULL)
-      progname = ___Argv[0];
-    else
-      progname++;
-
-    sprintf (buf, "%s/%ld.%s", profdir, (long) getpid (), progname);
-    proffile = buf;
-  } else {
-    proffile = "gmon.out";
-  }
-
-  fd = creat (proffile, 0666);
-  if (fd < 0) {
-    perror (proffile);
-    return;
-  }
-#ifdef DEBUG
-  fprintf (stderr, "[mcleanup] sbuf %#x ssiz %d\n", sbuf, ssiz);
-#endif /* DEBUG */
-
-  write (fd, sbuf, ssiz);
-  endfrom = s_textsize / (HASHFRACTION * sizeof (*froms));
-  for (fromindex = 0; fromindex < endfrom; fromindex++) {
-    if (froms[fromindex] == 0) {
-      continue;
-    }
-    frompc = s_lowpc + (fromindex * HASHFRACTION * sizeof (*froms));
-    for (toindex = froms[fromindex];
-        toindex != 0;
-        toindex = tos[toindex].link) {
-#ifdef DEBUG
-      fprintf (stderr, "[mcleanup] frompc %#x selfpc %#x count %d\n",
-              frompc, tos[toindex].selfpc, tos[toindex].count);
-#endif /* DEBUG */
-      rawarc.raw_frompc = (unsigned long) frompc;
-      rawarc.raw_selfpc = (unsigned long) tos[toindex].selfpc;
-      rawarc.raw_count = tos[toindex].count;
-      write (fd, &rawarc, sizeof (rawarc));
-    }
-  }
-  close (fd);
-}
-
-/* Solaris 2 libraries use _mcount.  */
-#if defined __i386__
-asm(".globl _mcount\n"
-    "_mcount:\n"
-    "  jmp     internal_mcount\n");
-#elif defined __x86_64__
-/* See GLIBC for additional information about this technique.  */
-asm(".globl _mcount\n" 
-    "  .type   _mcount, @function\n"
-    "_mcount:\n"
-    /* The compiler calls _mcount after the prologue, and does not
-       save any of the registers.  Therefore we must preserve all
-       seven registers which may contain function arguments.  */
-    "  subq    $0x38, %rsp\n"
-    "  movq    %rax, (%rsp)\n"
-    "  movq    %rcx, 0x08(%rsp)\n"
-    "  movq    %rdx, 0x10(%rsp)\n"
-    "  movq    %rsi, 0x18(%rsp)\n"
-    "  movq    %rdi, 0x20(%rsp)\n"
-    "  movq    %r8, 0x28(%rsp)\n"
-    "  movq    %r9, 0x30(%rsp)\n"
-    /* Get SELFPC (pushed by the call to this function) and
-       FROMPCINDEX (via the frame pointer).  */
-    "  movq    0x38(%rsp), %rdi\n"
-    "  movq    0x8(%rbp), %rsi\n"
-    "  call    internal_mcount\n"
-    /* Restore the saved registers.  */
-    "  movq    0x30(%rsp), %r9\n"
-    "  movq    0x28(%rsp), %r8\n"
-    "  movq    0x20(%rsp), %rdi\n"
-    "  movq    0x18(%rsp), %rsi\n"
-    "  movq    0x10(%rsp), %rdx\n"
-    "  movq    0x08(%rsp), %rcx\n"
-    "  movq    (%rsp), %rax\n"
-    "  addq    $0x38, %rsp\n"
-    "  retq\n");
-#elif defined __sparc__
-/* The SPARC stack frame is only held together by the frame pointers
-   in the register windows. According to the SVR4 SPARC ABI
-   Supplement, Low Level System Information/Operating System
-   Interface/Software Trap Types, a type 3 trap will flush all of the
-   register windows to the stack, which will make it possible to walk
-   the frames and find the return addresses.
-       However, it seems awfully expensive to incur a trap (system
-   call) for every function call. It turns out that "call" simply puts
-   the return address in %o7 expecting the "save" in the procedure to
-   shift it into %i7; this means that before the "save" occurs, %o7
-   contains the address of the call to mcount, and %i7 still contains
-   the caller above that. The asm mcount here simply saves those
-   registers in argument registers and branches to internal_mcount,
-   simulating a call with arguments.
-       Kludges:
-       1) the branch to internal_mcount is hard coded; it should be
-   possible to tell asm to use the assembler-name of a symbol.
-       2) in theory, the function calling mcount could have saved %i7
-   somewhere and reused the register; in practice, I *think* this will
-   break longjmp (and maybe the debugger) but I'm not certain. (I take
-   some comfort in the knowledge that it will break the native mcount
-   as well.)
-       3) if builtin_return_address worked, this could be portable.
-   However, it would really have to be optimized for arguments of 0
-   and 1 and do something like what we have here in order to avoid the
-   trap per function call performance hit. 
-       4) the atexit and monsetup calls prevent this from simply
-   being a leaf routine that doesn't do a "save" (and would thus have
-   access to %o7 and %i7 directly) but the call to write() at the end
-   would have also prevented this.
-
-   -- [eichin:19920702.1107EST]  */
-asm(".global _mcount\n"
-    "_mcount:\n"
-    /* i7 == last ret, -> frompcindex.  */
-    "  mov     %i7, %o1\n"
-    /* o7 == current ret, -> selfpc.  */
-    "  mov     %o7, %o0\n"
-    "  b,a     internal_mcount\n");
-#endif
-
-static void
-#ifdef __i386__
-internal_mcount (void)
-#else
-internal_mcount (char *selfpc, unsigned short *frompcindex)
-#endif
-{
-  struct tostruct *top;
-  struct tostruct *prevtop;
-  long toindex;
-  static char already_setup;
-
-#ifdef __i386__
-  char *selfpc;
-  unsigned short *frompcindex;
-
-  /* Find the return address for mcount and the return address for mcount's
-     caller.  */
-
-  /* selfpc = pc pushed by mcount call.
-     This identifies the function that was just entered.  */
-  selfpc = (void *) __builtin_return_address (0);
-  /* frompcindex = pc in preceding frame.
-     This identifies the caller of the function just entered.  */
-  frompcindex = (void *) __builtin_return_address (1);
-#endif
-
-  if(!already_setup) {
-    extern char etext[];
-
-    already_setup = 1;
-
-#if defined __i386__
-    /* <sys/vmparam.h> USERSTACK.  */
-    monstartup ((char *) 0x8048000, etext);
-#elif defined __x86_64__
-    monstartup (NULL, etext);
-#elif defined __sparc__
-    {
-      extern char _start[];
-      extern char _init[];
-
-      monstartup (_start < _init ? _start : _init, etext);
-    }
-#endif
-    atexit (_mcleanup);
-  }
-  /* Check that we are profiling and that we aren't recursively invoked.  */
-  if (profiling) {
-    goto out;
-  }
-  profiling++;
-  /* Check that frompcindex is a reasonable pc value.  For example: signal
-     catchers get called from the stack, not from text space.  too bad.  */
-  frompcindex = (unsigned short *) ((long) frompcindex - (long) s_lowpc);
-  if ((unsigned long) frompcindex > s_textsize) {
-    goto done;
-  }
-  frompcindex = &froms[((long) frompcindex) / (HASHFRACTION * sizeof (*froms))];
-  toindex = *frompcindex;
-  if (toindex == 0) {
-    /* First time traversing this arc.  */
-    toindex = ++tos[0].link;
-    if (toindex >= tolimit) {
-      goto overflow;
-    }
-    *frompcindex = toindex;
-    top = &tos[toindex];
-    top->selfpc = selfpc;
-    top->count = 1;
-    top->link = 0;
-    goto done;
-  }
-  top = &tos[toindex];
-  if (top->selfpc == selfpc) {
-    /* arc at front of chain; usual case.  */
-    top->count++;
-    goto done;
-  }
-  /* Have to go looking down chain for it.  Top points to what we are
-     looking at, prevtop points to previous top.  We know it is not at the
-     head of the chain.  */
-  for (; /* goto done */; ) {
-    if (top->link == 0) {
-      /* top is end of the chain and none of the chain had top->selfpc ==
-        selfpc, so we allocate a new tostruct and link it to the head of
-        the chain.  */
-      toindex = ++tos[0].link;
-      if (toindex >= tolimit) {
-       goto overflow;
-      }
-      top = &tos[toindex];
-      top->selfpc = selfpc;
-      top->count = 1;
-      top->link = *frompcindex;
-      *frompcindex = toindex;
-      goto done;
-    }
-    /* Otherwise, check the next arc on the chain.  */
-    prevtop = top;
-    top = &tos[top->link];
-    if (top->selfpc == selfpc) {
-      /* There it is.  Increment its count move it to the head of the
-        chain.  */
-      top->count++;
-      toindex = prevtop->link;
-      prevtop->link = top->link;
-      top->link = *frompcindex;
-      *frompcindex = toindex;
-      goto done;
-    }
-
-  }
- done:
-  profiling--;
-  /* ... and fall through. */
- out:
-  /* Normal return restores saved registers.  */
-  return;
-
- overflow:
-  /* Halt further profiling.  */
-  profiling++;
-
-#define        TOLIMIT "mcount: tos overflow\n"
-  write (STDERR_FILENO, TOLIMIT, sizeof (TOLIMIT));
-  goto out;
-}
-
-/* Control profiling.  Profiling is what mcount checks to see if all the
-   data structures are ready.  */
-static void
-moncontrol (int mode)
-{
-  if (mode) {
-    /* Start.  */
-    profil ((unsigned short *) (sbuf + sizeof (struct phdr)),
-           ssiz - sizeof (struct phdr), (size_t) s_lowpc, s_scale);
-    profiling = 0;
-  } else {
-    /* Stop.  */
-    profil ((unsigned short *) 0, 0, 0, 0);
-    profiling = 3;
-  }
-}
diff --git a/libgcc/config/sol2/crtp.c b/libgcc/config/sol2/crtp.c
new file mode 100644 (file)
index 0000000..8b79c55
--- /dev/null
@@ -0,0 +1,33 @@
+/* Dummy _mcount when mixing profiling and non-profiling objects.
+   Copyright (C) 2015 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
+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
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+void _mcount (void);
+
+/* A dummy profiling support routine for non-profiling executables,
+   in case we link in some objects that have been compiled for profiling.  */
+
+void __attribute__((weak))
+_mcount (void)
+{
+}
diff --git a/libgcc/config/sol2/crtpg.c b/libgcc/config/sol2/crtpg.c
new file mode 100644 (file)
index 0000000..e07a36a
--- /dev/null
@@ -0,0 +1,47 @@
+/* Register profiling startup and cleanup with Solaris CRTs.
+   Copyright (C) 2015 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
+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
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+extern void monstartup (char *, char *);
+extern void _mcleanup (void);
+
+extern char _start[], _etext[];
+
+int __start_crt_compiler (int, char **);
+
+/* Since Solaris 11.x and Solaris 12, the system-provided CRTs provide a
+   hook to invoke initialization code early during process startup.
+   __start_crt_compiler is documented in crt1.o(5).  We use it to perform
+   initialization for profiling as a substitute for the earlier separate
+   gcrt1.o.  */
+
+int
+__start_crt_compiler (int argc __attribute__ ((unused)),
+                     char **argv __attribute__ ((unused)))
+{
+  monstartup (_start, _etext);
+  atexit (_mcleanup);
+  return 0;
+}
diff --git a/libgcc/config/sol2/gmon.c b/libgcc/config/sol2/gmon.c
new file mode 100644 (file)
index 0000000..f641958
--- /dev/null
@@ -0,0 +1,451 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Mangled into a form that works on Solaris 2/SPARC by Mark Eichin
+ * for Cygnus Support, July 1992.
+ *
+ * Modified to support Solaris 2/x86 by J.W.Hawtin <oolon@ankh.org>, 14/8/96.
+ *
+ * It must be used in conjunction with sol2-gc1.S, which is used to start
+ * and stop process monitoring.
+ */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "auto-target.h"
+#include <fcntl.h>             /* For creat.  */
+
+extern void monstartup (char *, char *);
+extern void _mcleanup (void);
+#ifdef __i386__
+static void internal_mcount (void) __attribute__ ((used));
+#else
+static void internal_mcount (char *, unsigned short *) __attribute__ ((used));
+#endif
+static void moncontrol (int);
+
+struct phdr {
+  char *lpc;
+  char *hpc;
+  int ncnt;
+};
+
+#define HISTFRACTION   2
+#define HISTCOUNTER    unsigned short
+#define HASHFRACTION   1
+#define ARCDENSITY     2
+#define MINARCS                50
+
+struct tostruct {
+  char *selfpc;
+  long count;
+  unsigned short link;
+};
+
+struct rawarc {
+  unsigned long raw_frompc;
+  unsigned long raw_selfpc;
+  long raw_count;
+};
+
+#define ROUNDDOWN(x, y)        (((x) / (y)) * (y))
+#define ROUNDUP(x, y)  ((((x) + (y) - 1) / (y)) * (y))
+
+/* froms is actually a bunch of unsigned shorts indexing tos.  */
+static int profiling = 3;
+static unsigned short *froms;
+static struct tostruct *tos = NULL;
+static long tolimit = 0;
+static char *s_lowpc = NULL;
+static char *s_highpc = NULL;
+static size_t s_textsize = 0;
+
+static int ssiz;
+static char *sbuf;
+static int s_scale;
+/* See profil(2) where this is describe (incorrectly).  */
+#define        SCALE_1_TO_1    0x10000L
+
+#define        MSG "No space for profiling buffer(s)\n"
+
+void
+monstartup (char *lowpc, char *highpc)
+{
+  size_t monsize;
+  char *buffer;
+  size_t o;
+
+  /* Round lowpc and highpc to multiples of the density we're using
+     so the rest of the scaling (here and in gprof) stays in ints.  */
+  lowpc = (char *) ROUNDDOWN ((size_t) lowpc,
+                             HISTFRACTION * sizeof (HISTCOUNTER));
+  s_lowpc = lowpc;
+  highpc = (char *) ROUNDUP ((size_t) highpc,
+                            HISTFRACTION * sizeof (HISTCOUNTER));
+  s_highpc = highpc;
+  s_textsize = highpc - lowpc;
+  monsize = (s_textsize / HISTFRACTION) + sizeof (struct phdr);
+  buffer = sbrk (monsize);
+  if (buffer == (void *) -1) {
+    write (STDERR_FILENO, MSG, sizeof (MSG));
+    return;
+  }
+  froms = sbrk (s_textsize / HASHFRACTION);
+  if (froms == (void *) -1) {
+    write (STDERR_FILENO, MSG, sizeof (MSG));
+    froms = NULL;
+    return;
+  }
+  tolimit = s_textsize * ARCDENSITY / 100;
+  if (tolimit < MINARCS) {
+    tolimit = MINARCS;
+  } else if (tolimit > 65534) {
+    tolimit = 65534;
+  }
+  tos = sbrk (tolimit * sizeof (struct tostruct));
+  if (tos == (void *) -1) {
+    write (STDERR_FILENO, MSG, sizeof (MSG));
+    froms = NULL;
+    tos = NULL;
+    return;
+  }
+  tos[0].link = 0;
+  sbuf = buffer;
+  ssiz = monsize;
+  ((struct phdr *) buffer)->lpc = lowpc;
+  ((struct phdr *) buffer)->hpc = highpc;
+  ((struct phdr *) buffer)->ncnt = ssiz;
+  monsize -= sizeof (struct phdr);
+  if (monsize <= 0)
+    return;
+  o = highpc - lowpc;
+  if(monsize < o)
+    s_scale = ((float) monsize / o) * SCALE_1_TO_1;
+  else
+    s_scale = SCALE_1_TO_1;
+  moncontrol (1);
+}
+
+void
+_mcleanup (void)
+{
+  int fd;
+  int fromindex;
+  int endfrom;
+  char *frompc;
+  int toindex;
+  struct rawarc        rawarc;
+  char *profdir;
+  const char *proffile;
+  char *progname;
+  char buf[PATH_MAX];
+  extern char **___Argv;
+
+  moncontrol (0);
+
+  if ((profdir = getenv ("PROFDIR")) != NULL) {
+    /* If PROFDIR contains a null value, no profiling output is produced.  */
+    if (*profdir == '\0') {
+      return;
+    }
+
+    progname = strrchr (___Argv[0], '/');
+    if (progname == NULL)
+      progname = ___Argv[0];
+    else
+      progname++;
+
+    sprintf (buf, "%s/%ld.%s", profdir, (long) getpid (), progname);
+    proffile = buf;
+  } else {
+    proffile = "gmon.out";
+  }
+
+  fd = creat (proffile, 0666);
+  if (fd < 0) {
+    perror (proffile);
+    return;
+  }
+#ifdef DEBUG
+  fprintf (stderr, "[mcleanup] sbuf %#x ssiz %d\n", sbuf, ssiz);
+#endif /* DEBUG */
+
+  write (fd, sbuf, ssiz);
+  endfrom = s_textsize / (HASHFRACTION * sizeof (*froms));
+  for (fromindex = 0; fromindex < endfrom; fromindex++) {
+    if (froms[fromindex] == 0) {
+      continue;
+    }
+    frompc = s_lowpc + (fromindex * HASHFRACTION * sizeof (*froms));
+    for (toindex = froms[fromindex];
+        toindex != 0;
+        toindex = tos[toindex].link) {
+#ifdef DEBUG
+      fprintf (stderr, "[mcleanup] frompc %#x selfpc %#x count %d\n",
+              frompc, tos[toindex].selfpc, tos[toindex].count);
+#endif /* DEBUG */
+      rawarc.raw_frompc = (unsigned long) frompc;
+      rawarc.raw_selfpc = (unsigned long) tos[toindex].selfpc;
+      rawarc.raw_count = tos[toindex].count;
+      write (fd, &rawarc, sizeof (rawarc));
+    }
+  }
+  close (fd);
+}
+
+/* Solaris 2 libraries use _mcount.  */
+#if defined __i386__
+asm(".globl _mcount\n"
+    "_mcount:\n"
+    "  jmp     internal_mcount\n");
+#elif defined __x86_64__
+/* See GLIBC for additional information about this technique.  */
+asm(".globl _mcount\n" 
+    "  .type   _mcount, @function\n"
+    "_mcount:\n"
+    /* The compiler calls _mcount after the prologue, and does not
+       save any of the registers.  Therefore we must preserve all
+       seven registers which may contain function arguments.  */
+    "  subq    $0x38, %rsp\n"
+    "  movq    %rax, (%rsp)\n"
+    "  movq    %rcx, 0x08(%rsp)\n"
+    "  movq    %rdx, 0x10(%rsp)\n"
+    "  movq    %rsi, 0x18(%rsp)\n"
+    "  movq    %rdi, 0x20(%rsp)\n"
+    "  movq    %r8, 0x28(%rsp)\n"
+    "  movq    %r9, 0x30(%rsp)\n"
+    /* Get SELFPC (pushed by the call to this function) and
+       FROMPCINDEX (via the frame pointer).  */
+    "  movq    0x38(%rsp), %rdi\n"
+    "  movq    0x8(%rbp), %rsi\n"
+    "  call    internal_mcount\n"
+    /* Restore the saved registers.  */
+    "  movq    0x30(%rsp), %r9\n"
+    "  movq    0x28(%rsp), %r8\n"
+    "  movq    0x20(%rsp), %rdi\n"
+    "  movq    0x18(%rsp), %rsi\n"
+    "  movq    0x10(%rsp), %rdx\n"
+    "  movq    0x08(%rsp), %rcx\n"
+    "  movq    (%rsp), %rax\n"
+    "  addq    $0x38, %rsp\n"
+    "  retq\n");
+#elif defined __sparc__
+/* The SPARC stack frame is only held together by the frame pointers
+   in the register windows. According to the SVR4 SPARC ABI
+   Supplement, Low Level System Information/Operating System
+   Interface/Software Trap Types, a type 3 trap will flush all of the
+   register windows to the stack, which will make it possible to walk
+   the frames and find the return addresses.
+       However, it seems awfully expensive to incur a trap (system
+   call) for every function call. It turns out that "call" simply puts
+   the return address in %o7 expecting the "save" in the procedure to
+   shift it into %i7; this means that before the "save" occurs, %o7
+   contains the address of the call to mcount, and %i7 still contains
+   the caller above that. The asm mcount here simply saves those
+   registers in argument registers and branches to internal_mcount,
+   simulating a call with arguments.
+       Kludges:
+       1) the branch to internal_mcount is hard coded; it should be
+   possible to tell asm to use the assembler-name of a symbol.
+       2) in theory, the function calling mcount could have saved %i7
+   somewhere and reused the register; in practice, I *think* this will
+   break longjmp (and maybe the debugger) but I'm not certain. (I take
+   some comfort in the knowledge that it will break the native mcount
+   as well.)
+       3) if builtin_return_address worked, this could be portable.
+   However, it would really have to be optimized for arguments of 0
+   and 1 and do something like what we have here in order to avoid the
+   trap per function call performance hit. 
+       4) the atexit and monsetup calls prevent this from simply
+   being a leaf routine that doesn't do a "save" (and would thus have
+   access to %o7 and %i7 directly) but the call to write() at the end
+   would have also prevented this.
+
+   -- [eichin:19920702.1107EST]  */
+asm(".global _mcount\n"
+    "_mcount:\n"
+    /* i7 == last ret, -> frompcindex.  */
+    "  mov     %i7, %o1\n"
+    /* o7 == current ret, -> selfpc.  */
+    "  mov     %o7, %o0\n"
+    "  b,a     internal_mcount\n");
+#endif
+
+static void
+#ifdef __i386__
+internal_mcount (void)
+#else
+internal_mcount (char *selfpc, unsigned short *frompcindex)
+#endif
+{
+  struct tostruct *top;
+  struct tostruct *prevtop;
+  long toindex;
+  static char already_setup;
+
+#ifdef __i386__
+  char *selfpc;
+  unsigned short *frompcindex;
+
+  /* Find the return address for mcount and the return address for mcount's
+     caller.  */
+
+  /* selfpc = pc pushed by mcount call.
+     This identifies the function that was just entered.  */
+  selfpc = (void *) __builtin_return_address (0);
+  /* frompcindex = pc in preceding frame.
+     This identifies the caller of the function just entered.  */
+  frompcindex = (void *) __builtin_return_address (1);
+#endif
+
+/* Only necessary without the Solaris CRTs or a proper gcrt1.o, otherwise
+   crtpg.o or gcrt1.o take care of that.
+
+   FIXME: What about _init vs. _start on sparc?  */
+#ifndef HAVE_SOLARIS_CRTS
+  if(!already_setup) {
+    extern char etext[];
+
+    already_setup = 1;
+
+#if defined __i386__
+    /* <sys/vmparam.h> USERSTACK.  */
+    monstartup ((char *) 0x8048000, etext);
+#elif defined __x86_64__
+    monstartup (NULL, etext);
+#elif defined __sparc__
+    {
+      extern char _start[];
+      extern char _init[];
+
+      monstartup (_start < _init ? _start : _init, etext);
+    }
+#endif
+    atexit (_mcleanup);
+  }
+#endif /* !HAVE_SOLARIS_CRTS */
+  /* Check that we are profiling and that we aren't recursively invoked.  */
+  if (profiling) {
+    goto out;
+  }
+  profiling++;
+  /* Check that frompcindex is a reasonable pc value.  For example: signal
+     catchers get called from the stack, not from text space.  too bad.  */
+  frompcindex = (unsigned short *) ((long) frompcindex - (long) s_lowpc);
+  if ((unsigned long) frompcindex > s_textsize) {
+    goto done;
+  }
+  frompcindex = &froms[((long) frompcindex) / (HASHFRACTION * sizeof (*froms))];
+  toindex = *frompcindex;
+  if (toindex == 0) {
+    /* First time traversing this arc.  */
+    toindex = ++tos[0].link;
+    if (toindex >= tolimit) {
+      goto overflow;
+    }
+    *frompcindex = toindex;
+    top = &tos[toindex];
+    top->selfpc = selfpc;
+    top->count = 1;
+    top->link = 0;
+    goto done;
+  }
+  top = &tos[toindex];
+  if (top->selfpc == selfpc) {
+    /* arc at front of chain; usual case.  */
+    top->count++;
+    goto done;
+  }
+  /* Have to go looking down chain for it.  Top points to what we are
+     looking at, prevtop points to previous top.  We know it is not at the
+     head of the chain.  */
+  for (; /* goto done */; ) {
+    if (top->link == 0) {
+      /* top is end of the chain and none of the chain had top->selfpc ==
+        selfpc, so we allocate a new tostruct and link it to the head of
+        the chain.  */
+      toindex = ++tos[0].link;
+      if (toindex >= tolimit) {
+       goto overflow;
+      }
+      top = &tos[toindex];
+      top->selfpc = selfpc;
+      top->count = 1;
+      top->link = *frompcindex;
+      *frompcindex = toindex;
+      goto done;
+    }
+    /* Otherwise, check the next arc on the chain.  */
+    prevtop = top;
+    top = &tos[top->link];
+    if (top->selfpc == selfpc) {
+      /* There it is.  Increment its count move it to the head of the
+        chain.  */
+      top->count++;
+      toindex = prevtop->link;
+      prevtop->link = top->link;
+      top->link = *frompcindex;
+      *frompcindex = toindex;
+      goto done;
+    }
+
+  }
+ done:
+  profiling--;
+  /* ... and fall through. */
+ out:
+  /* Normal return restores saved registers.  */
+  return;
+
+ overflow:
+  /* Halt further profiling.  */
+  profiling++;
+
+#define        TOLIMIT "mcount: tos overflow\n"
+  write (STDERR_FILENO, TOLIMIT, sizeof (TOLIMIT));
+  goto out;
+}
+
+/* Control profiling.  Profiling is what mcount checks to see if all the
+   data structures are ready.  */
+static void
+moncontrol (int mode)
+{
+  if (mode) {
+    /* Start.  */
+    profil ((unsigned short *) (sbuf + sizeof (struct phdr)),
+           ssiz - sizeof (struct phdr), (size_t) s_lowpc, s_scale);
+    profiling = 0;
+  } else {
+    /* Stop.  */
+    profil ((unsigned short *) 0, 0, 0, 0);
+    profiling = 3;
+  }
+}
diff --git a/libgcc/config/sol2/t-sol2 b/libgcc/config/sol2/t-sol2
new file mode 100644 (file)
index 0000000..1f7324a
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2004-2015 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 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 WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or 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
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# crtp, crtpg build rules
+crtp.o: $(srcdir)/config/sol2/crtp.c
+       $(gcc_compile) -c $<
+crtpg.o: $(srcdir)/config/sol2/crtpg.c
+       $(gcc_compile) -c $<
+
+# gmon build rule
+gmon.o:        $(srcdir)/config/sol2/gmon.c
+       $(gcc_compile) -c $<
+
+# Assemble startup files.
+crt1.o: $(srcdir)/config/$(cpu_type)/sol2-c1.S
+       $(crt_compile) -c $<
+gcrt1.o: $(srcdir)/config/$(cpu_type)/sol2-c1.S
+       $(crt_compile) -c -DGCRT1 $<
diff --git a/libgcc/config/t-sol2 b/libgcc/config/t-sol2
deleted file mode 100644 (file)
index 85eddb2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2004-2015 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 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 WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or 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
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-# gmon build rule:
-gmon.o:        $(srcdir)/config/gmon-sol2.c
-       $(gcc_compile) -c $<
-
-# Assemble startup files.
-crt1.o: $(srcdir)/config/$(cpu_type)/sol2-c1.S
-       $(crt_compile) -c $<
-gcrt1.o: $(srcdir)/config/$(cpu_type)/sol2-c1.S
-       $(crt_compile) -c -DGCRT1 $<
index e22cbcb872a48424363b74d544463fe1b103b0f7..78708c7f407778d2b633fe538abbf61e2743f7d7 100644 (file)
@@ -4665,6 +4665,38 @@ fi
 $as_echo "$libgcc_cv_mips_hard_float" >&6; }
 esac
 
+case ${host} in
+*-*-solaris2*)
+  # Check for system-provided CRTs on Solaris 11.x and Solaris 12.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking system-provided CRTs on Solaris" >&5
+$as_echo_n "checking system-provided CRTs on Solaris... " >&6; }
+if test "${libgcc_cv_solaris_crts+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  libgcc_cv_solaris_crts=no
+     libgcc_sysroot="`${CC} -print-sysroot`"
+     libgcc_libdir="$libgcc_sysroot/usr/lib"
+     # At the time they were added, gcrt1.o became a symlink for backwards
+     # compatibility on x86, while crt1.o was added on sparc, so check for that.
+     case ${host} in
+       i?86-*-solaris2* | x86_64-*-solaris2*)
+         if test -h "$libgcc_libdir/gcrt1.o"; then libgcc_cv_solaris_crts=yes; fi
+        ;;
+       sparc*-*-solaris2*)
+         if test -f "$libgcc_libdir/crt1.o"; then libgcc_cv_solaris_crts=yes; fi
+        ;;
+     esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_solaris_crts" >&5
+$as_echo "$libgcc_cv_solaris_crts" >&6; }
+  if test $libgcc_cv_solaris_crts = yes; then
+
+$as_echo "#define HAVE_SOLARIS_CRTS 1" >>confdefs.h
+
+  fi
+  ;;
+esac
+
 # Determine the version of glibc, if any, used on the target.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for target glibc version" >&5
 $as_echo_n "checking for target glibc version... " >&6; }
index dfabd808d11a360dc4e265ffe75a8f004af1956a..9d831a769971954c58f8b85323d4ed697d5dfd5b 100644 (file)
@@ -292,6 +292,31 @@ mips*-*-*)
     [libgcc_cv_mips_hard_float=no])])
 esac
 
+case ${host} in
+*-*-solaris2*)
+  # Check for system-provided CRTs on Solaris 11.x and Solaris 12.
+  AC_CACHE_CHECK([system-provided CRTs on Solaris],
+                [libgcc_cv_solaris_crts],
+    [libgcc_cv_solaris_crts=no
+     libgcc_sysroot="`${CC} -print-sysroot`"
+     libgcc_libdir="$libgcc_sysroot/usr/lib"
+     # At the time they were added, gcrt1.o became a symlink for backwards
+     # compatibility on x86, while crt1.o was added on sparc, so check for that.
+     case ${host} in
+       i?86-*-solaris2* | x86_64-*-solaris2*)
+         if test -h "$libgcc_libdir/gcrt1.o"; then libgcc_cv_solaris_crts=yes; fi
+        ;;
+       sparc*-*-solaris2*)
+         if test -f "$libgcc_libdir/crt1.o"; then libgcc_cv_solaris_crts=yes; fi
+        ;;
+     esac])
+  if test $libgcc_cv_solaris_crts = yes; then
+    AC_DEFINE(HAVE_SOLARIS_CRTS, 1,
+      [Define if the system-provided CRTs are present on Solaris.])
+  fi
+  ;;
+esac
+
 # Determine the version of glibc, if any, used on the target.
 AC_MSG_CHECKING([for target glibc version])
 AC_ARG_WITH([glibc-version],