Restrict global constructors base ISA?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Restrict global constructors base ISA?

Jeffrey Walton-3
I'm testing on older OS X 10.8 with older SSE4 hardware from about
2010. I've got updated gear from MacPorts and it includes GCC and
Clang. GCC is the compiler, and Clang is the assembler.

We perform a compile/link on a test file to ensure an ISA is supported
by the toolchain. If an ISA is available then we compile a source file
to the ISA. Then, we guard the higher ISAs at runtime to avoid
SIGILLs. It worked well until we added AVX2.

At AVX2 we see this as expected:

    $ CXX=/opt/local/bin/clang++-mp-5.0 make
    /opt/local/bin/clang++-mp-5.0 ... -c chacha.cpp
    /opt/local/bin/clang++-mp-5.0 ... -mavx2 -c chacha_avx.cpp
    /opt/local/bin/clang++-mp-5.0 ... -msse2 -c chacha_simd.cpp

At runtime we catch a SIGILL due to chacha_avx.cpp as shown below. It
looks like global constructors are using instructions from AVX (vxorps
), which is beyond what the machine can support.

How do we tell GCC to use the base ISA for global constructors?

Thanks in advance.

==========

(lldb) r v
...
* thread #1: tid = 0x19f83aa, 0x000000010016ec49
cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at string:1322, queue =
'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION
(code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x000000010016ec49
cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at string:1322
   1319         {
   1320             size_type (&__a)[__n_words] = __r_.first().__r.__words;
   1321             for (unsigned __i = 0; __i < __n_words; ++__i)
-> 1322                 __a[__i] = 0;
   1323         }
   1324
   1325     template <size_type __a> static

And:

(lldb) disass
cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at chacha_avx.cpp:
   0x10016ec30:  pushq  %rbp
   0x10016ec31:  movq   %rsp, %rbp
   0x10016ec34:  pushq  %r14
   0x10016ec36:  pushq  %rbx
   0x10016ec37:  movq   0x24cf8a(%rip), %rax      ; (void
*)0x00000001003e69f0: vtable for CryptoPP::NullNameValuePairs
   0x10016ec3e:  addq   $0x10, %rax
   0x10016ec42:  movq   %rax, 0x2dfb6f(%rip)      ;
CryptoPP::s_nullNameValuePairs
-> 0x10016ec49:  vxorps %xmm0, %xmm0, %xmm0
   0x10016ec4d:  vmovups %xmm0, 0x2dfb6b(%rip)     ; CryptoPP::DEFAULT_CHANNEL
   0x10016ec55:  movq   $0x0, 0x2dfb70(%rip)      ;
CryptoPP::DEFAULT_CHANNEL + 12
   0x10016ec60:  leaq   0x2dfb59(%rip), %rsi      ; CryptoPP::DEFAULT_CHANNEL
   0x10016ec67:  movq   0x24ba52(%rip), %rbx      ; (void
*)0x00007fff8f09321e: std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char>
>::~basic_string()
   0x10016ec6e:  leaq   -0x16ec75(%rip), %r14     ; _mh_execute_header
   ...
Reply | Threaded
Open this post in threaded view
|

Re: Restrict global constructors base ISA?

Jeffrey Walton-3
Wrong list... please disregard.
On Sat, Dec 1, 2018 at 4:53 AM Jeffrey Walton <[hidden email]> wrote:

>
> I'm testing on older OS X 10.8 with older SSE4 hardware from about
> 2010. I've got updated gear from MacPorts and it includes GCC and
> Clang. GCC is the compiler, and Clang is the assembler.
>
> We perform a compile/link on a test file to ensure an ISA is supported
> by the toolchain. If an ISA is available then we compile a source file
> to the ISA. Then, we guard the higher ISAs at runtime to avoid
> SIGILLs. It worked well until we added AVX2.
>
> At AVX2 we see this as expected:
>
>     $ CXX=/opt/local/bin/clang++-mp-5.0 make
>     /opt/local/bin/clang++-mp-5.0 ... -c chacha.cpp
>     /opt/local/bin/clang++-mp-5.0 ... -mavx2 -c chacha_avx.cpp
>     /opt/local/bin/clang++-mp-5.0 ... -msse2 -c chacha_simd.cpp
>
> At runtime we catch a SIGILL due to chacha_avx.cpp as shown below. It
> looks like global constructors are using instructions from AVX (vxorps
> ), which is beyond what the machine can support.
>
> How do we tell GCC to use the base ISA for global constructors?
>
> Thanks in advance.
>
> ==========
>
> (lldb) r v
> ...
> * thread #1: tid = 0x19f83aa, 0x000000010016ec49
> cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at string:1322, queue =
> 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION
> (code=EXC_I386_INVOP, subcode=0x0)
>     frame #0: 0x000000010016ec49
> cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at string:1322
>    1319         {
>    1320             size_type (&__a)[__n_words] = __r_.first().__r.__words;
>    1321             for (unsigned __i = 0; __i < __n_words; ++__i)
> -> 1322                 __a[__i] = 0;
>    1323         }
>    1324
>    1325     template <size_type __a> static
>
> And:
>
> (lldb) disass
> cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at chacha_avx.cpp:
>    0x10016ec30:  pushq  %rbp
>    0x10016ec31:  movq   %rsp, %rbp
>    0x10016ec34:  pushq  %r14
>    0x10016ec36:  pushq  %rbx
>    0x10016ec37:  movq   0x24cf8a(%rip), %rax      ; (void
> *)0x00000001003e69f0: vtable for CryptoPP::NullNameValuePairs
>    0x10016ec3e:  addq   $0x10, %rax
>    0x10016ec42:  movq   %rax, 0x2dfb6f(%rip)      ;
> CryptoPP::s_nullNameValuePairs
> -> 0x10016ec49:  vxorps %xmm0, %xmm0, %xmm0
>    0x10016ec4d:  vmovups %xmm0, 0x2dfb6b(%rip)     ; CryptoPP::DEFAULT_CHANNEL
>    0x10016ec55:  movq   $0x0, 0x2dfb70(%rip)      ;
> CryptoPP::DEFAULT_CHANNEL + 12
>    0x10016ec60:  leaq   0x2dfb59(%rip), %rsi      ; CryptoPP::DEFAULT_CHANNEL
>    0x10016ec67:  movq   0x24ba52(%rip), %rbx      ; (void
> *)0x00007fff8f09321e: std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char>
> >::~basic_string()
>    0x10016ec6e:  leaq   -0x16ec75(%rip), %r14     ; _mh_execute_header
>    ...