Hello! Attached patch detect support for AES instructions and avoids compiling runtime/aeshash.c with older assemblers (on e.g. CentOS 5.11). The result of configure is also communicated into go runtime, so the library doesn't try to call non-existent aeshashbody routine.
Patch was tested on x86_64-linux-gnu, on Fedora 25 with AES capable CPU and on CentOS 5.11 with non-AES capable CPU. Uros.
Index: config.h.in =================================================================== --- config.h.in (revision 244024) +++ config.h.in (working copy) @@ -21,6 +21,9 @@ /* Define if your assembler supports unwind section type. */ #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE +/* Define if your assembler supports AES instructions. */ +#undef HAVE_AS_X86_AES + /* Define if your assembler supports PC relative relocs. */ #undef HAVE_AS_X86_PCREL Index: configure =================================================================== --- configure (revision 244024) +++ configure (working copy) @@ -15490,6 +15490,32 @@ fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports AES instructions" >&5 +$as_echo_n "checking assembler supports AES instructions... " >&6; } +if test "${libgo_cv_as_x86_aes+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +libgo_cv_as_x86_aes=yes +echo 'aesenc %xmm0, %xmm1' > conftest.s +CFLAGS_hold=$CFLAGS +if test "$libgo_cv_c_unused_arguments" = yes; then + CFLAGS="$CFLAGS -Qunused-arguments" +fi +if $CC $CFLAGS -c conftest.s 2>&1 | grep -i error > /dev/null; then + libgo_cv_as_x86_aes=no +fi +CFLAGS=$CFLAGS_hold + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_as_x86_aes" >&5 +$as_echo "$libgo_cv_as_x86_aes" >&6; } +if test "x$libgo_cv_as_x86_aes" = xyes; then + +$as_echo "#define HAVE_AS_X86_AES 1" >>confdefs.h + +fi + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure Index: configure.ac =================================================================== --- configure.ac (revision 244024) +++ configure.ac (working copy) @@ -934,6 +934,24 @@ [Define if your assembler supports unwind section type.]) fi +AC_CACHE_CHECK([assembler supports AES instructions], +libgo_cv_as_x86_aes, [ +libgo_cv_as_x86_aes=yes +echo 'aesenc %xmm0, %xmm1' > conftest.s +CFLAGS_hold=$CFLAGS +if test "$libgo_cv_c_unused_arguments" = yes; then + CFLAGS="$CFLAGS -Qunused-arguments" +fi +if $CC $CFLAGS -c conftest.s 2>&1 | grep -i error > /dev/null; then + libgo_cv_as_x86_aes=no +fi +CFLAGS=$CFLAGS_hold +]) +if test "x$libgo_cv_as_x86_aes" = xyes; then + AC_DEFINE(HAVE_AS_X86_AES, 1, + [Define if your assembler supports AES instructions.]) +fi + AC_CACHE_SAVE if test ${multilib} = yes; then Index: go/runtime/alg.go =================================================================== --- go/runtime/alg.go (revision 244024) +++ go/runtime/alg.go (working copy) @@ -233,6 +233,7 @@ // Install aes hash algorithm if we have the instructions we need if (GOARCH == "386" || GOARCH == "amd64") && GOOS != "nacl" && + support_aes && cpuid_ecx&(1<<25) != 0 && // aes (aesenc) cpuid_ecx&(1<<9) != 0 && // sse3 (pshufb) cpuid_ecx&(1<<19) != 0 { // sse4.1 (pinsr{d,q}) Index: go/runtime/runtime2.go =================================================================== --- go/runtime/runtime2.go (revision 244024) +++ go/runtime/runtime2.go (working copy) @@ -771,7 +771,8 @@ // Information about what cpu features are available. // Set on startup. - cpuid_ecx uint32 + cpuid_ecx uint32 + support_aes bool // cpuid_edx uint32 // cpuid_ebx7 uint32 Index: go/runtime/stubs.go =================================================================== --- go/runtime/stubs.go (revision 244024) +++ go/runtime/stubs.go (working copy) @@ -272,6 +272,12 @@ cpuid_ecx = v } +// For gccgo, to communicate from the C code to the Go code. +//go:linkname setSupportAES runtime.setSupportAES +func setSupportAES(v bool) { + support_aes = v +} + // typedmemmove copies a typed value. // For gccgo for now. //go:nosplit Index: runtime/aeshash.c =================================================================== --- runtime/aeshash.c (revision 244024) +++ runtime/aeshash.c (working copy) @@ -12,7 +12,7 @@ uintptr aeshashbody(void*, uintptr, uintptr, Slice) __attribute__((no_split_stack)); -#if defined(__i386__) || defined(__x86_64__) +#if (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_AS_X86_AES) #include <emmintrin.h> #include <tmmintrin.h> @@ -573,7 +573,7 @@ #endif // !defined(__x86_64__) -#else // !defined(__i386__) && !defined(__x86_64__) +#else // !defined(__i386__) && !defined(__x86_64__) || !defined(HAVE_AS_X86_AES) uintptr aeshashbody(void* p __attribute__((unused)), uintptr seed __attribute__((unused)), @@ -583,4 +583,4 @@ runtime_throw("impossible call to aeshashbody"); } -#endif // !defined(__i386__) && !defined(__x86_64__) +#endif // !defined(__i386__) && !defined(__x86_64__) || !defined(HAVE_AS_X86_AES) Index: runtime/runtime.h =================================================================== --- runtime/runtime.h (revision 244024) +++ runtime/runtime.h (working copy) @@ -599,6 +599,8 @@ __asm__ (GOSYM_PREFIX "runtime.setIsCgo"); extern void setCpuidECX(uint32) __asm__ (GOSYM_PREFIX "runtime.setCpuidECX"); +extern void setSupportAES(bool) + __asm__ (GOSYM_PREFIX "runtime.setSupportAES"); extern void makeMainInitDone(void) __asm__ (GOSYM_PREFIX "runtime.makeMainInitDone"); extern void closeMainInitDone(void) Index: runtime/runtime_c.c =================================================================== --- runtime/runtime_c.c (revision 244024) +++ runtime/runtime_c.c (working copy) @@ -190,5 +190,9 @@ if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { setCpuidECX(ecx); } + +#if defined(HAVE_AS_X86_AES) + setSupportAES(true); #endif +#endif }