Skip to content

Commit 0d0e841

Browse files
authored
Rollup merge of #133631 - flba-eb:add_nto_qnx71_iosock_support, r=workingjubilee
Support QNX 7.1 with `io-sock`+libstd and QNX 8.0 (`no_std` only) Changes of this pull request: 1. Refactor code for qnx nto targets to share more code in file `nto_qnx.rs` 1. Add support for an additional network stack on nto qnx 7.1. QNX 7.1 supports two network stacks: 1. `io-pkt`, which is default 2. `io-sock`, which is optional on 7.1 but default in QNX 8.0 As one can see in the [io-sock migration notes](https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html), this changes the libc API in a way similar to e.g. linux-gnu vs. linux-musl. This change adds a new target which has a different value for `target_env`, so that e.g. libc can distinguish between both APIs. 2. Add initial support for QNX 8.0, thanks to AkhilTThomas. As it turned out, the problem with forking many processes still exists in QNX 8.0. Because if this, we are now using it for any QNX version (i.e. not check for `target_env` anymore).
2 parents 2f0ad2a + 0462826 commit 0d0e841

17 files changed

+285
-141
lines changed

compiler/rustc_target/src/spec/base/nto_qnx.rs

+96-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::spec::{RelroLevel, TargetOptions, cvs};
1+
use crate::spec::{
2+
Cc, LinkArgs, LinkerFlavor, Lld, RelroLevel, Target, TargetMetadata, TargetOptions, cvs,
3+
};
24

35
pub(crate) fn opts() -> TargetOptions {
46
TargetOptions {
@@ -16,3 +18,96 @@ pub(crate) fn opts() -> TargetOptions {
1618
..Default::default()
1719
}
1820
}
21+
22+
pub(crate) fn meta() -> TargetMetadata {
23+
TargetMetadata { description: None, tier: Some(3), host_tools: Some(false), std: Some(true) }
24+
}
25+
26+
pub(crate) fn aarch64() -> Target {
27+
Target {
28+
llvm_target: "aarch64-unknown-unknown".into(),
29+
metadata: meta(),
30+
pointer_width: 64,
31+
// from: https://llvm.org/docs/LangRef.html#data-layout
32+
// e = little endian
33+
// m:e = ELF mangling: Private symbols get a .L prefix
34+
// i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
35+
// i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
36+
// i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
37+
// i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
38+
// n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
39+
// S128 = 128 bits are the natural alignment of the stack in bits.
40+
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
41+
arch: "aarch64".into(),
42+
options: TargetOptions {
43+
features: "+v8a".into(),
44+
max_atomic_width: Some(128),
45+
..opts()
46+
}
47+
}
48+
}
49+
50+
pub(crate) fn x86_64() -> Target {
51+
Target {
52+
llvm_target: "x86_64-pc-unknown".into(),
53+
metadata: meta(),
54+
pointer_width: 64,
55+
data_layout:
56+
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
57+
arch: "x86_64".into(),
58+
options: TargetOptions {
59+
cpu: "x86-64".into(),
60+
plt_by_default: false,
61+
max_atomic_width: Some(64),
62+
vendor: "pc".into(),
63+
..opts()
64+
},
65+
}
66+
}
67+
68+
pub(crate) fn pre_link_args(api_var: ApiVariant, arch: Arch) -> LinkArgs {
69+
let (qcc_arg, arch_lib_dir) = match arch {
70+
Arch::Aarch64 => ("-Vgcc_ntoaarch64le_cxx", "aarch64le"),
71+
Arch::I586 => {
72+
("-Vgcc_ntox86_cxx", "notSupportedByQnx_compiler/rustc_target/src/spec/base/nto_qnx.rs")
73+
}
74+
Arch::X86_64 => ("-Vgcc_ntox86_64_cxx", "x86_64"),
75+
};
76+
match api_var {
77+
ApiVariant::Default => {
78+
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[qcc_arg])
79+
}
80+
ApiVariant::IoSock => TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
81+
qcc_arg,
82+
get_iosock_param(arch_lib_dir),
83+
]),
84+
}
85+
}
86+
87+
pub(crate) enum ApiVariant {
88+
Default,
89+
IoSock,
90+
}
91+
92+
pub(crate) enum Arch {
93+
Aarch64,
94+
I586,
95+
X86_64,
96+
}
97+
98+
// When using `io-sock` on QNX, we must add a search path for the linker so
99+
// that it prefers the io-sock version.
100+
// The path depends on the host, i.e. we cannot hard-code it here, but have
101+
// to determine it when the compiler runs.
102+
// When using the QNX toolchain, the environment variable QNX_TARGET is always set.
103+
// More information:
104+
// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html
105+
fn get_iosock_param(arch_lib_dir: &str) -> &'static str {
106+
let target_dir = std::env::var("QNX_TARGET")
107+
.unwrap_or_else(|_| "QNX_TARGET_not_set_please_source_qnxsdp-env.sh".into());
108+
let linker_param = format!("-L{target_dir}/{arch_lib_dir}/io-sock/lib");
109+
110+
// FIXME: leaking this is kind of weird: we're feeding these into something that expects an
111+
// `AsRef<OsStr>`, but often converts to `OsString` anyways, so shouldn't we just demand an `OsString`?
112+
linker_param.leak()
113+
}

