Compiling the 'eix' program with gcc 9.3.0 and the '-march=i486' generated an 'endbr32' opcode. This is an undefined opcode on an i486. # /usr/bin/gdb /usr/bin/eix GNU gdb (Gentoo 10.1 vanilla) 10.1 ... Reading symbols from /usr/bin/eix... Reading symbols from /usr/lib/debug//usr/bin/eix.debug... (gdb) run Starting program: /usr/bin/eix Program received signal SIGILL, Illegal instruction. _GLOBAL__sub_I_spaces () at eixTk/stringutils.cc:686 686 } (gdb) disassemble _GLOBAL__sub_I_spaces Dump of assembler code for function _GLOBAL__sub_I_spaces(): => 0x004208e0 <+0>: endbr32 0x004208e4 <+4>: push %esi 0x004208e5 <+5>: push %ebx 0x004208e6 <+6>: sub $0xc,%esp 0x004208e9 <+9>: call 0x420d30 <__x86.get_pc_thunk.bx> 0x004208ee <+14>: add $0x17e712,%ebx 0x0042091e <+62>: add $0x14,%esp 0x00420921 <+65>: pop %ebx 0x00420922 <+66>: pop %esi 0x00420923 <+67>: ret (gdb) list 681 if(likely(isutf8firstgyte(t[i]))) { 682 ++len; 683 } 684 } 685 return len; 686 }
Here is the full set of compiler flags used. readelf --string-dump='.GCC.command.line' /usr/lib/debug/$( which eix ).debug String dump of section '.GCC.command.line': [ 0] -I . [ 5] -I .. [ b] -D_GNU_SOURCE [ 19] -D HAVE_CONFIG_H [ 2a] -D SYSCONFDIR="/etc" [ 3f] -D LOCALEDIR="/usr/share/locale" [ 60] -D _FORTIFY_SOURCE=2 [ 75] various/drop_permissions.cc [ 91] -march=i486 [ 9d] -auxbase-strip various/drop_permissions.o [ c7] -g [ ca] -ggdb [ d0] -O2 [ d4] -fdata-sections [ e4] -ffunction-sections [ f8] -fcf-protection=full [ 10d] -fstack-clash-protection [ 126] -frecord-gcc-switches [ 13c] eixTk/compare.cc [ 14d] -auxbase-strip eixTk/compare.o [ 16c] eixTk/formated.cc [ 17e] -auxbase-strip eixTk/formated.o [ 19e] eixTk/stringutils.cc [ 1b3] -auxbase-strip eixTk/stringutils.o [ 1d6] eixTk/ansicolor.cc [ 1e9] -auxbase-strip eixTk/ansicolor.o [ 20a] eixTk/argsreader.cc [ 21e] -auxbase-strip eixTk/argsreader.o [ 240] eixTk/parseerror.cc [ 254] -auxbase-strip eixTk/parseerror.o [ 276] eixTk/regexp.cc [ 286] -auxbase-strip eixTk/regexp.o [ 2a4] eixTk/sysutils.cc [ 2b6] -auxbase-strip eixTk/sysutils.o [ 2d6] eixTk/filenames.cc [ 2e9] -auxbase-strip eixTk/filenames.o [ 30a] eixTk/utils.cc [ 319] -auxbase-strip eixTk/utils.o [ 336] eixTk/varsreader.cc [ 34a] -auxbase-strip eixTk/varsreader.o [ 36c] database/io.cc [ 37b] -auxbase-strip database/io.o [ 398] database/io_header.cc [ 3ae] -auxbase-strip database/io_header.o [ 3d2] database/header.cc [ 3e5] -auxbase-strip database/header.o [ 406] database/header_portage.cc [ 421] -auxbase-strip database/header_portage.o [ 44a] database/io_portage.cc [ 461] -auxbase-strip database/io_portage.o [ 486] database/package_reader.cc [ 4a1] -auxbase-strip database/package_reader.o [ 4ca] portage/conf/portagesettings.cc [ 4ea] -auxbase-strip portage/conf/portagesettings.o [ 518] portage/conf/cascadingprofile.cc [ 539] -auxbase-strip portage/conf/cascadingprofile.o [ 568] eixTk/stringlist.cc [ 57c] -auxbase-strip eixTk/stringlist.o [ 59e] portage/mask.cc [ 5ae] -auxbase-strip portage/mask.o [ 5cc] portage/mask_list.cc [ 5e1] -auxbase-strip portage/mask_list.o [ 604] portage/depend.cc [ 616] -auxbase-strip portage/depend.o [ 636] portage/basicversion.cc [ 64e] -auxbase-strip portage/basicversion.o [ 674] portage/eapi.cc [ 684] -auxbase-strip portage/eapi.o [ 6a2] portage/extendedversion.cc [ 6bd] -auxbase-strip portage/extendedversion.o [ 6e6] portage/extendedversion_bin.cc [ 705] -auxbase-strip portage/extendedversion_bin.o [ 732] portage/instversion.cc [ 749] -auxbase-strip portage/instversion.o [ 76e] portage/package.cc [ 781] -auxbase-strip portage/package.o [ 7a2] portage/package_best.cc [ 7ba] -auxbase-strip portage/package_best.o [ 7e0] portage/packagesets.cc [ 7f7] -auxbase-strip portage/packagesets.o [ 81c] portage/vardbpkg.cc [ 830] -auxbase-strip portage/vardbpkg.o [ 852] portage/packagetree.cc [ 869] -auxbase-strip portage/packagetree.o [ 88e] portage/keywords.cc [ 8a2] -auxbase-strip portage/keywords.o [ 8c4] portage/overlay_bin.cc [ 8db] -auxbase-strip portage/overlay_bin.o [ 900] portage/overlay.cc [ 913] -auxbase-strip portage/overlay.o [ 934] portage/set_stability.cc [ 94d] -auxbase-strip portage/set_stability.o [ 974] portage/version.cc [ 987] -auxbase-strip portage/version.o [ 9a8] eixrc/eixrc.cc [ 9b7] -auxbase-strip eixrc/eixrc.o [ 9d4] eixrc/global.cc [ 9e4] -auxbase-strip eixrc/global.o [ a02] eixrc/globals.cc [ a13] -auxbase-strip eixrc/globals.o [ a32] eixrc/eixrc_portage.cc [ a49] -auxbase-strip eixrc/eixrc_portage.o [ a6e] eixTk/outputstring.cc [ a84] -auxbase-strip eixTk/outputstring.o [ aa8] eixTk/stringlist_output.cc [ ac3] -auxbase-strip eixTk/stringlist_output.o [ aec] portage/version_output.cc [ b06] -auxbase-strip portage/version_output.o [ b2e] output/formatstring.cc [ b45] -auxbase-strip output/formatstring.o [ b6a] output/formatstring-print.cc [ b87] -auxbase-strip output/formatstring-print.o [ bb2] eix.cc [ bb9] -auxbase-strip eix.o [ bce] various/cli.cc [ bdd] -auxbase-strip various/cli.o [ bfa] output/print-proto.cc [ c10] -auxbase-strip output/print-proto.o [ c34] output/print-xml.cc [ c48] -auxbase-strip output/print-xml.o [ c6a] search/levenshtein.cc [ c80] -auxbase-strip search/levenshtein.o [ ca4] search/algorithms.cc [ cb9] -auxbase-strip search/algorithms.o [ cdc] search/matchtree.cc [ cf0] -auxbase-strip search/matchtree.o [ d12] search/packagetest.cc [ d28] -auxbase-strip search/packagetest.o [ d4c] search/packagetest_default.cc [ d6a] -auxbase-strip search/packagetest_default.o [ d96] search/nowarn.cc [ da7] -auxbase-strip search/nowarn.o [ dc6] eixTk/ansicolor_print.cc [ ddf] -auxbase-strip eixTk/ansicolor_print.o [ e06] eix-diff.cc [ e12] -auxbase-strip eix-diff.o [ e2c] eix-update.cc [ e3a] -auxbase-strip eix-update.o [ e56] eixTk/percentage.cc [ e6a] -auxbase-strip eixTk/percentage.o [ e8c] eixTk/statusline.cc [ ea0] -auxbase-strip eixTk/statusline.o [ ec2] cache/cachetable.cc [ ed6] -auxbase-strip cache/cachetable.o [ ef8] cache/common/assign_reader.cc [ f16] -auxbase-strip cache/common/assign_reader.o [ f42] cache/common/ebuild_exec.cc [ f5e] -auxbase-strip cache/common/ebuild_exec.o [ f88] cache/common/flat_reader.cc [ fa4] -auxbase-strip cache/common/flat_reader.o [ fce] cache/common/selectors.cc [ fe8] -auxbase-strip cache/common/selectors.o [ 1010] cache/base.cc [ 101e] -auxbase-strip cache/base.o [ 103a] cache/eixcache/eixcache.cc [ 1055] -auxbase-strip cache/eixcache/eixcache.o [ 107e] cache/metadata/metadata.cc [ 1099] -auxbase-strip cache/metadata/metadata.o [ 10c2] cache/parse/parse.cc [ 10d7] -auxbase-strip cache/parse/parse.o [ 10fa] cache/sqlite/sqlite.cc [ 1111] -auxbase-strip cache/sqlite/sqlite.o [ 1136] eixTk/md5.cc [ 1143] -auxbase-strip eixTk/md5.o [ 115e] masked-packages.cc [ 1171] -auxbase-strip masked-packages.o [ 1192] versionsort.cc [ 11a1] -auxbase-strip versionsort.o [ 11be] eix-header.cc [ 11cc] -auxbase-strip eix-header.o [ 11e8] eix-drop-permissions.cc [ 1200] -auxbase-strip eix-drop-permissions.o [ 1226] main/main_all_tools.cc [ 123d] -auxbase-strip main/main_all_tools.o [ 1262] cache/cache_map.cc [ 1275] -auxbase-strip cache/cache_map.o
Is this directly on a i486 box or VirtualBox? VirtualBox might have a bug.
This is on an actual first generation i486DX 40MHz system I use to test for code issues exactly like this case.
It looks like /usr/bin/gdb 10.1 also has this opcode in it: objdump -D /usr/bin/gdb | grep -B6 -A6 endbr32 60d7b5: 3f aas 60d7b6: 1a 3b sbb (%ebx),%bh 60d7b8: 2a 32 sub (%edx),%dh 60d7ba: 24 22 and $0x22,%al 60d7bc: 00 00 add %al,(%eax) 60d7be: 00 00 add %al,(%eax) 60d7c0: f3 0f 1e fb endbr32 60d7c4: ff a3 00 00 00 00 jmp *0x0(%ebx) 60d7ca: 66 0f 1f 44 00 00 nopw 0x0(%eax,%eax,1) 60d7d0: f3 0f 1e fb endbr32 60d7d4: ff 25 00 00 00 00 jmp *0x0 60d7da: 66 0f 1f 44 00 00 nopw 0x0(%eax,%eax,1) 60d7e0: ff b3 04 00 00 00 pushl 0x4(%ebx) 60d7e6: ff a3 08 00 00 00 jmp *0x8(%ebx) 60d7ec: 0f 1f 40 00 nopl 0x0(%eax) 60d7f0: f3 0f 1e fb endbr32 60d7f4: 68 00 00 00 00 push $0x0 60d7f9: e9 00 00 00 00 jmp 60d7fe <_IO_stdin_used@@Base+0xd77fa> 60d7fe: 66 90 xchg %ax,%ax 60d800: ff 35 00 00 00 00 pushl 0x0 60d806: ff 25 00 00 00 00 jmp *0x0 60d80c: 0f 1f 40 00 nopl 0x0(%eax) i686-pentium4-mpentium4-lenovo /usr/lib/debug/usr/bin # /usr/bin/gdb --version GNU gdb (Gentoo 10.1 vanilla) 10.1 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. I will provide the gcc compile switches if asked, but it is long: 2156 items.
I guess to stay compatible with such CPUs one would need to disable CET completely. Pentium II (or whatever is the oldest that supports it): https://stackoverflow.com/questions/56120231/how-do-old-cpus-execute-the-new-endbr64-and-endbr32-instructions treat it as nops, which is the expected behavior on non-CET enabled hw.
It probably makes sense to disable CET by default when GCC is configured to "less" than i686-linux (definitely for i386 and i486, not sure about i586). Thus change the regexps in config/cet.m4 to not include those for =auto at least.
A patch is posted at https://gcc.gnu.org/pipermail/gcc-patches/2021-January/563478.html
(In reply to Richard Biener from comment #6) > It probably makes sense to disable CET by default when GCC is configured to > "less" than i686-linux (definitely for i386 and i486, not sure about i586). > Thus change the regexps in config/cet.m4 to not include those for =auto > at least. config/cet.m4 is OK: ENDBR32 is NOP on SSE2 processors: # Check if target supports multi-byte NOPs # and if compiler and assembler support CET. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [], [ #if !defined(__SSE2__) #error target does not support multi-byte NOPs #else asm ("setssbsy"); #endif ])], [enable_cet=yes], [enable_cet=no]) ;;
The master branch has been updated by H.J. Lu <hjl@gcc.gnu.org>: https://gcc.gnu.org/g:77d372abec0fbf2cfe922e3140ee3410248f979e commit r11-6672-g77d372abec0fbf2cfe922e3140ee3410248f979e Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Jan 14 05:56:46 2021 -0800 x86: Error on -fcf-protection with incompatible target -fcf-protection with CF_BRANCH inserts ENDBR32 at function entries. ENDBR32 is NOP only on 64-bit processors and 32-bit TARGET_CMOV processors. Issue an error for -fcf-protection with CF_BRANCH when compiling for 32-bit non-TARGET_CMOV targets. gcc/ PR target/98667 * config/i386/i386-options.c (ix86_option_override_internal): Issue an error for -fcf-protection with CF_BRANCH when compiling for 32-bit non-TARGET_CMOV targets. gcc/testsuite/ PR target/98667 * gcc.target/i386/pr98667-1.c: New file. * gcc.target/i386/pr98667-2.c: Likewise. * gcc.target/i386/pr98667-3.c: Likewise.
(In reply to Matthew Whitehead from comment #1) > Here is the full set of compiler flags used. > > readelf --string-dump='.GCC.command.line' /usr/lib/debug/$( which eix > ).debug > > String dump of section '.GCC.command.line': > [ 0] -I . > [ 5] -I .. > [ b] -D_GNU_SOURCE > [ 19] -D HAVE_CONFIG_H > [ 2a] -D SYSCONFDIR="/etc" > [ 3f] -D LOCALEDIR="/usr/share/locale" > [ 60] -D _FORTIFY_SOURCE=2 > [ 75] various/drop_permissions.cc > [ 91] -march=i486 > [ 9d] -auxbase-strip various/drop_permissions.o > [ c7] -g > [ ca] -ggdb > [ d0] -O2 > [ d4] -fdata-sections > [ e4] -ffunction-sections > [ f8] -fcf-protection=full > Please remove -fcf-protection=full.
A patch has been proposed to remove the -fcf-protection=full from the ebuild script: https://bugs.gentoo.org/765442
Fixed for GCC 11.
@H.J. Can you please document that one needs at least i686 CPU for the functionality?
(In reply to Martin Liška from comment #13) > @H.J. Can you please document that one needs at least i686 CPU for the > functionality? Like this? diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c66a25fcd69..71992b8c597 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -15542,7 +15542,8 @@ which functions and calls should be skipped from instrumentation (@pxref{Function Attributes}). Currently the x86 GNU/Linux target provides an implementation based -on Intel Control-flow Enforcement Technology (CET). +on Intel Control-flow Enforcement Technology (CET) which works for +i686 processor or newer. @item -fstack-protector @opindex fstack-protector
(In reply to H.J. Lu from comment #14) > (In reply to Martin Liška from comment #13) > > @H.J. Can you please document that one needs at least i686 CPU for the > > functionality? > > Like this? > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index c66a25fcd69..71992b8c597 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -15542,7 +15542,8 @@ which functions and calls should be skipped from > instrumentation > (@pxref{Function Attributes}). > > Currently the x86 GNU/Linux target provides an implementation based > -on Intel Control-flow Enforcement Technology (CET). > +on Intel Control-flow Enforcement Technology (CET) which works for > +i686 processor or newer. > > @item -fstack-protector > @opindex fstack-protector Yes, please.
The master branch has been updated by H.J. Lu <hjl@gcc.gnu.org>: https://gcc.gnu.org/g:1373066a46d8d47abd97e46a005aef3b3dbfe94a commit r12-4619-g1373066a46d8d47abd97e46a005aef3b3dbfe94a Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Oct 21 09:45:14 2021 -0700 x86: Document -fcf-protection requires i686 or newer PR target/98667 * doc/invoke.texi: Document -fcf-protection requires i686 or new.
The releases/gcc-11 branch has been updated by H.J. Lu <hjl@gcc.gnu.org>: https://gcc.gnu.org/g:e74336df42fa36244d576dd155d7e2e2c42bc3a0 commit r11-9179-ge74336df42fa36244d576dd155d7e2e2c42bc3a0 Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Oct 21 09:45:14 2021 -0700 x86: Document -fcf-protection requires i686 or newer PR target/98667 * doc/invoke.texi: Document -fcf-protection requires i686 or new. (cherry picked from commit 1373066a46d8d47abd97e46a005aef3b3dbfe94a)
The releases/gcc-10 branch has been updated by H.J. Lu <hjl@gcc.gnu.org>: https://gcc.gnu.org/g:523dc71f5cb858da18e1f648269746dab519b445 commit r10-10228-g523dc71f5cb858da18e1f648269746dab519b445 Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Oct 21 09:45:14 2021 -0700 x86: Document -fcf-protection requires i686 or newer PR target/98667 * doc/invoke.texi: Document -fcf-protection requires i686 or new. (cherry picked from commit 1373066a46d8d47abd97e46a005aef3b3dbfe94a)
The releases/gcc-9 branch has been updated by H.J. Lu <hjl@gcc.gnu.org>: https://gcc.gnu.org/g:5ed78f8bd84eb696579d928c816bc840664829b2 commit r9-9792-g5ed78f8bd84eb696579d928c816bc840664829b2 Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Oct 21 09:45:14 2021 -0700 x86: Document -fcf-protection requires i686 or newer PR target/98667 * doc/invoke.texi: Document -fcf-protection requires i686 or new. (cherry picked from commit 1373066a46d8d47abd97e46a005aef3b3dbfe94a)