[llvm-bugs] [Bug 34670] New: -fsplit-stack omits .note.GNU-split-stack section marker
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Sep 19 07:02:19 PDT 2017
https://bugs.llvm.org/show_bug.cgi?id=34670
Bug ID: 34670
Summary: -fsplit-stack omits .note.GNU-split-stack section
marker
Product: libraries
Version: trunk
Hardware: All
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Backend: X86
Assignee: unassignedbugs at nondot.org
Reporter: thanm at google.com
CC: llvm-bugs at lists.llvm.org
Created attachment 19172
--> https://bugs.llvm.org/attachment.cgi?id=19172&action=edit
tar file with repro sources
The implementation of "-fsplit-stack" in LLVM is missing a piece, specifically
marker/note section indicating whether the generated object file has been
compiled with -fsplit-stack. This marker is consumed by the gold linker, which
uses it to handle cases where there is call from a split-stack routine to a
non-split-stack routine. See https://gcc.gnu.org/wiki/SplitStacks in the
section on "Backward compatibility".
Example with gcc:
% gcc -fPIC -g -m64 -c mod1.c
% objdump -h mod1.o | fgrep split
% gcc -fPIC -g -m64 -c mod1.c -fsplit-stack
% objdump -h mod1.o | fgrep split 3 .note.GNU-split-stack 00000000
0000000000000000 0000000000000000 0000010d 2**0
%
Example with clang:
% clang -fPIC -g -m64 -c mod1.c
% objdump -h mod1.o | fgrep split
% clang -fPIC -g -m64 -c mod1.c -fsplit-stack
% objdump -h mod1.o | fgrep split
%
Programs built with "clang -fsplit-stack" will probably work in some cases, but
if there is a call from a split-stack routine to a non-split-stack routine (say
in a third party library), the callee will inherit the (smaller) stack segment
from the caller, meaning that it may wind up running out of stack space in that
scenario. With the marker present, the Gold linker will fix up the caller to
insure that it passes in a larger stack segment.
I'm attaching a zip file with a test case that illustrates. In this test there
is a main "test" program and two shared libraries, "mod1.so" and "mod2.so".
Functions in "mod1.so" are built with -fsplit-stack, whereas functions in
mod2.so are not compiled with that option. There is a call from mod1.so into
the function "mod2" in mod2.so, where 'mod2' winds up using ~50k worth of stack
space, which causes it to crash.
Reproduction instructions:
1. unpack tar file (contains main.c makefile mod1.c mod2.c mod.h).
2. run "make clean run CC=<path-to-C-compiler-to-test>", inspect output.
Example run (amd64 linux) with clang:
% make clean run CC=clang
rm -f *.asm *.so *.o test
clang -fPIC -fsplit-stack -g -m64 -c mod1.c -o mod1.o
clang -fPIC -g -m64 -c mod2.c -o mod2.o
clang -shared -g -m64 mod2.o -o mod2.so
clang -shared -g -m64 mod1.o -o mod1.so mod2.so
clang -g -m64 -c main.c -o main.o
clang -fsplit-stack -g -m64 main.o mod1.so mod2.so -o test
LD_LIBRARY_PATH=`pwd` ./test 11
10 0 249
est space: 5984
make: *** [run] Segmentation fault (core dumped)
LD_LIBRARY_PATH=`pwd` ./test 101
make: *** [run] Segmentation fault (core dumped)
%
Example run (amd64 linux) with gcc:
% make clean run CC=gcc
rm -f *.asm *.so *.o test
gcc -fPIC -fsplit-stack -g -m64 -c mod1.c -o mod1.o
gcc -fPIC -g -m64 -c mod2.c -o mod2.o
gcc -shared -g -m64 mod2.o -o mod2.so
gcc -shared -g -m64 mod1.o -o mod1.so mod2.so
gcc -g -m64 -c main.c -o main.o
gcc -fsplit-stack -g -m64 main.o mod1.so mod2.so -o test
LD_LIBRARY_PATH=`pwd` ./test 11
10 0 249
est space: 5808
LD_LIBRARY_PATH=`pwd` ./test 101
100 90 80 70 60 50 40 30 20 10 0 147
est space: 53328
Note: the expectation is that the version of "ld" in $PATH points to the Gold
linker, not the BFD linker (since Gold has support for fixing up split to
nonsplit calls).
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170919/2bee84c4/attachment-0001.html>
More information about the llvm-bugs
mailing list