diff --git a/0002-Set-proper-llvm-targets.patch b/0001-Set-proper-llvm-targets.patch
similarity index 65%
rename from 0002-Set-proper-llvm-targets.patch
rename to 0001-Set-proper-llvm-targets.patch
index b452812..d3ad25f 100644
--- a/0002-Set-proper-llvm-targets.patch
+++ b/0001-Set-proper-llvm-targets.patch
@@ -1,26 +1,24 @@
-From 72aaa3d28daa1b187059ef148c45bd9f186b430d Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Matti Kosola <matti.kosola@jolla.com>
 Date: Thu, 9 Jul 2020 11:22:10 +0000
-Subject: [PATCH 2/4] Set proper llvm targets.
+Subject: [PATCH] Set proper llvm targets.
 
 Signed-off-by: Matti Kosola <matti.kosola@jolla.com>
+Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
 ---
  config.toml.example | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/config.toml.example b/config.toml.example
-index 9121d1e1799..7990f01ab42 100644
+index 6e53d9b442f1609ec929f1c021984391d038e879..02b3a376409f5e523921aca8c89c2922c950aab3 100644
 --- a/config.toml.example
 +++ b/config.toml.example
-@@ -63,7 +63,7 @@
+@@ -103,7 +103,7 @@ changelog-seen = 2
  # support. You'll need to write a target specification at least, and most
  # likely, teach rustc about the C ABI of the target. Get in touch with the
  # Rust team and file an issue if you need assistance in porting!
--#targets = "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
+-#targets = "AArch64;ARM;BPF;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
 +targets = "X86;ARM;AArch64"
  
  # LLVM experimental targets to build support for. These targets are specified in
  # the same format as above, but since these targets are experimental, they are
--- 
-2.20.1
-
diff --git a/0003-Disable-statx-for-all-builds.-JB-50106.patch b/0002-Disable-statx-for-all-builds.-JB-50106.patch
similarity index 58%
rename from 0003-Disable-statx-for-all-builds.-JB-50106.patch
rename to 0002-Disable-statx-for-all-builds.-JB-50106.patch
index f8ae6c5..cd242fb 100644
--- a/0003-Disable-statx-for-all-builds.-JB-50106.patch
+++ b/0002-Disable-statx-for-all-builds.-JB-50106.patch
@@ -1,4 +1,4 @@
-From 0ea195274d580ada6af1f9687647564d9a06ecd5 Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Niels Breet <niels.breet@jolla.com>
 Date: Tue, 11 May 2021 13:03:55 +0300
 Subject: [PATCH] Disable statx for all builds. JB#50106
@@ -14,15 +14,40 @@ that gracefully without issues thanks to rust's type system.
 
 Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com
 Signed-off-by: Matti Kosola <matti.kosola@jolla.com>
+Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
 ---
- library/std/src/sys/unix/fs.rs | 15 ++-------------
- 1 file changed, 2 insertions(+), 13 deletions(-)
+ library/std/src/sys/unix/fs.rs | 27 ++-------------------------
+ 1 file changed, 2 insertions(+), 25 deletions(-)
 
 diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
-index d1b0ad9..f5ddc9b 100644
+index 7181451de575fcb8ff7df27ba5a66b18a08904be..141e1726db49f1ac483a5788bdbc31388a1c942e 100644
 --- a/library/std/src/sys/unix/fs.rs
 +++ b/library/std/src/sys/unix/fs.rs
-@@ -58,20 +58,9 @@ pub struct File(FileDesc);
+@@ -13,23 +13,11 @@
+ use crate::sys::{cvt, cvt_r};
+ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
+ 
+-#[cfg(any(
+-    all(target_os = "linux", target_env = "gnu"),
+-    target_os = "macos",
+-    target_os = "ios",
+-))]
+-use crate::sys::weak::syscall;
+ #[cfg(target_os = "macos")]
+ use crate::sys::weak::weak;
+ 
+ use libc::{c_int, mode_t};
+ 
+-#[cfg(any(
+-    target_os = "macos",
+-    target_os = "ios",
+-    all(target_os = "linux", target_env = "gnu")
+-))]
+-use libc::c_char;
+ #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
+ use libc::dirfd;
+ #[cfg(any(target_os = "linux", target_os = "emscripten"))]
+@@ -85,20 +73,9 @@
  // https://github.com/rust-lang/rust/pull/67774
  macro_rules! cfg_has_statx {
      ({ $($then_tt:tt)* } else { $($else_tt:tt)* }) => {
@@ -45,6 +70,3 @@ index d1b0ad9..f5ddc9b 100644
  }
  
  cfg_has_statx! {{
--- 
-1.9.1
-
diff --git a/0004-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch b/0003-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
similarity index 82%
rename from 0004-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
rename to 0003-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
index 4a82264..5078eb5 100644
--- a/0004-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
+++ b/0003-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
@@ -1,4 +1,4 @@
-From ac226bbc018e11311394126fe580763c5bc77a2c Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Niels Breet <niels.breet@jolla.com>
 Date: Tue, 11 May 2021 13:10:49 +0300
 Subject: [PATCH] Scratchbox2 needs to be able to tell rustc the default
@@ -9,15 +9,16 @@ hardcode this for a cross-compiler, using an environment variable
 allows the same rustc binary to be used for all builds.
 
 Signed-off-by: David Greaves <david.greaves@jolla.com>
+Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
 ---
  compiler/rustc_session/src/config.rs | 9 ++++++++-
  1 file changed, 8 insertions(+), 1 deletion(-)
 
 diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
-index 85448b7..ec51c50 100644
+index 4182a5d07118e0652ff63c4bec28bde0775d0c59..9904ab2e70d7aafab4ec63e86d0cdb383ca2285b 100644
 --- a/compiler/rustc_session/src/config.rs
 +++ b/compiler/rustc_session/src/config.rs
-@@ -1537,7 +1537,14 @@ fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType
+@@ -1848,7 +1848,14 @@ pub fn parse_target_triple(
              })
          }
          Some(target) => TargetTriple::TargetTriple(target),
@@ -33,6 +34,3 @@ index 85448b7..ec51c50 100644
      }
  }
  
