Open Quuxplusone opened 5 years ago
Attached clang-attachments.zip
(360038 bytes, application/x-zip-compressed): packed cgo-gcc-input-266913532-73e194.c and cgo-gcc-input-266913532-73e194.sh
Sanjoy, I looked at the code generated for split stack checks, and I don't see why we would need to exclude variadic functions. Any reason we shouldn't just remove the check?
This was a while back, but IIRC when expanding stack we need to copy over the incoming arguments to the new stacklet which means we need to know how many args we have on stack. We don't have this information for varargs function calls.
https://gcc.gnu.org/wiki/SplitStacks says "For varargs functions, this is impossible in general, so we will compile varargs functions differently: they will use an argument pointer which is not necessarily based on the frame pointer." so maybe we can indeed enable varargs with some work.
I see. I spent more time looking at the code that GCC generates and the __morestack routine in libgcc, and I see how it's supposed to work.
Here's the split stack prologue and the morestack stub:
_Z3fooPKcz: .LFB12: .cfi_startproc leaq -728(%rsp), %r11 cmpq %fs:112, %r11 jb .L9 leaq 8(%rsp), %r11 # STACK VARARGS .L7: pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 subq $720, %rsp .cfi_def_cfa_offset 736 ... .L9: .cfi_restore 3 movl $728, %r10d movl $0, %r11d call __morestack ret leaq 24(%rbp), %r11 # STACK VARARGS jmp .L7
Variadic arguments are left on the old stack. The address of the first variadic argument (computable with FuncInfo->getVarArgsFrameIndex()) is materialized into R11 at the end of the prologue. R11 is stored into the overflow_arg_area
field of the va_list struct when code generating builtin_va_start. In the morestack code path, the 'leaq 24(%rbp), %r11' instruction computes the address of variadic stack arguments on the old stack before rejoining the main prologue.
If I may ask, is there some work-around for this that I could use to compile the code?
(In reply to Benedikt Tröster from comment #4)
> If I may ask, is there some work-around for this that I could use to compile
> the code?
Well, yes, don't use varargs. (probably not helpful :)
You can also try annotating the relevant function with
__attribute__((no_split_stack)):
https://clang.llvm.org/docs/AttributeReference.html#no-split-stack
(In reply to Reid Kleckner from comment #5)
> (In reply to Benedikt Tröster from comment #4)
> > If I may ask, is there some work-around for this that I could use to compile
> > the code?
>
> Well, yes, don't use varargs. (probably not helpful :)
>
> You can also try annotating the relevant function with
> __attribute__((no_split_stack)):
> https://clang.llvm.org/docs/AttributeReference.html#no-split-stack
Thanks, will try. :)
clang-attachments.zip
(360038 bytes, application/x-zip-compressed)