2a3e3873a1
1 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Jeremie Le Hen
|
54f82841d5 |
Turn libc.so into an ld script rather than a symlink pointing to the
real shared object and libssp_nonshared.a. This was the last showstopper that prevented from enabling SSP for ports by default. portmgr@ performed a buildworld which showed no significant breakage with this patch. Details: On i386 for PIC objects, gcc uses the __stack_chk_fail_local hidden symbol instead of calling __stack_chk_fail directly [1]. This happen not only with our gcc-4.2.1 but also with the latest gcc-4.8. If you want the very nasty details, see [2]. OTOH the problem doesn't exist on other architectures. It also doesn't exist with Clang as the latter will somehow manage to create the function in the object file at compile time (contrary to only referencing it through a symbol that will be brought in at link time). In a perfect world, when an object file is compiled with -fstack-protector, it will be linked into a binary or a DSO with this same flag as well, so GCC will add libssp_nonshared.a to the linker command-line. Unfortunately, we don't control softwares in ports and we may have such broken DSO. This is the whole point of this patch. You can reproduce the problem on i386 by compiling a source file into an object file with "-fstack-protector-all -fPIE" and linking it into a binary without "-fstack-protector". This ld script automatically proposes libssp_nonshared.a along with the real libc DSO to the linker. It is important to understand that the object file contained in this library will be pulled in the resulting binary _only if_ the linker notices one of its symbols is needed (i.e. one of the SSP symbol is missing). A theorical performance impact could be when compiling, but my testing showed less than 0.1% of difference. [1] For 32-bit code gcc saves the PIC register setup by using __stack_chk_fail_local hidden function instead of calling __stack_chk_fail directly. See comment line 19460 in: src/contrib/gcc/config/i386/i386.c [2] When compiling a source file to an object file, if you use something which is external to the compilation unit, GCC doesn't know yet if this symbol will be inside or outside the DSO. So it expects the worst case and routes the symbol through the GOT, which means additional space and extra relocation for rtld(1). Declaring a symbol has hidden tells GCC to use the optimal route (no GOT), but on the other hand this means the symbol has to be provided in the same DSO (namely libssp_nonshared.a). On i386, GCC actually uses an hidden symbol for SSP in PIC objects to save PIC register setup, as said in [1]. PR: ports/138228 PR: ports/168010 Reviewed by: kib, kan |