diff options
author | luoqi <luoqi@FreeBSD.org> | 2008-07-23 11:37:20 +0000 |
---|---|---|
committer | luoqi <luoqi@FreeBSD.org> | 2008-07-23 11:37:20 +0000 |
commit | c9306f6f143425d8831c53d4318cf1555e10e16d (patch) | |
tree | e3cf8ad6e42c03fada42efbcde0fe17cba008265 /sys/i386 | |
parent | 183560b8225c55637893ede141cefe00ac4d9020 (diff) | |
download | FreeBSD-src-c9306f6f143425d8831c53d4318cf1555e10e16d.zip FreeBSD-src-c9306f6f143425d8831c53d4318cf1555e10e16d.tar.gz |
Unbreak cc -pg support on i386. In gcc 4.2, %ecx is used as the arg pointer
when stack realignment is turned on (it is ALWAYS on for main), however
in a profiling build %ecx would be clobbered by mcount(), this would lead
to a segmentation fault when the code tries to reference any argument.
This fix changes mcount() to preserve %ecx.
PR: bin/119709
Reviewed by: bde
MFC after: 1 week
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/include/profile.h | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/i386/include/profile.h b/sys/i386/include/profile.h index fe036d8..fb3320b 100644 --- a/sys/i386/include/profile.h +++ b/sys/i386/include/profile.h @@ -115,7 +115,15 @@ void user(void); void \ mcount() \ { \ - uintfptr_t selfpc, frompc; \ + uintfptr_t selfpc, frompc, ecx; \ + /* \ + * In gcc 4.2, ecx might be used in the caller as the arg \ + * pointer if the stack realignment option is set (-mstackrealign) \ + * or if the caller has the force_align_arg_pointer attribute \ + * (stack realignment is ALWAYS on for main). Preserve ecx \ + * here. \ + */ \ + __asm("" : "=c" (ecx)); \ /* \ * Find the return address for mcount, \ * and the return address for mcount's caller. \ @@ -132,6 +140,7 @@ mcount() \ __asm("movl (%%ebp),%0" : "=r" (frompc)); \ frompc = ((uintfptr_t *)frompc)[1]; \ _mcount(frompc, selfpc); \ + __asm("" : : "c" (ecx)); \ } #else /* !__GNUCLIKE_ASM */ #define MCOUNT |