Bug 27397 - CET autodetection fails configure on i486 and i586 targets
Summary: CET autodetection fails configure on i486 and i586 targets
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.36
: P2 normal
Target Milestone: 2.37
Assignee: H.J. Lu
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-02-11 20:33 UTC by Sergei Trofimovich
Modified: 2022-06-22 06:31 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2021-02-11 00:00:00


Attachments
A patch (590 bytes, patch)
2021-02-11 21:13 UTC, H.J. Lu
Details | Diff
binutils-gdb-fix-cet.patch (338 bytes, patch)
2021-02-12 10:58 UTC, Sergei Trofimovich
Details | Diff
An updated patch (605 bytes, patch)
2021-02-12 14:14 UTC, H.J. Lu
Details | Diff
A patch with run-time check for multi-byte NOPs (1.00 KB, patch)
2021-02-13 00:31 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2021-02-11 20:33:52 UTC
This is a forward of downstream bugs:
    https://bugs.gentoo.org/760926
    https://bugs.gentoo.org/770061

https://bugs.gentoo.org/760926 is slightly more detailed. There user uses j6-3 machine (almst, but not quite i686). As a result configure detect CET support by assembler but test crashes at runtime failing ./configure:

```
configure:5391: i486-pc-linux-gnu-gcc -o conftest -pipe -O2 -march=k6-3 -m3dnow -mmmx -fomit-frame-pointer -ftree-vectorize -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 --param l1-cache-size=32 --param l1-cache-line-size=32 --param l2-cache-size=256 -mtune=k6 -fcf-protection=none   -Wl,-O1 -Wl,--as-needed -Wl,-z,ibt,-z,shstk conftest.c  >&5
configure:5391: $? = 0
configure:5391: ./conftest

/var/tmp/portage/sys-devel/gdb-10.1/work/gdb-10.1/libiberty/configure: line 1624:   853 Illegal instruction     ./conftest$ac_exeext
configure:5391: $? = 132
configure: program exited with status 132

configure:5401: error: Intel CET must be enabled on Intel CET enabled host
```

Looks like the only way to get binutils and gdb on old machines is to pass --disable-cet explicitly to ./configure. Is it an intended behaviour?

Gentoo packages binutils-gdb in a few flavours:
- binutils
- gdb
- binutils-libs
- binutils-hppa64
and we need to duplicate the --disable-cet everywhere.

I ended up disabling CET for all architectures including x86_64 out of laziness. Would be nice if ./configure picked a better default.

I suggest tweaking upstream configure to silently disable the features instead of failing configure at least on non-x86_64 to make packaging slightly smoother.

WDYT?
Comment 1 H.J. Lu 2021-02-11 21:13:07 UTC
Created attachment 13218 [details]
A patch