compiler/rustc_target/src/spec/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1963,7 +1963,11 @@ supported_targets! {
19631963

19641964
("aarch64-unknown-nto-qnx700", aarch64_unknown_nto_qnx700),
19651965
("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710),
1966+
("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock),
1967+
("aarch64-unknown-nto-qnx800", aarch64_unknown_nto_qnx800),
19661968
("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710),
1969+
("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock),
1970+
("x86_64-pc-nto-qnx800", x86_64_pc_nto_qnx800),
19671971
("i586-pc-nto-qnx700", i586_pc_nto_qnx700),
19681972

19691973
("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos),
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,11 @@
1-
use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base};
1+
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
23

34
pub(crate) fn target() -> Target {
4-
// In QNX, libc does not provide a compatible ABI between versions.
5-
// To distinguish between QNX versions, we needed a stable conditional compilation switch,
6-
// which is why we needed to implement different targets in the compiler.
7-
Target {
8-
llvm_target: "aarch64-unknown-unknown".into(),
9-
metadata: crate::spec::TargetMetadata {
10-
description: Some("ARM64 QNX Neutrino 7.0 RTOS".into()),
11-
tier: Some(3),
12-
host_tools: Some(false),
13-
std: Some(true),
14-
},
15-
pointer_width: 64,
16-
// from: https://llvm.org/docs/LangRef.html#data-layout
17-
// e = little endian
18-
// m:e = ELF mangling: Private symbols get a .L prefix
19-
// i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
20-
// i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
21-
// i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
22-
// i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
23-
// n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
24-
// S128 = 128 bits are the natural alignment of the stack in bits.
25-
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
26-
arch: "aarch64".into(),
27-
options: TargetOptions {
28-
features: "+v8a".into(),
29-
max_atomic_width: Some(128),
30-
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
31-
"-Vgcc_ntoaarch64le_cxx",
32-
]),
33-
env: "nto70".into(),
34-
..base::nto_qnx::opts()
35-
},
36-
}
5+
let mut target = nto_qnx::aarch64();
6+
target.metadata.description = Some("ARM64 QNX Neutrino 7.0 RTOS".into());
7+
target.options.pre_link_args =
8+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64);
9+
target.options.env = "nto70".into();
10+
target
3711
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
23

34
pub(crate) fn target() -> Target {
4-
let mut base = super::aarch64_unknown_nto_qnx700::target();
5-
base.metadata.description = Some("ARM64 QNX Neutrino 7.1 RTOS".into());
6-
base.options.env = "nto71".into();
7-
base
5+
let mut target = nto_qnx::aarch64();
6+
target.metadata.description =
7+
Some("ARM64 QNX Neutrino 7.1 RTOS with io-pkt network stack".into());
8+
target.options.pre_link_args =
9+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64);
10+
target.options.env = "nto71".into();
11+
target
812
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
3+
4+
pub(crate) fn target() -> Target {
5+
let mut target = nto_qnx::aarch64();
6+
target.metadata.description =
7+
Some("ARM64 QNX Neutrino 7.1 RTOS with io-sock network stack".into());
8+
target.options.pre_link_args =
9+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::Aarch64);
10+
target.options.env = "nto71_iosock".into();
11+
target
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
3+
4+
pub(crate) fn target() -> Target {
5+
let mut target = nto_qnx::aarch64();
6+
target.metadata.description = Some("ARM64 QNX Neutrino 8.0 RTOS".into());
7+
target.options.pre_link_args =
8+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64);
9+
target.options.env = "nto80".into();
10+
target
11+
}

compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
1+
use crate::spec::base::nto_qnx;
2+
use crate::spec::{StackProbeType, Target, TargetOptions, base};
23

34
pub(crate) fn target() -> Target {
5+
let mut meta = nto_qnx::meta();
6+
meta.description = Some("32-bit x86 QNX Neutrino 7.0 RTOS".into());
7+
meta.std = Some(false);
48
Target {
59
llvm_target: "i586-pc-unknown".into(),
6-
metadata: crate::spec::TargetMetadata {
7-
description: Some("32-bit x86 QNX Neutrino 7.0 RTOS".into()),
8-
tier: Some(3),
9-
host_tools: Some(false),
10-
std: Some(false),
11-
},
10+
metadata: meta,
1211
pointer_width: 32,
1312
data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
1413
i128:128-f64:32:64-f80:32-n8:16:32-S128"
@@ -17,9 +16,10 @@ pub(crate) fn target() -> Target {
1716
options: TargetOptions {
1817
cpu: "pentium4".into(),
1918
max_atomic_width: Some(64),
20-
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
21-
"-Vgcc_ntox86_cxx",
22-
]),
19+
pre_link_args: nto_qnx::pre_link_args(
20+
nto_qnx::ApiVariant::Default,
21+
nto_qnx::Arch::I586,
22+
),
2323
env: "nto70".into(),
2424
vendor: "pc".into(),
2525
stack_probes: StackProbeType::Inline,
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
1-
use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base};
1+
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
23

34
pub(crate) fn target() -> Target {
4-
Target {
5-
llvm_target: "x86_64-pc-unknown".into(),
6-
metadata: crate::spec::TargetMetadata {
7-
description: Some("x86 64-bit QNX Neutrino 7.1 RTOS".into()),
8-
tier: Some(3),
9-
host_tools: Some(false),
10-
std: Some(true),
11-
},
12-
pointer_width: 64,
13-
data_layout:
14-
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
15-
arch: "x86_64".into(),
16-
options: TargetOptions {
17-
cpu: "x86-64".into(),
18-
plt_by_default: false,
19-
max_atomic_width: Some(64),
20-
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
21-
"-Vgcc_ntox86_64_cxx",
22-
]),
23-
env: "nto71".into(),
24-
vendor: "pc".into(),
25-
..base::nto_qnx::opts()
26-
},
27-
}
5+
let mut target = nto_qnx::x86_64();
6+
target.metadata.description =
7+
Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-pkt network stack".into());
8+
target.options.pre_link_args =
9+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64);
10+
target.options.env = "nto71".into();
11+
target
2812
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
3+
4+
pub(crate) fn target() -> Target {
5+
let mut target = nto_qnx::x86_64();
6+
target.metadata.description =
7+
Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-sock network stack".into());
8+
target.options.pre_link_args =
9+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::X86_64);
10+
target.options.env = "nto71_iosock".into();
11+
target
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use crate::spec::Target;
2+
use crate::spec::base::nto_qnx;
3+
4+
pub(crate) fn target() -> Target {
5+
let mut target = nto_qnx::x86_64();
6+
target.metadata.description = Some("x86 64-bit QNX Neutrino 8.0 RTOS".into());
7+
target.options.pre_link_args =
8+
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64);
9+
target.options.env = "nto80".into();
10+
target
11+
}

