aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>2016-03-16 11:57:02 +0000
committerRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>2016-03-16 11:57:02 +0000
commit47c8f0eeccdf05d898ccfa31aaf5479982128e73 (patch)
treeef8347a5f086259718003084f46bb00038048ff8 /libgcc
parent255b4c3e610227c36f69fa61397eb74f6655d0fe (diff)
Save call-clobbered registers in _mcount on 32-bit Solaris/x86 (PR target/38239)
PR target/38239 * config/sol2/gmon.c [__i386__] (_mcount): Save and restore call-clobbered registers. (internal_mcount): Remove __i386__ handling. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@234256 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog7
-rw-r--r--libgcc/config/sol2/gmon.c36
2 files changed, 19 insertions, 24 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index ca47125504e..3a626bc9bb7 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-03-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR target/38239
+ * config/sol2/gmon.c [__i386__] (_mcount): Save and restore
+ call-clobbered registers.
+ (internal_mcount): Remove __i386__ handling.
+
2016-02-26 Joel Sherrill <joel@rtems.org>
* config.host: Add x86_64-*-rtems*.
diff --git a/libgcc/config/sol2/gmon.c b/libgcc/config/sol2/gmon.c
index 81a03468b6e..652fd1ed946 100644
--- a/libgcc/config/sol2/gmon.c
+++ b/libgcc/config/sol2/gmon.c
@@ -44,11 +44,7 @@
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 {
@@ -223,8 +219,19 @@ _mcleanup (void)
/* Solaris 2 libraries use _mcount. */
#if defined __i386__
asm(".globl _mcount\n"
+ " .type _mcount, @function\n"
"_mcount:\n"
- " jmp internal_mcount\n");
+ /* Save and restore the call-clobbered registers. */
+ " pushl %eax\n"
+ " pushl %ecx\n"
+ " pushl %edx\n"
+ " movl 12(%esp), %edx\n"
+ " movl 4(%ebp), %eax\n"
+ " call internal_mcount\n"
+ " popl %edx\n"
+ " popl %ecx\n"
+ " popl %eax\n"
+ " ret\n");
#elif defined __x86_64__
/* See GLIBC for additional information about this technique. */
asm(".globl _mcount\n"
@@ -299,32 +306,13 @@ asm(".global _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.