This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hello,
On x86 targets, the "force_align_arg_pointer" implementation bits
potentially badly interact with code generated for profiling purposes.
The former's idea is to use one "free" register as the argument pointer
value, set on function entry before the stack pointer is aligned.
Typically, for
int main (int argc, char * argv [])
{
int x = argc;
return 0;
}
we get code like (gcc -S -fverbose-asm)
.globl main
.type main, @function
main:
leal 4(%esp), %ecx #, save arg pointer
andl $-16, %esp #, align sp
pushl -4(%ecx) #
pushl %ebp # ...
movl %esp, %ebp #, misc details
pushl %ecx # ...
subl $16, %esp #,
movl (%ecx), %eax # argc, argc use arg pointer
movl %eax, -8(%ebp) # argc, x
...
With -pg, a call to mcount is inserted between the "save" and the
"use", just before the use in the specific case above.
There is nothing to guarantee that mcount won't clobber ecx in the
absolute (no ABI mandate), and there is a clear problem when this happens.
It turns out not to happen on linux and windows, hence not to be
extremely visible, because mcount explicitly preserves the normally
call clobbered regs.
We have seen the problem on at least freebsd and solaris, still, and I
think this is what http://gcc.gnu.org/ml/gcc/2006-12/msg00319.html is
about with DJGPP.
The code below exposes the problem on i386-solaris, where it aborts
when compiled with -pg:
#define EXPECTED_ARG 0x12345678
void __attribute__ ((force_align_arg_pointer)) foo (int arg)
{
if (arg != EXPECTED_ARG)
abort ();
}
int main (int argc, char *argv[])
{
foo (EXPECTED_ARG);
return 0;
}
The attached patch is a suggestion to address this by having
x86_function_profiler save/restore the "force_align_arg_pointer"
register as needed, either because the mcount we call might clobber
it, or if it conflicts with PROFILE_COUNT_REGNUM and we are setting
the latter as an mcount argument.
It splits the function into 32 and 64 bits variants for readability
purposes, and turns PROFILE_COUNT_REGISTER into PROFILE_COUNT_REGNUM
to make comparisons against force_align_arg_pointer easier.
Bootstrapped and regression tested for c,c++,objc,ada on
i386-pc-solaris2.10 + for all,ada on x86_64-redhat-linux.
Thanks in advance,
Olivier
2007-02-26 Olivier Hainque <hainque@adacore.com>
gcc/
* config/i386/i386.h (PROFILE_COUNT_REGISTER): Turn into ...
(PROFILE_COUNT_REGNUM): New macro.
(MCOUNT_PRESERVES_ALL_REGS): New macro, tells whether mcount
preserves all regs. Default to 1 here, to be redefined by subtarget
configurations as needed.
* config/i386/i386.c (X86_SET_PROFILE_COUNTERS): New local macro,
always defined. Conveys whether NO_PROFILE_COUNTERS is defined.
(x86_function_profiler): Split into ...
(x86_64_function_profiler): New function, and
(x86_32_function_profiler): New function. Save/restore the
force_align_arg_pointer register when needed.
* config/i386/sol2.h (MCOUNT_PRESERVES_ALL_REGS): Redefine to 0.
testsuite/
* gcc.target/i386/force_align_mcount.c: New case.
Attachment:
force_align_mcount.dif
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |