Web lists-archives.com

Re: linker error with gcc flag -mfunction-return=thunk




[Cc'ing JonY and Yaakov, just for pinging]

On Jun 25 14:41, Corinna Vinschen wrote:
> On Jun 25 14:16, Corinna Vinschen wrote:
> > On Jun 25 14:08, Michael Haubenwallner wrote:
> > > Hi,
> > > 
> > > I'm encountering a package's configure script (openssh-7.7p1) that
> > > successfully tests for the compiler flag "-mfunction-return=thunk",
> > > which causes subsequent linker errors (and fails to identify zlib):
> > >  relocation truncated to fit: R_X86_64_32S against `.text'
> > > 
> > > The compiler used is gcc-7.3.0 with binutils-2.29.1.20171006 (current),
> > > and the easiest test case here is:
> > > 
> > > $ echo 'int main() { return 0; }' > conftest.c
> > > $ gcc -mfunction-return=thunk conftest.c
> > > /tmp/ccv1Ird0.o:conftest.c:(.text+0x1a): relocation truncated to fit: R_X86_64_32S against `.text'
> > > collect2: error: ld returned 1 exit status
> > > 
> > > Not sure though where to finally report this problem:
> > > * openssh, as they should do a link-test rather than compile-test
> > > * gcc, as their generated code is wrong for cygwin
> > > * binutils, as their ld is unable to link that code
> > > * cygwin, as the maintainers of cygwin support in binutils+gcc
> > > 
> > > After all, openssh-7.7p1-1.src cygwin package currently fails to compile.
> > 
> > configure with --without-hardening for the time being.
> 
> First of all, I think this needs fixing in gcc/binutils.
> 
> However, interesting problem!  I just tested this with your above
> testcase and it failed, as expected.  Then I tweaked the openssh
> configure.ac file to use OSSH_CHECK_CFLAG_LINK rather than
> OSSH_CHECK_CFLAG_COMPILE and to my surprise the link stage
> succeeded!  So I tried this again with the conftest.c file used
> by the OpenSSH configure.ac and yes, it works!
> 
> $ cat > conftest.c <<EOF
> #include <stdlib.h>
> #include <stdio.h>
> int main(int argc, char **argv) {
>       /* Some math to catch -ftrapv problems in the toolchain */
>       int i = 123 * argc, j = 456 + argc, k = 789 - argc;
>       float l = i * 2.1;
>       double m = l / 0.5;
>       long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
>       printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
>       exit(0);
> }
> EOF
> $ gcc -o conftest.exe -ggdb -O2 -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector-strong --param=ssp-buffer-size=4 -fdebug-prefix-map=/cygwin/src/openssh/openssh-7.7p1/openssh-7.7p1-1.x86_64/build=/usr/src/debug/openssh-7.7p1-1 -fdebug-prefix-map=/cygwin/src/openssh/openssh-7.7p1/openssh-7.7p1-1.x86_64/src/openssh-7.7p1=/usr/src/debug/openssh-7.7p1-1 -pipe -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -Werror -mfunction-return=thunk conftest.c
> $
> 
> Yes, no error.  The reason is that the code never returns due to calling
> exit(0), rather than return 0.  Given that exit is a noreturn function,
> the thunking doesn't take place in the testcase.

Worse, -mindirect-branch=thunk appears to result in the same
problem for more complex code, but works fine for the conftest
testcase, even with exit(0) replace by return 0.

There's the following info in the gcc manual:

     Note that '-mcmodel=large' is incompatible with
     '-mindirect-branch=thunk' nor '-mindirect-branch=thunk-extern'
     since the thunk function may not be reachable in large code model.

     [...]

     Note that '-mcmodel=large' is incompatible with
     '-mfunction-return=thunk' nor '-mfunction-return=thunk-extern'
     since the thunk function may not be reachable in large code model.

Is it possible that the gcc devs forgot the -mcmodel=medium case
which is used by Cygwin?!?


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

Attachment: signature.asc
Description: PGP signature