Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

error in backend: Segmented stacks do not support vararg functions. #39689

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR40718
Status CONFIRMED
Importance P enhancement
Reported by Benedikt Tröster (benjima@gmail.com)
Reported on 2019-02-13 06:27:40 -0800
Last modified on 2019-02-25 10:25:10 -0800
Version 8.0
Hardware PC Linux
CC benjima@gmail.com, craig.topper@gmail.com, htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, llvm-dev@redking.me.uk, neeilans@live.com, richard-llvm@metafoo.co.uk, rnk@google.com, sanjoy@playingwithpointers.com, spatel+llvm@rotateright.com
Fixed by commit(s)
Attachments clang-attachments.zip (360038 bytes, application/x-zip-compressed)
Blocks
Blocked by
See also
Created attachment 21473
packed cgo-gcc-input-266913532-73e194.c and cgo-gcc-input-266913532-73e194.sh

Hi!

I'm not really sure what the problem with the code is, but I've attached the
files mentioned by clang.

Some background: I'm working with gollvm to compile C code that is being used
in Go.

Hopefully this can shed some light on a workaround, as I would like to be able
to compile. Could it be, that the "-fsplit-stack" invokation leads to this?

CGO_LDFLAGS='"-g" "-O2" "-lrt"' /root/llvm-install/tools/cgo -objdir
$WORK/b002/ -importpath karalabe-hid/karalabe/hid -gccgo -gccgopkgpath=karalabe-
hid/karalabe/hid -exportheader=$WORK/b002/_cgo_install.h -- -
fsanitize=fuzzer,memory -I $WORK/b002/ -g -O2 -I/root/go/src/karalabe-
hid/karalabe/hid/hidapi/hidapi -I/root/go/src/karalabe-
hid/karalabe/hid/libusb/libusb -DDEFAULT_VISIBILITY= -DOS_LINUX -D_GNU_SOURCE -
DPOLL_NFDS_TYPE=int -fsplit-stack ./hid_enabled.go ./wchar.go
# karalabe-hid/karalabe/hid
fatal error: error in backend: Segmented stacks do not support vararg functions.
clang-8: error: clang frontend command failed with exit code 70 (use -v to see
invocation)
clang version 8.0.0
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
clang-8: note: diagnostic msg: PLEASE submit a bug report to
https://bugs.llvm.org/ and include the crash backtrace, preprocessed source,
and associated run script.
clang-8: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-8: note: diagnostic msg: /tmp/cgo-gcc-input-266913532-73e194.c
clang-8: note: diagnostic msg: /tmp/cgo-gcc-input-266913532-73e194.sh
clang-8: note: diagnostic msg:

********************
Quuxplusone commented 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

Quuxplusone commented 5 years ago

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?

Quuxplusone commented 5 years ago

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.

Quuxplusone commented 5 years ago

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.

Quuxplusone commented 5 years ago

If I may ask, is there some work-around for this that I could use to compile the code?

Quuxplusone commented 5 years ago
(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
Quuxplusone commented 5 years ago
(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. :)