Description of problem: I'd like to be able to cross-compile the Linux kernel on ppc64 for x86_64. The cross-compiler for the x86_64 target is unable to compile a kernel with CONFIG_CC_STACKPROTECTOR=y. Version-Release number of selected component (if applicable): gcc-x86_64-linux-gnu-5.1.1-2.fc22 How reproducible: always Steps to Reproduce: 1. Run the test the Linux kernel build uses to detect the compiler's ability to generate stack protector code: echo "int foo(void) { char X[200]; return 3; }" | x86_64-linux-gnu-gcc -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - Actual results: The generated code refers to __stack_chk_guard: ... movq __stack_chk_guard(%rip), %rax movq %rax, -8(%rbp) xorl %eax, %eax movl $3, %eax movq -8(%rbp), %rdx xorq __stack_chk_guard(%rip), %rdx je .L3 call __stack_chk_fail ... Expected results: It should use the %gs segment register to access the canary: ... movq %gs:40, %rax movq %rax, -8(%rbp) xorl %eax, %eax movl $3, %eax movq -8(%rbp), %rdx xorq %gs:40, %rdx je .L3 call __stack_chk_fail ... Additional info: I looked into how cross-gcc is built and the problem seems to be this: gcc is configured with "--without-headers". The configure script checks for whether the target libc provides SSP (TARGET_LIBC_PROVIDES_SSP). In this case it will be false. The definition of TARGET_THREAD_SSP_OFFSET is conditional under "#ifdef TARGET_LIBC_PROVIDES_SSP" (in gcc/config/i386/gnu-user64.h), so it will not be defined. config/i386/i386.md describes how to generate stack protector code. It will use TLS canary only if "#ifdef TARGET_THREAD_SSP_OFFSET". Possible solutions: A) Add a hack to cross-gcc.spec to convince the configure script that the target libc does indeed provide SSP. Ugly, but easy: ./configure [...] gcc_cv_libc_provides_ssp=yes B) Build cross-gcc against glibc headers. Complicated. (http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/) C) Treat it as an upstream gcc bug that even with "-mcmodel=kernel" it generates different code based on what it thinks it knows about the target libc.
(In reply to Michal Schmidt from comment #0) > B) Build cross-gcc against glibc headers. Complicated. > (http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/) Yeah, complicated. If I do it for one arch, I really have to do it for all. However, this leads to a multiplicative effect on those arches that support multiple different configurations (including things like LE/BE variations). Further, not all arches support glibc, so I'd have to build some against uClibc instead or as well (FRV, for example, does not support glibc in conjunction with nommu subarches).
(In reply to Michal Schmidt from comment #0) > C) Treat it as an upstream gcc bug that even with "-mcmodel=kernel" it > generates different code based on what it thinks it knows about the > target libc. Okay, I think I prefer this. Raised against gcc as: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66491
(In reply to Michal Schmidt from comment #0) > A) Add a hack to cross-gcc.spec to convince the configure script that > the target libc does indeed provide SSP. Ugly, but easy: > ./configure [...] gcc_cv_libc_provides_ssp=yes This works, but the qualifier needs to be passed to make rather than configure as it's not used by the base configure.
cross-gcc-5.1.1-3.fc22 has been submitted as an update for Fedora 22. https://admin.fedoraproject.org/updates/cross-gcc-5.1.1-3.fc22
cross-gcc-5.1.1-3.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.