This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
unwind, x86, DW_CFA_GNU_args_size
- From: Geoffrey Keating <geoffk at apple dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>, GCC Mailing List <gcc at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Fri, 18 Aug 2006 16:07:55 -0700
- Subject: unwind, x86, DW_CFA_GNU_args_size
Hi Alexandre,
your patch,
------------------------------------------------------------------------
r112170 | aoliva | 2006-03-16 22:08:49 -0800 (Thu, 16 Mar 2006) | 4
lines
* dwarf2out.c (dwarf2out_stack_adjust): Always track the stack
pointer, instead of assuming it is possible to derive the
correct args size from a call insn.
discussed in <http://gcc.gnu.org/ml/gcc-patches/2006-03/
msg01039.html>, is causing g++.brendan/eh1.C to fail on x86-darwin.
The problem is that the patch assumes that it's possible to track the
stack pointer. I don't think this is possible and it's certainly not
done right by this code.
The problem is that the code ignores all instructions in the
prologue. It happens, in eh1.C, that a stack adjustment (to enforce
stack alignment) for the call is combined with a different stack
adjustment (to allocate a local variable) in the prologue, by the
'csa' phase. There's no way to get this right without knowing that
this is happening, and as far as I can see there's no information
available that it happened. The final code looks like:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $16, %esp # the stack push that is combined
call L6
"L00000000001$pb":
L6:
popl %ebx # last instruction in prolog
pushl $4
call L___cxa_allocate_exception$stub # this routine has
16 bytes of arguments
movl $99, (%eax)
addl $12, %esp # stack adjust preparing for next call
pushl $0
pushl L__ZTIi$non_lazy_ptr-"L00000000001$pb"(%ebx)
pushl %eax
call L___cxa_throw$stub
The EH information says that __cxa_allocate_exception has 4 bytes of
args, and __cxa_throw has 12 bytes of args; but really they both have
16 bytes of args.
The effect of all this on Darwin is that the stack becomes misaligned
and then the dynamic loader crashes when it tries to use SSE (or
something).
I think possible solutions are:
1. Revert this patch, and note that the original bug (which you
mention you couldn't reproduce on 4.0+) might not be fixed.
2. Remove the whole routine and declare that if you want to use EH,
you must not have ACCUMULATE_OUTGOING_ARGS set.
3. Try to patch around it by looking at the argument size in the
call, and if it's greater than the apparent argument size, using the
value in the call instead.
4. Make the routine much more intelligent, or ideally have the proper
information attached to the call at the time it's generated (as a
note?), and just use that. Add gcc_assert calls to verify that (a)
the argument size never becomes negative and (b) the argument size is
never less than the size of each particular call.
I prefer (1). Next best would be (4), but it's likely to break some
ports. (3) doesn't sound very good, and (2) removes a feature.
Any other suggestions?Attachment:
smime.p7s
Description: S/MIME cryptographic signature