library/std/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ test = true
139139
level = "warn"
140140
check-cfg = [
141141
'cfg(bootstrap)',
142-
'cfg(target_arch, values("xtensa"))',
142+
'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock", "x86_64-pc-nto-qnx800","aarch64-unknown-nto-qnx800"))',
143+
'cfg(target_env, values("nto71_iosock", "nto80"))',
143144
# std use #[path] imports to portable-simd `std_float` crate
144145
# and to the `backtrace` crate which messes-up with Cargo list
145146
# of declared features, we therefor expect any feature cfg

library/std/src/sys/pal/unix/process/process_unix.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ use crate::sys::process::process_common::*;
1919
use crate::{fmt, mem, sys};
2020

2121
cfg_if::cfg_if! {
22-
// This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0
23-
if #[cfg(any(target_env = "nto70", target_env = "nto71"))] {
22+
if #[cfg(target_os = "nto")] {
2423
use crate::thread;
2524
use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t};
2625
use crate::time::Duration;
@@ -187,12 +186,7 @@ impl Command {
187186

188187
// Attempts to fork the process. If successful, returns Ok((0, -1))
189188
// in the child, and Ok((child_pid, -1)) in the parent.
190-
#[cfg(not(any(
191-
target_os = "watchos",
192-
target_os = "tvos",
193-
target_env = "nto70",
194-
target_env = "nto71"
195-
)))]
189+
#[cfg(not(any(target_os = "watchos", target_os = "tvos", target_os = "nto")))]
196190
unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
197191
cvt(libc::fork())
198192
}
@@ -201,8 +195,7 @@ impl Command {
201195
// or closed a file descriptor while the fork() was occurring".
202196
// Documentation says "... or try calling fork() again". This is what we do here.
203197
// See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
204-
// This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0
205-
#[cfg(any(target_env = "nto70", target_env = "nto71"))]
198+
#[cfg(target_os = "nto")]
206199
unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
207200
use crate::sys::os::errno;
208201

src/bootstrap/src/core/sanity.rs

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ pub struct Finder {
3434
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
3535
const STAGE0_MISSING_TARGETS: &[&str] = &[
3636
// just a dummy comment so the list doesn't get onelined
37+
"aarch64-unknown-nto-qnx710_iosock",
38+
"x86_64-pc-nto-qnx710_iosock",
39+
"x86_64-pc-nto-qnx800",
40+
"aarch64-unknown-nto-qnx800",
3741
];
3842

3943
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM

src/doc/rustc/src/platform-support.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,9 @@ target | std | host | notes
259259
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
260260
[`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD
261261
[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS |
262-
[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS |
262+
[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
263+
[`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
264+
[`aarch64-unknown-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 8.0 RTOS |
263265
[`aarch64-unknown-nuttx`](platform-support/nuttx.md) | * | | ARM64 with NuttX
264266
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
265267
[`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS
@@ -404,7 +406,9 @@ target | std | host | notes
404406
[`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly
405407
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
406408
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
407-
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS |
409+
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
410+
[`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) |
411+
[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS |
408412
[`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3
409413
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
410414
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku

0 commit comments

Comments
 (0)