<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - -fsplit-stack omits .note.GNU-split-stack section marker"
   href="https://bugs.llvm.org/show_bug.cgi?id=34670">34670</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>-fsplit-stack omits .note.GNU-split-stack section marker
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Backend: X86
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>thanm@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=19172" name="attach_19172" title="tar file with repro sources">attachment 19172</a> <a href="attachment.cgi?id=19172&action=edit" title="tar file with repro sources">[details]</a></span>
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 <a href="https://gcc.gnu.org/wiki/SplitStacks">https://gcc.gnu.org/wiki/SplitStacks</a> 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).</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>