diff options
author | Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> | 2016-03-16 11:57:02 +0000 |
---|---|---|
committer | Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> | 2016-03-16 11:57:02 +0000 |
commit | 47c8f0eeccdf05d898ccfa31aaf5479982128e73 (patch) | |
tree | ef8347a5f086259718003084f46bb00038048ff8 /libgcc | |
parent | 255b4c3e610227c36f69fa61397eb74f6655d0fe (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/ChangeLog | 7 | ||||
-rw-r--r-- | libgcc/config/sol2/gmon.c | 36 |
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. |