Please try this.
Comment 2 Sergei Trofimovich 2021-02-12 07:58:22 UTC
(In reply to H.J. Lu from comment #1)
> Created attachment 13218 [details]
> A patch
> 
> Please try this.

Asked user to try in https://bugs.gentoo.org/770061#c16, failed in a simialr way. I'll debug with user a bit more to better understand the problem and come back.
Comment 3 Sergei Trofimovich 2021-02-12 10:58:44 UTC
Created attachment 13219 [details]
binutils-gdb-fix-cet.patch

We debugged it in https://bugs.gentoo.org/attachment.cgi?id=686394 a bit more and managed to work around the failure with: binutils-gdb-fix-cet.patch

But it's not a correct patch.

Revised explanation of failure mode:

1. toolchain does not support sse2 (good, intended)
2. That leads to enable_cet=no autodetection (good, intended)
3. Then '# Check whether -fcf-protection=none -Wl,-z,ibt,-z,shstk work.' test is ran. 'endbr' instructions are injected (via PLT stubs for shstk?).
4 That makes the test fail with SIGILL when ran on pre-SSE CPUs.
5. have_cet=yes is raised (UNINTENDED). O think 'have_cet=' is shightly misleading. I suggest renaming it to 'requires_cet='.
6 ./configure fails with:

    if test x$enable_cet = xno -a x$have_cet = xyes; then
      AC_MSG_ERROR([Intel CET must be enabled on Intel CET enabled host])
    fi

Another possibility is to turn have_cet=yes to a positive test: if CET can run successfully then enable it (attached patch tries to do it, but incorrectly) (or if disabled CET makes minimal binaries crash?).

But it requires more work as './configure --disable-cet' fails with it.

Or slightly change your patch to do similar disabling on AC_TRY_RUN side instead.
Comment 4 H.J. Lu 2021-02-12 14:13:58 UTC
(In reply to Sergei Trofimovich from comment #3)
> Created attachment 13219 [details]
> binutils-gdb-fix-cet.patch

This patch is wrong.
Comment 5 H.J. Lu 2021-02-12 14:14:29 UTC
Created attachment 13220 [details]
An updated patch

Try this.
Comment 6 Sergei Trofimovich 2021-02-12 18:15:02 UTC
(In reply to H.J. Lu from comment #5)
> Created attachment 13220 [details]
> An updated patch
> 
> Try this.

The user reports it's building fine for them on i486: https://bugs.gentoo.org/770061#c26

AFAIU event with the patch ./configure --host=i686-pc-linux-gnu if ran on pre-sse2 CPU, right?
Comment 7 H.J. Lu 2021-02-12 19:02:04 UTC
(In reply to Sergei Trofimovich from comment #6)
> (In reply to H.J. Lu from comment #5)
> > Created attachment 13220 [details]
> > An updated patch
> > 
> > Try this.
> 
> The user reports it's building fine for them on i486:
> https://bugs.gentoo.org/770061#c26
> 
> AFAIU event with the patch ./configure --host=i686-pc-linux-gnu if ran on
> pre-sse2 CPU, right?

SSE2 isn't the issue.  The multi-byte NOP is the issue.
Comment 8 Sergei Trofimovich 2021-02-12 20:55:24 UTC
(In reply to H.J. Lu from comment #7)
> (In reply to Sergei Trofimovich from comment #6)
> > (In reply to H.J. Lu from comment #5)
> > > Created attachment 13220 [details]
> > > An updated patch
> > > 
> > > Try this.
> > 
> > The user reports it's building fine for them on i486:
> > https://bugs.gentoo.org/770061#c26
> > 
> > AFAIU event with the patch ./configure --host=i686-pc-linux-gnu if ran on
> > pre-sse2 CPU, right?
> 
> SSE2 isn't the issue.  The multi-byte NOP is the issue.

Oh, I thought these multibyte NOP come from SSE2 encoding. I'd like to understand why then these NOPs crash the program with SIGILL.

Looking at endbr32 instruction as an example: "F3 0F 1E FB".

Do I understand correctly it's supposed to be decoded by old CPUs as:
    prefix=F3 (REP) escape="0F 1E" (Reserved-NOP) modrm(?)=FB

Do you know when these 'Reserved-NOP' were introduced as valid instruction to IA-32? I wonder why K6-III can't handle it: is it a CPU bug (imprecise implementation of reserved NOPs) or it was introduced later.
Comment 9 H.J. Lu 2021-02-12 21:27:53 UTC
(In reply to Sergei Trofimovich from comment #8)

> 
> Do I understand correctly it's supposed to be decoded by old CPUs as:
>     prefix=F3 (REP) escape="0F 1E" (Reserved-NOP) modrm(?)=FB
> 
> Do you know when these 'Reserved-NOP' were introduced as valid instruction
> to IA-32? I wonder why K6-III can't handle it: is it a CPU bug (imprecise
> implementation of reserved NOPs) or it was introduced later.

Pentium Pro supports multi-byte NOP.  A run-time test can be added.
Comment 10 H.J. Lu 2021-02-13 00:31:40 UTC
Created attachment 13222 [details]
A patch with run-time check for multi-byte NOPs

Try this.
Comment 11 Sergei Trofimovich 2021-02-14 16:44:00 UTC
(In reply to H.J. Lu from comment #10)
> Created attachment 13222 [details]
> A patch with run-time check for multi-byte NOPs
> 
> Try this.

User reported that it works as well: https://bugs.gentoo.org/770061#c29

Thank you!
Comment 12 Sourceware Commits 2021-03-18 15:03:11 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=538c15fc2a29ff142f2ec71d253d4027946ece09

commit 538c15fc2a29ff142f2ec71d253d4027946ece09
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Mar 18 07:54:15 2021 -0700

    GCC_CET_HOST_FLAGS: Check if host supports multi-byte NOPs
    
    Check if host supports multi-byte NOPs before enabling CET on host.
    
    config/
    
            PR binutils/27397
            * cet.m4 (GCC_CET_HOST_FLAGS): Check if host supports multi-byte
            NOPs.
    
    libiberty/
    
            PR binutils/27397
            * configure: Regenerated.
Comment 13 H.J. Lu 2021-03-18 15:03:46 UTC
Fixed on master branch so far.
Comment 14 H.J. Lu 2021-03-22 18:37:24 UTC
It could be a dup of

https://sourceware.org/bugzilla/show_bug.cgi?id=27397
Comment 15 H.J. Lu 2022-01-18 14:25:38 UTC
Fixed for 2.37.