From 72b664286d5d30c40b93b265740112d49c7d35f9 Mon Sep 17 00:00:00 2001
From: Florian Bartels <Florian.Bartels@elektrobit.com>
Date: Fri, 29 Nov 2024 18:15:05 +0100
Subject: [PATCH] Add support for QNX 7.1 with io-sock on x64

---
 compiler/rustc_target/src/spec/mod.rs         |  1 +
 .../targets/x86_64_pc_nto_qnx710_iosock.rs    | 25 +++++++++++++++++++
 library/std/Cargo.toml                        |  2 +-
 src/bootstrap/src/core/sanity.rs              |  1 +
 src/doc/rustc/src/platform-support.md         |  3 ++-
 src/doc/rustc/src/platform-support/nto-qnx.md | 11 ++++----
 tests/assembly/targets/targets-elf.rs         |  3 +++
 7 files changed, 39 insertions(+), 7 deletions(-)
 create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs

diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index e73b086f82c22..44118b7253d67 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1928,6 +1928,7 @@ supported_targets! {
     ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710),
     ("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock),
     ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710),
+    ("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock),
     ("i586-pc-nto-qnx700", i586_pc_nto_qnx700),
 
     ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs
new file mode 100644
index 0000000000000..da2f45a853386
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs
@@ -0,0 +1,25 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    let mut target = super::x86_64_pc_nto_qnx710::target();
+    target.options.env = "nto71_iosock".into();
+    target.options.pre_link_args = TargetOptions::link_args(
+        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        &["-Vgcc_ntox86_64_cxx", get_iosock_param()],
+    );
+    target
+}
+
+// When using `io-sock` on QNX, we must add a search path for the linker so
+// that it prefers the io-sock version.
+// The path depends on the host, i.e. we cannot hard-code it here, but have
+// to determine it when the compiler runs.
+// When using the QNX toolchain, the environment variable QNX_TARGET is always set.
+// More information:
+// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html
+fn get_iosock_param() -> &'static str {
+    let target_dir = std::env::var("QNX_TARGET").expect("Environment variable QNX_TARGET is set");
+    let linker_param = format!("-L{target_dir}/x86_64/io-sock/lib");
+
+    linker_param.leak()
+}
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 35624cec8f54a..305134ded2093 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -139,7 +139,7 @@ test = true
 level = "warn"
 check-cfg = [
     'cfg(bootstrap)',
-    'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock"))',
+    'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock"))',
     'cfg(target_env, values("nto71_iosock"))',
     # std use #[path] imports to portable-simd `std_float` crate
     # and to the `backtrace` crate which messes-up with Cargo list
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index fdcbc5be8a0e5..3d775714f3d35 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -35,6 +35,7 @@ pub struct Finder {
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
     "aarch64-unknown-nto-qnx710_iosock",
+    "x86_64-pc-nto-qnx710_iosock",
 ];
 
 /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 25481c261fc39..8b22566c1ecb5 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -381,7 +381,8 @@ target | std | host | notes
 [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? |  | WebAssembly
 [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ |  | x86 64-bit tvOS
 [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ |  | x86 64-bit Apple WatchOS simulator
-[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ |  | x86 64-bit QNX Neutrino 7.1 RTOS |
+[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ |  | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
+[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ |  | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
 [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ |   | 64-bit Unikraft with musl 1.2.3
 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
 `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
index e49d08b579c52..c444df3788117 100644
--- a/src/doc/rustc/src/platform-support/nto-qnx.md
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -22,11 +22,12 @@ Currently, the following QNX Neutrino versions and compilation targets are suppo
 
 | QNX Neutrino Version | Target Architecture | Full support | `no_std` support |
 |----------------------|---------------------|:------------:|:----------------:|
-| 7.1 with io-pkt | AArch64 | ✓ | ✓ |
-| 7.1 with io-sock | AArch64 | ✓ | ✓ |
-| 7.1 | x86_64  | ✓ | ✓ |
-| 7.0 | AArch64 | ? | ✓ |
-| 7.0 | x86     |   | ✓ |
+| 7.1 with io-pkt  | AArch64  | ✓ | ✓ |
+| 7.1 with io-sock | AArch64  | ? | ✓ |
+| 7.1 with io-pkt  | x86_64   | ✓ | ✓ |
+| 7.1 with io-sock | x86_64   | ? | ✓ |
+| 7.0 | AArch64               | ? | ✓ |
+| 7.0 | x86                   |   | ✓ |
 
 On QNX 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX 7.1 includes
 the optional network stack `io-sock`.
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index d14df425f6685..02428d10b6a5f 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -549,6 +549,9 @@
 //@ revisions: x86_64_pc_nto_qnx710
 //@ [x86_64_pc_nto_qnx710] compile-flags: --target x86_64-pc-nto-qnx710
 //@ [x86_64_pc_nto_qnx710] needs-llvm-components: x86
+//@ revisions: x86_64_pc_nto_qnx710_iosock
+//@ [x86_64_pc_nto_qnx710_iosock] compile-flags: --target x86_64-pc-nto-qnx710_iosock
+//@ [x86_64_pc_nto_qnx710_iosock] needs-llvm-components: x86
 //@ revisions: x86_64_pc_solaris
 //@ [x86_64_pc_solaris] compile-flags: --target x86_64-pc-solaris
 //@ [x86_64_pc_solaris] needs-llvm-components: x86