--- 
-1.9.1
-
diff --git a/0005-Cargo-Force-the-target-when-building-for-CompileKind-Host.patch b/0004-Force-the-target-when-building-for-CompileKind-Host.patch
similarity index 68%
rename from 0005-Cargo-Force-the-target-when-building-for-CompileKind-Host.patch
rename to 0004-Force-the-target-when-building-for-CompileKind-Host.patch
index beba5b6..b0f395a 100644
--- a/0005-Cargo-Force-the-target-when-building-for-CompileKind-Host.patch
+++ b/0004-Force-the-target-when-building-for-CompileKind-Host.patch
@@ -1,4 +1,4 @@
-From f58f4a0fb53df2b1b27c11986596c62de803afdf Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: David Greaves <david.greaves@jolla.com>
 Date: Mon, 30 Nov 2020 13:07:39 +0000
 Subject: [PATCH] Force the target when building for CompileKind::Host
@@ -6,24 +6,21 @@ Subject: [PATCH] Force the target when building for CompileKind::Host
 Currently hardwired to be i686-unknown-linux-gnu
 
 Signed-off-by: David Greaves <david.greaves@jolla.com>
+Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
 ---
- src/tools/cargo/src/cargo/core/compiler/mod.rs | 3 +++
- 1 file changed, 3 insertions(+)
+ src/tools/cargo | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/tools/cargo/src/cargo/core/compiler/mod.rs b/src/tools/cargo/src/cargo/core/compiler/mod.rs
-index faee6e5..4af3f29 100644
 --- a/src/tools/cargo/src/cargo/core/compiler/mod.rs
 +++ b/src/tools/cargo/src/cargo/core/compiler/mod.rs
