RustCrypto / RustCrypto/universal-hashes

SIGILL / LLVM ERROR from rustc when compiling to a x86_64 target that lacks SSE2 instructions

Open
#189 16 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
39
Forks
23
Avg merge
1h 57m
Merged PRs (30d)
2

Description

Steps to reproduce

$ cargo new --lib repro
$ cd repro

$ echo '#![no_std]' > src/lib.rs
$ cargo add poly1305@0.8.0

$ rustup default 1.73.0
$ rustup target add x86_64-unknown-none
$ cargo b --target x86_64-unknown-none
error: could not compile `poly1305` (lib)

Caused by:
  process didn't exit successfully: `$RUSTUP_TOOLCHAIN/bin/rustc (..)` (signal: 4, SIGILL: illegal instruction)

at some point I was able to get a "LLVM ERROR" message but I can't no longer reproduce that


after some digging it seems that the lack of SSE2 instructions in the x86_64-unknown-none is the problem:

$ rustup default nightly-2023-11-15
$ rustc -Z unstable-options --print target-spec-json --target x86_64-unknown-none | grep features
  "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",

creating a custom target that adds back the sse2 feature makes the crate compile

$ rustc -Z unstable-options --print target-spec-json --target x86_64-unknown-none > x86_64.json

patch the JSON like this

--- before.json	2023-11-15 14:35:19.565448966 +0100
+++ x86_64.json	2023-11-15 14:35:10.115355396 +0100
@@ -5,8 +5,7 @@
   "crt-objects-fallback": "false",
   "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
   "disable-redzone": true,
-  "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
-  "is-builtin": true,
+  "features": "-mmx,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2",
   "linker": "rust-lld",
   "linker-flavor": "gnu-lld",
   "llvm-target": "x86_64-unknown-none-elf",
$ rustup component add rust-src
$ cargo b -j1 -Z build-std=core --target ./x86_64.json && echo OK
OK

keeping the -sse2 produces "LLVM ERROR: Access past stack top!"

perhaps the auto_detect module could use #[cfg(not(target_feature = "sse2"))] to skip the auto-detection and directly use the soft implementation? or you could add something like this:

#[cfg(not(target_feature = "sse2"))]
compile_error!("compilation targets without SSE2 instructions are not supported");

which is nicer than the SIGILL


for additional context ("why are you even using this target?"): I was looking for a built-in "OS agnostic" / no-std target for a no-std rustls demo (rustls/rustls PR1534) and tried x86_64-unknown-none and run into this and other problems. I ended up using a custom target for the demo but I figured I should still report what I found.

by the way, the sha2 has a similar problem with this target. Let me know if you think I should report a similar issue in the hashes repo.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with poly1305 0.8.0 on rustc 1.73.0 using the x86_64-unknown-none target and inspect the target features shown by rustc. Start with the auto_detect module and the existing soft implementation. Done should be a clear, tested behavior for targets without SSE2, whether that is selecting the soft implementation or reporting that the target is unsupported.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system, cryptography
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.