-@@ -912,6 +912,9 @@ fn build_base_args<'a, 'cfg>(
- 
+@@ -989,6 +989,9 @@ fn build_base_args(
+
      if let CompileKind::Target(n) = unit.kind {
          cmd.arg("--target").arg(n.rustc_target());
 +    } else {
-+	debug!("kind is {:?} - Forcing this to be 686", unit.kind);
++        debug!("kind is {:?} - Forcing this to be 686", unit.kind);
 +        cmd.arg("--target").arg("i686-unknown-linux-gnu");
      }
- 
-     opt(
--- 
-2.20.1
 
+     opt(
diff --git a/0005-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch b/0005-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch
new file mode 100644
index 0000000..540069a
--- /dev/null
+++ b/0005-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch
@@ -0,0 +1,374 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: David Greaves <david.greaves@jolla.com>
+Date: Wed, 20 Jan 2021 09:40:34 +0000
+Subject: [PATCH] Provide ENV controls to bypass some sb2 calls between fork
+ exec
+
+In threaded systems there can be deadlocks caused by calling malloc
+after fork and before exec. Rust manages this but sb2 does not.
+
+The following ENV variables are available:
+
+SB2_RUST_EXECVP_SHIM
+
+This executable is passed to the execvp call. The intended executable
+is passed in the argv[] list. Typically set to "/usr/bin/env --". Used
+wth SB2_RUST_USE_REAL_EXECVP which will not do path processing to exec
+this binary but the binary will then exec the command provided via sb2
+lookups.
+
+SB2_RUST_USE_REAL_EXECVP
+When set will cause the libc execvp() to be called and not the sb2
+gate
+
+SB2_RUST_USE_REAL_FN
+This ensures that no sb2 calls to gates for dup2/chdir etc are made
+between fork and exec
+
+SB2_RUST_NO_SPAWNVP
+When set the rust libc::spawnvp() call (which is gated) is bypassed
+and the fallback fork/exec is used.
+
+Note that some reworking of rust's handling of program/argv[0] was
+needed to support the SHIM functionality
+
+Signed-off-by: David Greaves <david.greaves@jolla.com>
+Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
+---
+ .../src/sys/unix/process/process_common.rs    |  50 ++++++-
+ .../std/src/sys/unix/process/process_unix.rs  | 138 ++++++++++++++++--
+ 2 files changed, 170 insertions(+), 18 deletions(-)
+
+diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
+index 27bee714f5b4317132db508fe916c7e194d05bc5..7746177e0423b7689833cc84b6132240a8bb2bf0 100644
+--- a/library/std/src/sys/unix/process/process_common.rs
++++ b/library/std/src/sys/unix/process/process_common.rs
+@@ -61,7 +61,7 @@ pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::
+ ////////////////////////////////////////////////////////////////////////////////
+ 
+ pub struct Command {
+-    program: CString,
++    pub(crate) program: CString,
+     args: Vec<CString>,
+     /// Exactly what will be passed to `execvp`.
+     ///
+@@ -70,6 +70,13 @@ pub struct Command {
+     /// `args` to properly update this as well.
+     argv: Argv,
+     env: CommandEnv,
++    pub(crate) execvp: Option<ExecvpFn>,
++    pub(crate) dup2: Option<Dup2Fn>,
++    pub(crate) close: Option<CloseFn>,
++    pub(crate) chdir: Option<ChdirFn>,
++    pub(crate) setuid: Option<SetuidFn>,
++    pub(crate) setgid: Option<SetgidFn>,
++    pub(crate) setgroups: Option<SetgroupsFn>,
+ 
+     cwd: Option<CString>,
+     uid: Option<uid_t>,
+@@ -85,6 +92,14 @@ pub struct Command {
+     pgroup: Option<pid_t>,
+ }
+ 
++pub(crate) type ExecvpFn = fn(*const c_char, *const *const c_char) -> c_int;
++pub(crate) type Dup2Fn = fn(c_int, c_int) -> c_int;
++pub(crate) type CloseFn = fn(c_int) -> c_int;
++pub(crate) type ChdirFn = fn(*const c_char) -> c_int;
++pub(crate) type SetuidFn = fn(uid_t) -> c_int;
++pub(crate) type SetgidFn = fn(gid_t) -> c_int;
++pub(crate) type SetgroupsFn = fn(libc::size_t, *const gid_t) -> c_int;
++
+ // Create a new type for argv, so that we can make it `Send` and `Sync`
+ struct Argv(Vec<*const c_char>);
+ 
+@@ -132,15 +147,23 @@ impl Command {
+     pub fn new(program: &OsStr) -> Command {
+         let mut saw_nul = false;
+         let program = os2c(program, &mut saw_nul);
++        let arg0 = program.clone();
+         Command {
+-            argv: Argv(vec![program.as_ptr(), ptr::null()]),
+-            args: vec![program.clone()],
+-            program,
++            argv: Argv(vec![arg0.as_ptr(), ptr::null()]),
++            args: vec![arg0],
++            program: program,
+             env: Default::default(),
++            execvp: None,
++            dup2: None,
++            close: None,
++            chdir: None,
++            setuid: None,
++            setgid: None,
++            setgroups: None,
+             cwd: None,
+             uid: None,
+             gid: None,
+-            saw_nul,
++            saw_nul: saw_nul,
+             closures: Vec::new(),
+             groups: None,
+             stdin: None,
+@@ -159,6 +182,13 @@ pub fn new(program: &OsStr) -> Command {
+             args: vec![program.clone()],
+             program,
+             env: Default::default(),
++            execvp: None,
++            dup2: None,
++            close: None,
++            chdir: None,
++            setuid: None,
++            setgid: None,
++            setgroups: None,
+             cwd: None,
+             uid: None,
+             gid: None,
+@@ -173,6 +203,16 @@ pub fn new(program: &OsStr) -> Command {
+         }
+     }
+ 
++    // This allows process_unix::{spawn, exec} to push program to the
++    // start of /usr/bin/env's arg list
++    pub fn insert_program(&mut self, arg: String) {
++        let arg = OsString::from(arg);
++        let arg = os2c(&arg, &mut self.saw_nul);
++        self.program = arg.clone();
++        self.argv.0.insert(0, arg.as_ptr());
++        self.args.insert(0, arg);
++    }
++
+     pub fn set_arg_0(&mut self, arg: &OsStr) {
+         // Set a new arg0
+         let arg = os2c(arg, &mut self.saw_nul);
+diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
+index 3d305cd7310fd4b8419d220d1adeadebb9fda914..5d1c667b943cb2af0e0e918c17a7b24293617376 100644
+--- a/library/std/src/sys/unix/process/process_unix.rs
++++ b/library/std/src/sys/unix/process/process_unix.rs
+@@ -27,11 +27,15 @@
+ use libc::RTP_ID as pid_t;
+ 
+ #[cfg(not(target_os = "vxworks"))]
+-use libc::{c_int, pid_t};
++use libc::{c_char, c_int, dlsym, pid_t};
+ 
+ #[cfg(not(any(target_os = "vxworks", target_os = "l4re")))]
+ use libc::{gid_t, uid_t};
+ 
++use crate::ffi::OsString;
++use crate::intrinsics::transmute;
++use sys::os::getenv;
++
+ ////////////////////////////////////////////////////////////////////////////////
+ // Command
+ ////////////////////////////////////////////////////////////////////////////////
+@@ -61,6 +65,65 @@ pub fn spawn(
+ 
+         let (input, output) = sys::pipe::anon_pipe()?;
+ 
++        // If there is a RUST_EXEC_SHIM (could be "/usr/bin/env --")
++        // then we're probably going to directly execvp it via dlsym
++        // to avoid issues with threads and malloc post-fork and
++        // pre-exec. That will then re-execvp but this time sb2 will
++        // do magic. See also RUST_EXECVP_REAL
++
++        // We do this here and pass so do_exec() so any malloc's are
++        // pre-fork()
++
++        // At this point self.program is the real program. argv[0] is
++        // now a clone() of program.
++
++        let libc_h =
++            unsafe { libc::dlopen("libc.so.6\0".as_ptr() as *const c_char, libc::RTLD_LAZY) };
++
++        match getenv(&OsString::from("SB2_RUST_EXECVP_SHIM")) {
++            Some(var) => {
++                // handle "/usr/bin/env <arg> <arg>"
++                let var = var.into_string().expect("Valid string"); // so we can .split()
++                let words: Vec<&str> = var.as_str().split(" ").collect();
++                for w in words.iter().rev() {
++                    self.insert_program(w.to_string());
++                }
++                // At this point self.program is the SHIM. argv[0] is
++                // the SHIM and argv[>0] is the real program.
++            }
++            None => {} // Business as usual
++        };
++        match getenv(&OsString::from("SB2_RUST_USE_REAL_EXECVP")) {
++            Some(_var) => unsafe {
++                let real_execvp_p =
++                    dlsym(libc_h, "execvp\0".as_ptr() as *const c_char) as *const ();
++                self.execvp = Some(transmute::<*const (), ExecvpFn>(real_execvp_p));
++            },
++            None => {}
++        };
++        match getenv(&OsString::from("SB2_RUST_USE_REAL_FN")) {
++            Some(_var) => unsafe {
++                let real_dup2_p = dlsym(libc_h, "dup2\0".as_ptr() as *const c_char) as *const ();
++                self.dup2 = Some(transmute::<*const (), Dup2Fn>(real_dup2_p));
++                let real_close_p = dlsym(libc_h, "close\0".as_ptr() as *const c_char) as *const ();
++                self.close = Some(transmute::<*const (), CloseFn>(real_close_p));
++                let real_chdir_p = dlsym(libc_h, "chdir\0".as_ptr() as *const c_char) as *const ();
++                self.chdir = Some(transmute::<*const (), ChdirFn>(real_chdir_p));
++                let real_setuid_p =
++                    dlsym(libc_h, "setuid\0".as_ptr() as *const c_char) as *const ();
++                self.setuid = Some(transmute::<*const (), SetuidFn>(real_setuid_p));
++                let real_setgid_p =
++                    dlsym(libc_h, "setgid\0".as_ptr() as *const c_char) as *const ();
++                self.setgid = Some(transmute::<*const (), SetgidFn>(real_setgid_p));
++                let real_setgroups_p =
++                    dlsym(libc_h, "setgroups\0".as_ptr() as *const c_char) as *const ();
++                self.setgroups = Some(transmute::<*const (), SetgroupsFn>(real_setgroups_p));
++            },
++            None => {}
++        };
++        // We close before calling but that's OK as this is just a lookup handle
++        unsafe { cvt(libc::dlclose(libc_h))? };
++
+         // Whatever happens after the fork is almost for sure going to touch or
+         // look at the environment in one way or another (PATH in `execvp` or
+         // accessing the `environ` pointer ourselves). Make sure no other thread
+@@ -76,7 +139,7 @@ pub fn spawn(
+         if pid == 0 {
+             crate::panic::always_abort();
+             mem::forget(env_lock);
+-            drop(input);
++            self.unwrap_drop(input);
+             let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
+             let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
+             let errno = errno.to_be_bytes();
+@@ -243,7 +306,48 @@ pub fn exec(&mut self, default: Stdio) -> io::Error {
+             Err(e) => e,
+         }
+     }
+-
++    fn unwrap_drop(&mut self, fh: sys::unix::pipe::AnonPipe) {
++        use crate::os::unix::io::AsRawFd;
++        // drop() simply calls libc::close(fh.fd)
++        match self.close {
++            Some(real_close) => {
++                (real_close)(fh.as_raw_fd());
++            }
++            None => {
++                drop(fh);
++            }
++        }
++    }
++    fn unwrap_dup2(&mut self, src: c_int, dst: c_int) -> c_int {
++        match self.dup2 {
++            Some(real_dup2) => (real_dup2)(src, dst),
++            None => unsafe { libc::dup2(src, dst) },
++        }
++    }
++    fn unwrap_chdir(&self, dir: *const c_char) -> c_int {
++        match self.chdir {
++            Some(real_chdir) => (real_chdir)(dir),
++            None => unsafe { libc::chdir(dir) },
++        }
++    }
++    fn unwrap_setuid(&self, uid: uid_t) -> c_int {
++        match self.setuid {
++            Some(real_setuid) => (real_setuid)(uid),
++            None => unsafe { libc::setuid(uid) },
++        }
++    }
++    fn unwrap_setgid(&self, gid: gid_t) -> c_int {
++        match self.setgid {
++            Some(real_setgid) => (real_setgid)(gid),
++            None => unsafe { libc::setgid(gid) },
++        }
++    }
++    fn unwrap_setgroups(&self, ngroups: libc::size_t, gid: *const gid_t) -> c_int {
++        match self.setgroups {
++            Some(real_setgroups) => (real_setgroups)(ngroups, gid),
++            None => unsafe { libc::setgroups(ngroups, gid) },
++        }
++    }
+     // And at this point we've reached a special time in the life of the
+     // child. The child must now be considered hamstrung and unable to
+     // do anything other than syscalls really. Consider the following
+@@ -282,13 +386,13 @@ unsafe fn do_exec(
+         use crate::sys::{self, cvt_r};
+ 
+         if let Some(fd) = stdio.stdin.fd() {
+-            cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?;
++            cvt_r(|| self.unwrap_dup2(fd, libc::STDIN_FILENO))?;
+         }
+         if let Some(fd) = stdio.stdout.fd() {
+-            cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?;
++            cvt_r(|| self.unwrap_dup2(fd, libc::STDOUT_FILENO))?;
+         }
+         if let Some(fd) = stdio.stderr.fd() {
+-            cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
++            cvt_r(|| self.unwrap_dup2(fd, libc::STDERR_FILENO))?;
+         }
+ 
+         #[cfg(not(target_os = "l4re"))]
+@@ -296,10 +400,10 @@ unsafe fn do_exec(
+             if let Some(_g) = self.get_groups() {
+                 //FIXME: Redox kernel does not support setgroups yet
+                 #[cfg(not(target_os = "redox"))]
+-                cvt(libc::setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
++                cvt(self.unwrap_setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
+             }
+             if let Some(u) = self.get_gid() {
+-                cvt(libc::setgid(u as gid_t))?;
++                cvt(self.unwrap_setgid(u as gid_t))?;
+             }
+             if let Some(u) = self.get_uid() {
+                 // When dropping privileges from root, the `setgroups` call
+@@ -311,13 +415,13 @@ unsafe fn do_exec(
+                 //FIXME: Redox kernel does not support setgroups yet
+                 #[cfg(not(target_os = "redox"))]
+                 if libc::getuid() == 0 && self.get_groups().is_none() {
+-                    cvt(libc::setgroups(0, ptr::null()))?;
++                    cvt(self.unwrap_setgroups(0, ptr::null()))?;
+                 }
+-                cvt(libc::setuid(u as uid_t))?;
++                cvt(self.unwrap_setuid(u as uid_t))?;
+             }
+         }
+         if let Some(ref cwd) = *self.get_cwd() {
+-            cvt(libc::chdir(cwd.as_ptr()))?;
++            cvt(self.unwrap_chdir(cwd.as_ptr()))?;
+         }
+ 
+         if let Some(pgroup) = self.get_pgroup() {
+@@ -378,8 +482,12 @@ fn drop(&mut self) {
+             _reset = Some(Reset(*sys::os::environ()));
+             *sys::os::environ() = envp.as_ptr();
+         }
+-
+-        libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr());
++        match self.execvp {
++            Some(real_execvp) => {
++                (real_execvp)(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr())
++            }
++            None => libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr()),
++        };
+         Err(io::Error::last_os_error())
+     }
+ 
+@@ -394,6 +502,7 @@ fn posix_spawn(
+         _: &ChildPipes,
+         _: Option<&CStringArray>,
+     ) -> io::Result<Option<Process>> {
++        eprintln!("process_unix:270: in null posix_spawn");
+         Ok(None)
+     }
+ 
+@@ -413,12 +522,15 @@ fn posix_spawn(
+         use crate::mem::MaybeUninit;
+         use crate::sys::{self, cvt_nz};
+ 
++        let skip_spawnvp: bool = getenv(&OsString::from("SB2_RUST_NO_SPAWNVP")).is_some();
++
+         if self.get_gid().is_some()
+             || self.get_uid().is_some()
+             || (self.env_saw_path() && !self.program_is_path())
+             || !self.get_closures().is_empty()
+             || self.get_groups().is_some()
+             || self.get_create_pidfd()
++            || skip_spawnvp
+         {
+             return Ok(None);
+         }
diff --git a/0006-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch b/0006-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch
deleted file mode 100644
index df5fd2e..0000000
--- a/0006-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch
+++ /dev/null
@@ -1,365 +0,0 @@
-From 596ba5c8339b803b19734358e464fb25ca2786e6 Mon Sep 17 00:00:00 2001
-From: David Greaves <david.greaves@jolla.com>
-Date: Wed, 20 Jan 2021 09:40:34 +0000
-Subject: [PATCH] Provide ENV controls to bypass some sb2 calls between fork
- exec
-
-In threaded systems there can be deadlocks caused by calling malloc
-after fork and before exec. Rust manages this but sb2 does not.
-
-The following ENV variables are available:
-
-SB2_RUST_EXECVP_SHIM
-
-This executable is passed to the execvp call. The intended executable
-is passed in the argv[] list. Typically set to "/usr/bin/env --". Used
-wth SB2_RUST_USE_REAL_EXECVP which will not do path processing to exec
-this binary but the binary will then exec the command provided via sb2
-lookups.
-
-SB2_RUST_USE_REAL_EXECVP
-When set will cause the libc execvp() to be called and not the sb2
-gate
-
-SB2_RUST_USE_REAL_FN
-This ensures that no sb2 calls to gates for dup2/chdir etc are made
-between fork and exec
-
-SB2_RUST_NO_SPAWNVP
-When set the rust libc::spawnvp() call (which is gated) is bypassed
-and the fallback fork/exec is used.
-
-Note that some reworking of rust's handling of program/argv[0] was
-needed to support the SHIM functionality
-
-Signed-off-by: David Greaves <david.greaves@jolla.com>
----
- library/std/src/sys/unix/process/process_common.rs |  40 ++++-
- library/std/src/sys/unix/process/process_unix.rs   | 138 ++++++++++++++++--
- 2 files changed, 160 insertions(+), 18 deletions(-)
-
-diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
-index 859da691ad2..ee5e776efac 100644
---- a/library/std/src/sys/unix/process/process_common.rs
-+++ b/library/std/src/sys/unix/process/process_common.rs
-@@ -60,7 +60,7 @@
- ////////////////////////////////////////////////////////////////////////////////
-
- pub struct Command {
--    program: CString,
-+    pub(crate) program: CString,
-     args: Vec<CString>,
-     /// Exactly what will be passed to `execvp`.
-     ///
-@@ -69,6 +69,13 @@
-     /// `args` to properly update this as well.
-     argv: Argv,
-     env: CommandEnv,
-+    pub(crate) execvp: Option<ExecvpFn>,
-+    pub(crate) dup2: Option<Dup2Fn>,
-+    pub(crate) close: Option<CloseFn>,
-+    pub(crate) chdir: Option<ChdirFn>,
-+    pub(crate) setuid: Option<SetuidFn>,
-+    pub(crate) setgid: Option<SetgidFn>,
-+    pub(crate) setgroups: Option<SetgroupsFn>,
-
-     cwd: Option<CString>,
-     uid: Option<uid_t>,
-@@ -81,6 +88,14 @@
-     stderr: Option<Stdio>,
- }
-
-+pub(crate) type ExecvpFn = fn(*const c_char, *const *const c_char)->c_int;
-+pub(crate) type Dup2Fn = fn(c_int, c_int)->c_int;
-+pub(crate) type CloseFn = fn(c_int)->c_int;
-+pub(crate) type ChdirFn = fn(*const c_char)->c_int;
-+pub(crate) type SetuidFn = fn(uid_t)->c_int;
-+pub(crate) type SetgidFn = fn(gid_t)->c_int;
-+pub(crate) type SetgroupsFn = fn(libc::size_t, *const gid_t)->c_int;
-+
- // Create a new type for argv, so that we can make it `Send` and `Sync`
- struct Argv(Vec<*const c_char>);
-
-@@ -130,15 +143,23 @@ impl Command {
-     pub fn new(program: &OsStr) -> Command {
-         let mut saw_nul = false;
-         let program = os2c(program, &mut saw_nul);
-+        let arg0 = program.clone();
-         Command {
--            argv: Argv(vec![program.as_ptr(), ptr::null()]),
--            args: vec![program.clone()],
--            program,
-+            argv: Argv(vec![arg0.as_ptr(), ptr::null()]),
-+            args: vec![arg0],
-+            program: program,
-             env: Default::default(),
-+	    execvp: None,
-+	    dup2: None,
-+	    close: None,
-+	    chdir: None,
-+	    setuid: None,
-+	    setgid: None,
-+	    setgroups: None,
-             cwd: None,
-             uid: None,
-             gid: None,
--            saw_nul,
-+            saw_nul: saw_nul,
-             closures: Vec::new(),
-             stdin: None,
-             stdout: None,
-@@ -146,6 +166,16 @@ impl Command {
-         }
-     }
- 
-+    // This allows process_unix::{spawn, exec} to push program to the
-+    // start of /usr/bin/env's arg list
-+    pub fn insert_program(&mut self, arg: String) {
-+	let arg = OsString::from(arg);
-+        let arg = os2c(&arg, &mut self.saw_nul);
-+	self.program = arg.clone();
-+	self.argv.0.insert(0, arg.as_ptr());
-+        self.args.insert(0, arg);
-+    }
-+
-     pub fn set_arg_0(&mut self, arg: &OsStr) {
-         // Set a new arg0
-         let arg = os2c(arg, &mut self.saw_nul);
-diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
-index f389c60615f..d5763b8aa1a 100644
---- a/library/std/src/sys/unix/process/process_unix.rs
-+++ b/library/std/src/sys/unix/process/process_unix.rs
-@@ -5,7 +5,10 @@ #[cfg(target_os = "vxworks")]
- use libc::RTP_ID as pid_t;
- 
- #[cfg(not(target_os = "vxworks"))]
--use libc::{c_int, gid_t, pid_t, uid_t};
-+use libc::{c_int, gid_t, pid_t, uid_t, dlsym, c_char};
-+use crate::intrinsics::transmute;
-+use crate::ffi::{OsString};
-+use sys::os::getenv;
- 
- ////////////////////////////////////////////////////////////////////////////////
- // Command
-@@ -35,6 +41,74 @@ impl Command {
- 
-         let (input, output) = sys::pipe::anon_pipe()?;
- 
-+	// If there is a RUST_EXEC_SHIM (could be "/usr/bin/env --")
-+	// then we're probably going to directly execvp it via dlsym
-+	// to avoid issues with threads and malloc post-fork and
-+	// pre-exec. That will then re-execvp but this time sb2 will
-+	// do magic. See also RUST_EXECVP_REAL
-+
-+	// We do this here and pass so do_exec() so any malloc's are
-+	// pre-fork()
-+
-+	// At this point self.program is the real program. argv[0] is
-+	// now a clone() of program.
-+
-+	let libc_h = unsafe { libc::dlopen("libc.so.6\0".as_ptr() as *const c_char,
-+					   libc::RTLD_LAZY) };
-+
-+	match getenv(&OsString::from("SB2_RUST_EXECVP_SHIM"))? {
-+	    Some(var) => { // handle "/usr/bin/env <arg> <arg>"
-+		let var = var.into_string().expect("Valid string"); // so we can .split()
-+		let words: Vec<&str> = var.as_str().split(" ").collect();
-+		for w in words.iter().rev() {
-+		    self.insert_program(w.to_string());
-+		};
-+		// At this point self.program is the SHIM. argv[0] is
-+		// the SHIM and argv[>0] is the real program.
-+	    },
-+	    None => {} // Business as usual
-+	};
-+	match getenv(&OsString::from("SB2_RUST_USE_REAL_EXECVP"))? {
-+	    Some(_var) => unsafe {
-+		let real_execvp_p = dlsym(libc_h,
-+		      "execvp\0".as_ptr() as *const c_char) as *const ();
-+		self.execvp = Some(
-+		    transmute::<*const (), ExecvpFn>(real_execvp_p) );
-+	    },
-+	    None => {}
-+	};
-+	match getenv(&OsString::from("SB2_RUST_USE_REAL_FN"))? {
-+	    Some(_var) => unsafe {
-+		let real_dup2_p = dlsym(libc_h,
-+		      "dup2\0".as_ptr() as *const c_char) as *const ();
-+		self.dup2 = Some(
-+		    transmute::<*const (), Dup2Fn>(real_dup2_p) );
-+		let real_close_p = dlsym(libc_h,
-+		      "close\0".as_ptr() as *const c_char) as *const ();
-+		self.close = Some(
-+		    transmute::<*const (), CloseFn>(real_close_p) );
-+		let real_chdir_p = dlsym(libc_h,
-+		      "chdir\0".as_ptr() as *const c_char) as *const ();
-+		self.chdir = Some(
-+		    transmute::<*const (), ChdirFn>(real_chdir_p) );
-+		let real_setuid_p = dlsym(libc_h,
-+		      "setuid\0".as_ptr() as *const c_char) as *const ();
-+		self.setuid = Some(
-+		    transmute::<*const (), SetuidFn>(real_setuid_p) );
-+		let real_setgid_p = dlsym(libc_h,
-+		      "setgid\0".as_ptr() as *const c_char) as *const ();
-+		self.setgid = Some(
-+		    transmute::<*const (), SetgidFn>(real_setgid_p) );
-+		let real_setgroups_p = dlsym(libc_h,
-+		      "setgroups\0".as_ptr() as *const c_char) as *const ();
-+		self.setgroups = Some(
-+		    transmute::<*const (), SetgroupsFn>(real_setgroups_p) );
-+	    },
-+	    None => {}
-+	};
-+	// We close before calling but that's OK as this is just a lookup handle
-+	unsafe { cvt(libc::dlclose(libc_h))? };
-+
-         // Whatever happens after the fork is almost for sure going to touch or
-         // look at the environment in one way or another (PATH in `execvp` or
-         // accessing the `environ` pointer ourselves). Make sure no other thread
-@@ -54,7 +125,7 @@
-             match result {
-                 0 => {
-                     mem::forget(env_lock);
--                    drop(input);
-+                    self.unwrap_drop(input);
-                     let Err(err) = self.do_exec(theirs, envp.as_ref());
-                     let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
-                     let errno = errno.to_be_bytes();
-@@ -135,7 +202,43 @@ impl Command {
-             Err(e) => e,
-         }
-     }
--
-+    fn unwrap_drop(&mut self, fh: sys::unix::pipe::AnonPipe) {
-+	// drop() simply calls libc::close(fh.fd)
-+	match self.close {
-+	    Some(real_close) => { (real_close)(fh.fd().raw()); },
-+	    None => { drop(fh); }
-+	}
-+    }
-+    fn unwrap_dup2(&mut self, src: c_int, dst: c_int) -> c_int {
-+	match self.dup2 {
-+	    Some(real_dup2) => { (real_dup2)(src, dst) },
-+	    None => { unsafe { libc::dup2(src, dst) } }
-+	}
-+    }
-+    fn unwrap_chdir(&self, dir: *const c_char) -> c_int {
-+	match self.chdir {
-+	    Some(real_chdir) => { (real_chdir)(dir) },
-+	    None => { unsafe { libc::chdir(dir) } }
-+	}
-+    }
-+    fn unwrap_setuid(&self, uid: uid_t) -> c_int {
-+	match self.setuid {
-+	    Some(real_setuid) => { (real_setuid)(uid) },
-+	    None => { unsafe { libc::setuid(uid) } }
-+	}
-+    }
-+    fn unwrap_setgid(&self, gid: gid_t) -> c_int {
-+	match self.setgid {
-+	    Some(real_setgid) => { (real_setgid)(gid) },
-+	    None => { unsafe { libc::setgid(gid) } }
-+	}
-+    }
-+    fn unwrap_setgroups(&self, ngroups: libc::size_t, gid: *const gid_t) -> c_int {
-+	match self.setgroups {
-+	    Some(real_setgroups) => { (real_setgroups)(ngroups, gid) },
-+	    None => { unsafe { libc::setgroups(ngroups, gid) } }
-+	}
-+    }
-     // And at this point we've reached a special time in the life of the
-     // child. The child must now be considered hamstrung and unable to
-     // do anything other than syscalls really. Consider the following
-@@ -174,24 +277,24 @@ impl Command {
-         use crate::sys::{self, cvt_r};
- 
-         if let Some(fd) = stdio.stdin.fd() {
--            cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?;
-+            cvt_r(|| self.unwrap_dup2(fd, libc::STDIN_FILENO))?;
-         }
-         if let Some(fd) = stdio.stdout.fd() {
--            cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?;
-+            cvt_r(|| self.unwrap_dup2(fd, libc::STDOUT_FILENO))?;
-         }
-         if let Some(fd) = stdio.stderr.fd() {
--            cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
-+            cvt_r(|| self.unwrap_dup2(fd, libc::STDERR_FILENO))?;
-         }
- 
-         #[cfg(not(target_os = "l4re"))]
-         {
-             if let Some(_g) = self.get_groups() {
-                 //FIXME: Redox kernel does not support setgroups yet
-                 #[cfg(not(target_os = "redox"))]
--                cvt(libc::setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
-+                cvt(self.unwrap_setgroups(_g.len().try_into().unwrap(), _g.as_ptr()))?;
-             }
-             if let Some(u) = self.get_gid() {
--                cvt(libc::setgid(u as gid_t))?;
-+                cvt(self.unwrap_setgid(u as gid_t))?;
-             }
-             if let Some(u) = self.get_uid() {
-                 // When dropping privileges from root, the `setgroups` call
-@@ -199,13 +296,13 @@ impl Command {
-                 //FIXME: Redox kernel does not support setgroups yet
-                 #[cfg(not(target_os = "redox"))]
-                 if libc::getuid() == 0 && self.get_groups().is_none() {
--                    cvt(libc::setgroups(0, ptr::null()))?;
-+                    cvt(self.unwrap_setgroups(0, ptr::null()))?;
-                 }
--                cvt(libc::setuid(u as uid_t))?;
-+                cvt(self.unwrap_setuid(u as uid_t))?;
-             }
-         }
-         if let Some(ref cwd) = *self.get_cwd() {
--            cvt(libc::chdir(cwd.as_ptr()))?;
-+            cvt(self.unwrap_chdir(cwd.as_ptr()))?;
-         }
- 
-         // emscripten has no signal support.
-@@ -250,9 +347,17 @@ impl Command {
-             _reset = Some(Reset(*sys::os::environ()));
-             *sys::os::environ() = envp.as_ptr();
-         }
--
--        libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr());
--        Err(io::Error::last_os_error())
-+	match self.execvp {
-+	    Some(real_execvp) => {
-+		(real_execvp)(self.get_program_cstr().as_ptr(),
-+			      self.get_argv().as_ptr())
-+	    },
-+	    None => {
-+		libc::execvp(self.get_program_cstr().as_ptr(),
-+			     self.get_argv().as_ptr())
-+	    }
-+	};
-+	Err(io::Error::last_os_error())
-     }
- 
-     #[cfg(not(any(
-@@ -265,6 +370,7 @@ impl Command {
-         _: &ChildPipes,
-         _: Option<&CStringArray>,
-     ) -> io::Result<Option<Process>> {
-+	eprintln!("process_unix:270: in null posix_spawn");
-         Ok(None)
-     }
- 
-@@ -283,11 +389,14 @@ impl Command {
-         use crate::mem::MaybeUninit;
-         use crate::sys::{self, cvt_nz};
- 
-+	let skip_spawnvp: bool = getenv(&OsString::from("SB2_RUST_NO_SPAWNVP"))?.is_some();
-+
-         if self.get_gid().is_some()
-             || self.get_uid().is_some()
-             || (self.env_saw_path() && !self.program_is_path())
-             || !self.get_closures().is_empty()
-             || self.get_groups().is_some()
-+	    || skip_spawnvp
-         {
-             return Ok(None);
-         }
--- 
-2.20.1
diff --git a/0007-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch b/0006-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
similarity index 56%
rename from 0007-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
rename to 0006-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
index 3ae75c8..0c755a5 100644
--- a/0007-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
+++ b/0006-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
@@ -1,4 +1,4 @@
-From f5d252ef690390c2cb9948995ccf68aeae2b123e Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Ruben De Smet <ruben.de.smet@rubdos.be>
 Date: Thu, 27 Jan 2022 16:32:39 +0100
 Subject: [PATCH] Scratchbox2 needs to be able to tell cargo the default
@@ -8,28 +8,24 @@ This is analogous to the SB2 patch to rustc; ac226bbc018e11311394126fe580763c5bc
 
 Signed-off-by: Ruben De Smet <ruben.de.smet@rubdos.be>
 ---
- src/cargo/core/compiler/compile_kind.rs | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
+ src/tools/cargo | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/tools/cargo/src/cargo/core/compiler/compile_kind.rs b/src/tools/cargo/src/cargo/core/compiler/compile_kind.rs
-index adfa55f..8d892a0 100644
+index c3c921d41..d8a08582a 100644
 --- a/src/tools/cargo/src/cargo/core/compiler/compile_kind.rs
 +++ b/src/tools/cargo/src/cargo/core/compiler/compile_kind.rs
-@@ -76,7 +76,13 @@ impl CompileKind {
-                 };
-                 CompileKind::Target(CompileTarget::new(&value)?)
-             }
--            None => CompileKind::Host,
+@@ -72,7 +72,13 @@ impl CompileKind {
+         }
+
+         let kinds = match &config.build_config()?.target {
+-            None => Ok(vec![CompileKind::Host]),
 +            None => {
 +                if let Ok(sb2_tgt) = std::env::var("SB2_RUST_TARGET_TRIPLE") {
-+                    CompileKind::Target(CompileTarget::new(&sb2_tgt)?)
++                    Ok(vec![CompileKind::Target(CompileTarget::new(&sb2_tgt)?)])
 +                } else {
-+                    CompileKind::Host
++                    Ok(vec![CompileKind::Host])
 +                }
-+            }
++            },
+             Some(build_target_config) => dedup(&build_target_config.values(config)?),
          };
-         Ok(vec![kind])
-     }
--- 
-2.31.1
-
diff --git a/rust-1.52.1-i686-unknown-linux-gnu.tar.gz b/rust-1.52.1-i686-unknown-linux-gnu.tar.gz
deleted file mode 100644
index 57c3bc4..0000000
--- a/rust-1.52.1-i686-unknown-linux-gnu.tar.gz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:c91f0431c8137a4e98e097ab47b49846820531aafb6e9c249b71b770771832e9
-size 353110704
diff --git a/rust-1.61.0-i686-unknown-linux-gnu.tar.gz b/rust-1.61.0-i686-unknown-linux-gnu.tar.gz
new file mode 100644
index 0000000..91762a1
--- /dev/null
+++ b/rust-1.61.0-i686-unknown-linux-gnu.tar.gz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b15eb0ad44b7253e0b5b1a8cd285feb10e9fb0402840dba9a13112c3349a4b39
+size 359348717
diff --git a/rust.spec b/rust.spec
index ec97318..7973c84 100644
--- a/rust.spec
+++ b/rust.spec
@@ -11,13 +11,13 @@
 %define rust_use_bootstrap 1
 %define bootstrap_arches i486
 
-%global bootstrap_rust 1.52.1
-%global bootstrap_cargo 1.52.1
+%global bootstrap_rust 1.61.0
+%global bootstrap_cargo 1.61.0
 
 # Only x86_64 and i686 are Tier 1 platforms at this time.
 # https://forge.rust-lang.org/platform-support.html
 
-%global rust_version 1.52.1
+%global rust_version 1.61.0
 
 %ifarch %ix86
 %define xbuildjobs %{nil}
@@ -45,7 +45,7 @@
 %bcond_without lldb
 
 Name:           rust
-Version:        %{rust_version}+git2
+Version:        %{rust_version}+git1
 Release:        1
 Summary:        The Rust Programming Language
 License:        (ASL 2.0 or MIT) and (BSD and MIT)
@@ -57,12 +57,12 @@ Source0:        rustc-%{rust_version}-src.tar.gz
 Source100:      rust-%{rust_version}-i686-unknown-linux-gnu.tar.gz
 Source200:      README.md
 
-Patch2: 0002-Set-proper-llvm-targets.patch
-Patch3: 0003-Disable-statx-for-all-builds.-JB-50106.patch
-Patch4: 0004-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
-Patch5: 0005-Cargo-Force-the-target-when-building-for-CompileKind-Host.patch
-Patch6: 0006-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch
-Patch7: 0007-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
+Patch1: 0001-Set-proper-llvm-targets.patch
+Patch2: 0002-Disable-statx-for-all-builds.-JB-50106.patch
+Patch3: 0003-Scratchbox2-needs-to-be-able-to-tell-rustc-the-defau.patch
+Patch4: 0004-Force-the-target-when-building-for-CompileKind-Host.patch
+Patch5: 0005-Provide-ENV-controls-to-bypass-some-sb2-calls-betwee.patch
+Patch6: 0006-Scratchbox2-needs-to-be-able-to-tell-cargo-the-defau.patch
 # This is the real rustc spec - the stub one appears near the end.
 %ifarch %ix86
 
@@ -84,13 +84,13 @@ BuildRequires:  gcc
 BuildRequires:  gcc-c++
 
 BuildRequires:  ncurses-devel
-BuildRequires:  pkgconfig(libcurl)
+# BuildRequires:  pkgconfig(libcurl)
 # build.rs and boostrap/config.rs => cargo_native_static?
 BuildRequires:  pkgconfig(liblzma)
 BuildRequires:  pkgconfig(openssl)
 BuildRequires:  pkgconfig(zlib)
 BuildRequires:  python3-base
-BuildRequires:  llvm-devel
+BuildRequires:  llvm-devel >= 12
 BuildRequires:  libffi-devel
 
 # make check needs "ps" for src/test/run-pass/wait-forked-but-failed-child.rs
diff --git a/rustc-1.52.1-src.tar.gz b/rustc-1.52.1-src.tar.gz
deleted file mode 100644
index 75fb28d..0000000
--- a/rustc-1.52.1-src.tar.gz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3a6f23a26d0e8f87abbfbf32c5cd7daa0c0b71d0986abefc56b9a5fbfbd0bf98
-size 168175645
diff --git a/rustc-1.61.0-src.tar.gz b/rustc-1.61.0-src.tar.gz
new file mode 100644
index 0000000..c7fd631
--- /dev/null
+++ b/rustc-1.61.0-src.tar.gz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ad0b4351675aa9abdf4c7e066613bd274c4391c5506db152983426376101daed
+size 203300188