diff --git a/.dotnet6.0.metadata b/.dotnet6.0.metadata
index 1a855ef..69a9be0 100644
--- a/.dotnet6.0.metadata
+++ b/.dotnet6.0.metadata
@@ -1,3 +1 @@
-1aa752efb0102349176045a3262ab4d85961a5e9 SOURCES/dotnet-28be3e9a006d90d8c6e87d4353b77882829df718-x64-bootstrap.tar.xz
-24ff251aaded592f67ec3dfaaca63184d3fd0303 SOURCES/dotnet-arm64-prebuilts-2021-10-04.tar.gz
-1e391934046ab2857b716526310ffa3f9df8ff28 SOURCES/dotnet-s390x-prebuilts-2021-10-01.tar.gz
+0d1ecdbbe7ebfd2fc201854d02d98212a3fcaed3 SOURCES/dotnet-v6.0.101-SDK.tar.gz
diff --git a/.gitignore b/.gitignore
index efd9129..6578a82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1 @@
-SOURCES/dotnet-28be3e9a006d90d8c6e87d4353b77882829df718-x64-bootstrap.tar.xz
-SOURCES/dotnet-arm64-prebuilts-2021-10-04.tar.gz
-SOURCES/dotnet-s390x-prebuilts-2021-10-01.tar.gz
+SOURCES/dotnet-v6.0.101-SDK.tar.gz
diff --git a/SOURCES/aspnetcore-add-arm64-crossgen-dependencies.patch b/SOURCES/aspnetcore-add-arm64-crossgen-dependencies.patch
deleted file mode 100644
index 0bba983..0000000
--- a/SOURCES/aspnetcore-add-arm64-crossgen-dependencies.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/eng/Dependencies.props b/eng/Dependencies.props
-index 8a50fb9f21..a13b74fb51 100644
---- a/eng/Dependencies.props
-+++ b/eng/Dependencies.props
-@@ -99,6 +99,7 @@ and are generated based on the last package release.
-
-
-
-+
-
-
-
diff --git a/SOURCES/aspnetcore-dont-check-eol-targets.patch b/SOURCES/aspnetcore-dont-check-eol-targets.patch
deleted file mode 100644
index 7ab712d..0000000
--- a/SOURCES/aspnetcore-dont-check-eol-targets.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/eng/SourceBuild.props
-+++ b/eng/SourceBuild.props
-@@ -69,6 +69,8 @@
-
-
- $(InnerBuildArgs) /p:SourceBuildRuntimeIdentifier=$(TargetRuntimeIdentifier)
-+ $(InnerBuildArgs) /p:CheckEolTargetFramework=false
-+ $(InnerBuildArgs) /p:EnablePreviewFeatures=true
-
-
-
diff --git a/SOURCES/aspnetcore-no-shared-compilation.patch b/SOURCES/aspnetcore-no-shared-compilation.patch
deleted file mode 100644
index f29acfd..0000000
--- a/SOURCES/aspnetcore-no-shared-compilation.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: source-build-tarball/src/aspnetcore.4ab0cf33ecb1c25a38422f5b11810e4c8a91d8eb/Directory.Build.props
-===================================================================
---- a/Directory.Build.props
-+++ b/Directory.Build.props
-@@ -48,6 +48,8 @@
-
-
- true
-+
-+ false
-
-
-
- $(OtherFlags) --nowarn:1204
-
-Index: tests/benchmarks/TaskPerf/TaskPerf.fsproj
-===================================================================
+
+
+
$(OtherFlags) --nowarn:1204
+
diff --git a/SOURCES/fsharp-no-shared-compilation.patch b/SOURCES/fsharp-no-shared-compilation.patch
deleted file mode 100644
index 21ec960..0000000
--- a/SOURCES/fsharp-no-shared-compilation.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: a/FSharpBuild.Directory.Build.props
-===================================================================
---- a/FSharpBuild.Directory.Build.props
-+++ b/FSharpBuild.Directory.Build.props
-@@ -21,6 +21,7 @@
- 4.4.0
- 1182;0025;$(WarningsAsErrors)
- $(OtherFlags) --nowarn:3384
-+ false
-
-
-
diff --git a/SOURCES/installer-12516-portablerid.patch b/SOURCES/installer-12516-portablerid.patch
new file mode 100644
index 0000000..4cb4ab6
--- /dev/null
+++ b/SOURCES/installer-12516-portablerid.patch
@@ -0,0 +1,23 @@
+From 892222071f73062f969f4f6ed1df8f759b9327b7 Mon Sep 17 00:00:00 2001
+From: Tom Deseyn
+Date: Wed, 3 Nov 2021 15:12:59 +0100
+Subject: [PATCH] GetRuntimeInformation.targets: determine
+ PortableProductMonikerRid based on HostOSName and Architecture.
+
+---
+ src/redist/targets/GetRuntimeInformation.targets | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/redist/targets/GetRuntimeInformation.targets b/src/redist/targets/GetRuntimeInformation.targets
+index 5133c3a3841..01f704c7d8e 100644
+--- a/src/redist/targets/GetRuntimeInformation.targets
++++ b/src/redist/targets/GetRuntimeInformation.targets
+@@ -28,6 +28,8 @@
+ '$(Rid)' == 'linux-musl-x64' ">$(Rid)
+ $(OSName)-$(Architecture)
+
++ $(HostOSName)-$(Architecture)
++
+ dotnet-sdk-internal$(PgoTerm)
+ dotnet-sdk$(PgoTerm)
+
diff --git a/SOURCES/installer-12736-no-sudo.patch b/SOURCES/installer-12736-no-sudo.patch
new file mode 100644
index 0000000..34d583a
--- /dev/null
+++ b/SOURCES/installer-12736-no-sudo.patch
@@ -0,0 +1,39 @@
+From f8e115fadf6e8b392fa007e78d9b77fc64590cdd Mon Sep 17 00:00:00 2001
+From: Daniel Plaisted
+Date: Mon, 29 Nov 2021 20:19:30 -0800
+Subject: [PATCH] Don't set ulimit
+
+1ES pools should now have ulimit set already now
+---
+ build.sh | 4 +---
+ run-build.sh | 4 ----
+ 2 files changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/build.sh b/build.sh
+index 594a355fafa..7ff647c4060 100755
+--- a/build.sh
++++ b/build.sh
+@@ -53,7 +53,5 @@ dockerbuild()
+ if [ ! -z "$BUILD_IN_DOCKER" ]; then
+ dockerbuild $args
+ else
+- # Run under sudo so we can set ulimit
+- # See https://github.com/dotnet/core-eng/issues/14808
+- sudo -E $DIR/run-build.sh $args
++ $DIR/run-build.sh $args
+ fi
+diff --git a/run-build.sh b/run-build.sh
+index fe839eb8009..7b98aedc0be 100755
+--- a/run-build.sh
++++ b/run-build.sh
+@@ -25,10 +25,6 @@ CUSTOM_BUILD_ARGS=
+ # Set nuget package cache under the repo
+ [ -z $NUGET_PACKAGES ] && export NUGET_PACKAGES="$REPOROOT/.nuget/packages"
+
+-# Set max number of files open, helps avoid errors during NuGet restore
+-# See https://github.com/dotnet/core-eng/issues/14808
+-ulimit -n 16384
+-
+ args=( )
+
+ while [[ $# > 0 ]]; do
diff --git a/SOURCES/msbuild-no-systemconfiguration.patch b/SOURCES/msbuild-no-systemconfiguration.patch
new file mode 100644
index 0000000..537470d
--- /dev/null
+++ b/SOURCES/msbuild-no-systemconfiguration.patch
@@ -0,0 +1,46 @@
+--- a/src/Build/Definition/ProjectCollection.cs
++++ b/src/Build/Definition/ProjectCollection.cs
+@@ -1754,7 +1754,11 @@ namespace Microsoft.Build.Evaluation
+ #if FEATURE_WIN32_REGISTRY
+ ToolsetRegistryReader registryReader = null,
+ #endif
++#if FEATURE_SYSTEM_CONFIGURATION
+ ToolsetConfigurationReader configReader = null
++#else
++ object configReader = null
++#endif
+ )
+ {
+ _toolsets = new Dictionary(StringComparer.OrdinalIgnoreCase);
+--- a/src/Build/Definition/ToolsetReader.cs
++++ b/src/Build/Definition/ToolsetReader.cs
+@@ -101,7 +101,11 @@ namespace Microsoft.Build.Evaluation
+ #if FEATURE_WIN32_REGISTRY
+ ToolsetRegistryReader registryReader,
+ #endif
++#if FEATURE_SYSTEM_CONFIGURATION
+ ToolsetConfigurationReader configurationReader,
++#else
++ object _configurationReader,
++#endif
+ PropertyDictionary environmentProperties,
+ PropertyDictionary globalProperties,
+ ToolsetDefinitionLocations locations
+@@ -120,6 +124,7 @@ namespace Microsoft.Build.Evaluation
+
+ if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
+ {
++#if FEATURE_SYSTEM_CONFIGURATION
+ if (configurationReader == null)
+ {
+ configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties);
+@@ -129,6 +134,9 @@ namespace Microsoft.Build.Evaluation
+ defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties,
+ initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration,
+ out defaultOverrideToolsVersionFromConfiguration);
++#else
++ throw new InvalidOperationException("ToolsetDefinitionLocations.ConfigurationFile not supported");
++#endif
+ }
+
+ string defaultToolsVersionFromRegistry = null;
diff --git a/SOURCES/msbuild-no-systemsecurity.patch b/SOURCES/msbuild-no-systemsecurity.patch
new file mode 100644
index 0000000..dcf6809
--- /dev/null
+++ b/SOURCES/msbuild-no-systemsecurity.patch
@@ -0,0 +1,12 @@
+--- a/src/Shared/ExceptionHandling.cs
++++ b/src/Shared/ExceptionHandling.cs
+@@ -153,7 +153,9 @@ namespace Microsoft.Build.Shared
+ internal static bool IsXmlException(Exception e)
+ {
+ return e is XmlException
++#if FEATURE_SECURITY_PERMISSIONS
+ || e is XmlSyntaxException
++#endif
+ || e is XmlSchemaException
+ || e is UriFormatException; // XmlTextReader for example uses this under the covers
+ }
diff --git a/SOURCES/nuget-client-use-work-tree-with-git-apply.patch b/SOURCES/nuget-client-use-work-tree-with-git-apply.patch
deleted file mode 100644
index e1785ae..0000000
--- a/SOURCES/nuget-client-use-work-tree-with-git-apply.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 691babb1c8316e2f829fbcf9f2aa14f4b7711960 Mon Sep 17 00:00:00 2001
-From: Omair Majid
-Date: Thu, 9 Sep 2021 10:03:36 -0400
-Subject: [PATCH] [ArPow] Use --work-tree with git apply
-
-This makes things work bettern in a source-tarball build (where there
-may not be a .git directory), or there might be a .git directory but
-it's for a different repo than the one we are building.
----
- eng/source-build/source-build.proj | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/eng/source-build/source-build.proj b/eng/source-build/source-build.proj
-index 6f90f9793..72058ac88 100644
---- a/eng/source-build/source-build.proj
-+++ b/eng/source-build/source-build.proj
-@@ -55,7 +55,7 @@
-
-
-
-
---
-2.31.1
-
diff --git a/SOURCES/roslyn-57003-mono-named-mutex.patch b/SOURCES/roslyn-57003-mono-named-mutex.patch
new file mode 100644
index 0000000..c264bff
--- /dev/null
+++ b/SOURCES/roslyn-57003-mono-named-mutex.patch
@@ -0,0 +1,453 @@
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs
+@@ -31,5 +31,24 @@ namespace Roslyn.Utilities
+ }
+ }
+ }
++ ///
++ /// Are we running on .NET 5 or later using the Mono runtime?
++ /// Will also return true when running on Mono itself; if necessary
++ /// we can use IsRunningOnMono to distinguish.
++ ///
++ public static bool IsUsingMonoRuntime
++ {
++ get
++ {
++ try
++ {
++ return !(Type.GetType("Mono.RuntimeStructs", throwOnError: false) is null);
++ }
++ catch
++ {
++ return false;
++ }
++ }
++ }
+ }
+ }
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs
+@@ -79,7 +79,7 @@ namespace Microsoft.CodeAnalysis.Compile
+ // to connect. When it fails it should fall back to in-proc
+ // compilation.
+ bool holdsMutex;
+- using (var serverMutex = new Mutex(initiallyOwned: true,
++ using (var serverMutex = BuildServerConnection.OpenOrCreateMutex(
+ name: BuildServerConnection.GetServerMutexName(_pipeName),
+ createdNew: out holdsMutex))
+ {
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
+@@ -103,7 +103,7 @@ class Hello
+ var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
+
+ bool holdsMutex;
+- using (var mutex = new Mutex(initiallyOwned: true,
++ using (var mutex = BuildServerConnection.OpenOrCreateMutex(
+ name: mutexName,
+ createdNew: out holdsMutex))
+ {
+@@ -119,7 +119,7 @@ class Hello
+ }
+ finally
+ {
+- mutex.ReleaseMutex();
++ mutex.Dispose();
+ }
+ }
+ }
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs
+@@ -304,7 +304,7 @@ End Module")
+ var newTempDir = _tempDirectory.CreateDirectory(new string('a', 100 - _tempDirectory.Path.Length));
+ await ApplyEnvironmentVariables(
+ new[] { new KeyValuePair("TMPDIR", newTempDir.Path) },
+- async () =>
++ async () => await Task.Run(async () =>
+ {
+ using var serverData = await ServerUtil.CreateServer(_logger);
+ var result = RunCommandLineCompiler(
+@@ -317,7 +317,7 @@ End Module")
+
+ var listener = await serverData.Complete();
+ Assert.Equal(CompletionData.RequestCompleted, listener.CompletionDataList.Single());
+- });
++ }));
+ }
+
+ [Fact]
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs
+@@ -101,7 +101,7 @@ namespace Microsoft.CodeAnalysis.Compile
+
+ var thread = new Thread(() =>
+ {
+- using (var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created))
++ using (var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created))
+ using (var stream = NamedPipeUtil.CreateServer(pipeName))
+ {
+ readyMre.Set();
+@@ -112,7 +112,7 @@ namespace Microsoft.CodeAnalysis.Compile
+ stream.Close();
+
+ doneMre.WaitOne();
+- mutex.ReleaseMutex();
++ mutex.Dispose();
+ }
+ });
+
+@@ -153,7 +153,7 @@ namespace Microsoft.CodeAnalysis.Compile
+ {
+ using (var stream = NamedPipeUtil.CreateServer(pipeName))
+ {
+- var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created);
++ var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created);
+ readyMre.Set();
+
+ stream.WaitForConnection();
+@@ -161,7 +161,6 @@ namespace Microsoft.CodeAnalysis.Compile
+
+ // Client is waiting for a response. Close the mutex now. Then close the connection
+ // so the client gets an error.
+- mutex.ReleaseMutex();
+ mutex.Dispose();
+ stream.Close();
+
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs
+@@ -543,19 +543,10 @@ namespace Microsoft.CodeAnalysis.Command
+ {
+ try
+ {
+- if (PlatformInformation.IsRunningOnMono)
++ if (PlatformInformation.IsUsingMonoRuntime)
+ {
+- IServerMutex? mutex = null;
+- bool createdNew = false;
+- try
+- {
+- mutex = new ServerFileMutexPair(mutexName, false, out createdNew);
+- return !createdNew;
+- }
+- finally
+- {
+- mutex?.Dispose();
+- }
++ using var mutex = new ServerFileMutex(mutexName);
++ return !mutex.CouldLock();
+ }
+ else
+ {
+@@ -572,9 +563,11 @@ namespace Microsoft.CodeAnalysis.Command
+
+ internal static IServerMutex OpenOrCreateMutex(string name, out bool createdNew)
+ {
+- if (PlatformInformation.IsRunningOnMono)
++ if (PlatformInformation.IsUsingMonoRuntime)
+ {
+- return new ServerFileMutexPair(name, initiallyOwned: true, out createdNew);
++ var mutex = new ServerFileMutex(name);
++ createdNew = mutex.TryLock(0);
++ return mutex;
+ }
+ else
+ {
+@@ -648,19 +641,22 @@ namespace Microsoft.CodeAnalysis.Command
+ }
+
+ ///
+- /// An interprocess mutex abstraction based on OS advisory locking (FileStream.Lock/Unlock).
++ /// An interprocess mutex abstraction based on file sharing permission (FileShare.None).
+ /// If multiple processes running as the same user create FileMutex instances with the same name,
+ /// those instances will all point to the same file somewhere in a selected temporary directory.
+- /// The TryLock method can be used to attempt to acquire the mutex, with Unlock or Dispose used to release.
++ /// The TryLock method can be used to attempt to acquire the mutex, with Dispose used to release.
++ /// The CouldLock method can be used to check whether an attempt to acquire the mutex would have
++ /// succeeded at the current time, without actually acquiring it.
+ /// Unlike Win32 named mutexes, there is no mechanism for detecting an abandoned mutex. The file
+ /// will simply revert to being unlocked but remain where it is.
+ ///
+- internal sealed class FileMutex : IDisposable
++ internal sealed class ServerFileMutex : IServerMutex
+ {
+- public readonly FileStream Stream;
++ public FileStream? Stream;
+ public readonly string FilePath;
++ public readonly string GuardPath;
+
+- public bool IsLocked { get; private set; }
++ public bool IsDisposed { get; private set; }
+
+ internal static string GetMutexDirectory()
+ {
+@@ -670,61 +666,176 @@ namespace Microsoft.CodeAnalysis.Command
+ return result;
+ }
+
+- public FileMutex(string name)
++ public ServerFileMutex(string name)
+ {
+- FilePath = Path.Combine(GetMutexDirectory(), name);
+- Stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
++ var mutexDirectory = GetMutexDirectory();
++ FilePath = Path.Combine(mutexDirectory, name);
++ GuardPath = Path.Combine(mutexDirectory, ".guard");
+ }
+
+- public bool TryLock(int timeoutMs)
++ ///
++ /// Acquire the guard by opening the guard file with FileShare.None. The guard must only ever
++ /// be held for very brief amounts of time, so we can simply spin until it is acquired. The
++ /// guard must be released by disposing the FileStream returned from this routine. Note the
++ /// guard file is never deleted; this is a leak, but only of a single file.
++ ///
++ internal FileStream LockGuard()
+ {
+- if (IsLocked)
+- throw new InvalidOperationException("Lock already held");
+-
+- var sw = Stopwatch.StartNew();
+- do
++ // We should be able to acquire the guard quickly. Limit the number of retries anyway
++ // by some arbitrary bound to avoid getting hung up in a possibly infinite loop.
++ for (var i = 0; i < 100; i++)
+ {
+ try
+ {
+- Stream.Lock(0, 0);
+- IsLocked = true;
+- return true;
++ return new FileStream(GuardPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
+ }
+ catch (IOException)
+ {
+- // Lock currently held by someone else.
++ // Guard currently held by someone else.
+ // We want to sleep for a short period of time to ensure that other processes
+ // have an opportunity to finish their work and relinquish the lock.
+ // Spinning here (via Yield) would work but risks creating a priority
+ // inversion if the lock is held by a lower-priority process.
+ Thread.Sleep(1);
+ }
++ }
++ // Handle unexpected failure to acquire guard as error.
++ throw new InvalidOperationException("Unable to acquire guard");
++ }
++
++ ///
++ /// Attempt to acquire the lock by opening the lock file with FileShare.None. Sets "Stream"
++ /// and returns true if successful, returns false if the lock is already held by another
++ /// thread or process. Guard must be held when calling this routine.
++ ///
++ internal bool TryLockFile()
++ {
++ Debug.Assert(Stream is null);
++ FileStream? stream = null;
++ try
++ {
++ stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
++ // On some targets, the file locking used to implement FileShare.None may not be
++ // atomic with opening/creating the file. This creates a race window when another
++ // thread holds the lock and is just about to unlock: we may be able to open the
++ // file here, then the other thread unlocks and deletes the file, and then we
++ // acquire the lock on our file handle - but the actual file is already deleted.
++ // To close this race, we verify that the file does in fact still exist now that
++ // we have successfull acquired the locked FileStream. (Note that this check is
++ // safe because we cannot race with an other attempt to create the file since we
++ // hold the guard, and after the FileStream constructor returned we can no race
++ // with file deletion because we hold the lock.)
++ if (!File.Exists(FilePath))
++ {
++ // To simplify the logic, we treat this case as "unable to acquire the lock"
++ // because it we caught another process while it owned the lock and was just
++ // giving it up. If the caller retries, we'll likely acquire the lock then.
++ stream.Dispose();
++ return false;
++ }
++ }
++ catch (Exception)
++ {
++ stream?.Dispose();
++ return false;
++ }
++ Stream = stream;
++ return true;
++ }
++
++ ///
++ /// Release the lock by deleting the lock file and disposing "Stream".
++ ///
++ internal void UnlockFile()
++ {
++ Debug.Assert(Stream is not null);
++ try
++ {
++ // Delete the lock file while the stream is not yet disposed
++ // and we therefore still hold the FileShare.None exclusion.
++ // There may still be a race with another thread attempting a
++ // TryLockFile in parallel, but that is safely handled there.
++ File.Delete(FilePath);
++ }
++ finally
++ {
++ Stream.Dispose();
++ Stream = null;
++ }
++ }
++
++ public bool TryLock(int timeoutMs)
++ {
++ if (IsDisposed)
++ throw new ObjectDisposedException("Mutex");
++ if (Stream is not null)
++ throw new InvalidOperationException("Lock already held");
++
++ var sw = Stopwatch.StartNew();
++ do
++ {
++ try
++ {
++ // Attempt to acquire lock while holding guard.
++ using var guard = LockGuard();
++ if (TryLockFile())
++ return true;
++ }
+ catch (Exception)
+ {
+- // Something else went wrong.
+ return false;
+ }
++
++ // See comment in LockGuard.
++ Thread.Sleep(1);
+ } while (sw.ElapsedMilliseconds < timeoutMs);
+
+ return false;
+ }
+
+- public void Unlock()
++ public bool CouldLock()
+ {
+- if (!IsLocked)
+- return;
+- Stream.Unlock(0, 0);
+- IsLocked = false;
++ if (IsDisposed)
++ return false;
++ if (Stream is not null)
++ return false;
++
++ try
++ {
++ // Attempt to acquire lock while holding guard, and if successful
++ // immediately unlock again while still holding guard. This ensures
++ // no other thread will spuriously observe the lock as held due to
++ // the lock attempt here.
++ using var guard = LockGuard();
++ if (TryLockFile())
++ {
++ UnlockFile();
++ return true;
++ }
++ }
++ catch (Exception)
++ {
++ return false;
++ }
++
++ return false;
+ }
+
+ public void Dispose()
+ {
+- var wasLocked = IsLocked;
+- if (wasLocked)
+- Unlock();
+- Stream.Dispose();
+- // We do not delete the lock file here because there is no reliable way to perform a
+- // 'delete if no one has the file open' operation atomically on *nix. This is a leak.
++ if (IsDisposed)
++ return;
++ IsDisposed = true;
++ if (Stream is not null)
++ {
++ try
++ {
++ UnlockFile();
++ }
++ catch (Exception)
++ {
++ }
++ }
+ }
+ }
+
+@@ -792,56 +903,4 @@ namespace Microsoft.CodeAnalysis.Command
+ }
+ }
+ }
+-
+- ///
+- /// Approximates a named mutex with 'locked', 'unlocked' and 'abandoned' states.
+- /// There is no reliable way to detect whether a mutex has been abandoned on some target platforms,
+- /// so we use the AliveMutex to manually track whether the creator of a mutex is still running,
+- /// while the HeldMutex represents the actual lock state of the mutex.
+- ///
+- internal sealed class ServerFileMutexPair : IServerMutex
+- {
+- public readonly FileMutex AliveMutex;
+- public readonly FileMutex HeldMutex;
+-
+- public bool IsDisposed { get; private set; }
+-
+- public ServerFileMutexPair(string mutexName, bool initiallyOwned, out bool createdNew)
+- {
+- AliveMutex = new FileMutex(mutexName + "-alive");
+- HeldMutex = new FileMutex(mutexName + "-held");
+- createdNew = AliveMutex.TryLock(0);
+- if (initiallyOwned && createdNew)
+- {
+- if (!TryLock(0))
+- throw new Exception("Failed to lock mutex after creating it");
+- }
+- }
+-
+- public bool TryLock(int timeoutMs)
+- {
+- if (IsDisposed)
+- throw new ObjectDisposedException("Mutex");
+- return HeldMutex.TryLock(timeoutMs);
+- }
+-
+- public void Dispose()
+- {
+- if (IsDisposed)
+- return;
+- IsDisposed = true;
+-
+- try
+- {
+- HeldMutex.Unlock();
+- AliveMutex.Unlock();
+- }
+- finally
+- {
+- AliveMutex.Dispose();
+- HeldMutex.Dispose();
+- }
+- }
+- }
+-
+ }
diff --git a/SOURCES/roslyn-analyzers-no-apphost.patch b/SOURCES/roslyn-analyzers-no-apphost.patch
index f4e7f4b..c1fc3dd 100644
--- a/SOURCES/roslyn-analyzers-no-apphost.patch
+++ b/SOURCES/roslyn-analyzers-no-apphost.patch
@@ -1,11 +1,9 @@
-Index: roslyn-analyzers.e71e518713d6d578569bba6c5d401e405eee6058/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj
-===================================================================
--- a/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj
+++ b/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj
-@@ -3,6 +3,7 @@
- Exe
+@@ -4,6 +4,7 @@
netcoreapp3.1
true
+ true
+ false
diff --git a/SOURCES/roslyn-no-apphost.patch b/SOURCES/roslyn-no-apphost.patch
index b2511f9..f1767c7 100644
--- a/SOURCES/roslyn-no-apphost.patch
+++ b/SOURCES/roslyn-no-apphost.patch
@@ -1,125 +1,10 @@
-Index: a/src/Interactive/csi/csi.csproj
-===================================================================
---- a/src/Interactive/csi/csi.csproj
-+++ b/src/Interactive/csi/csi.csproj
-@@ -6,6 +6,7 @@
+--- a/src/Workspaces/Remote/ServiceHub.CoreComponents/Microsoft.CodeAnalysis.Remote.ServiceHub.CoreComponents.csproj
++++ b/src/Workspaces/Remote/ServiceHub.CoreComponents/Microsoft.CodeAnalysis.Remote.ServiceHub.CoreComponents.csproj
+@@ -5,6 +5,7 @@
Exe
- CSharpInteractive
- netcoreapp3.1;net472
-+ false
-
-
-
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Interactive/vbi/vbi.vbproj
-===================================================================
---- a/src/Interactive/vbi/vbi.vbproj
-+++ b/src/Interactive/vbi/vbi.vbproj
-@@ -7,6 +7,7 @@
- Sub Main
- netcoreapp3.1;net472
-
-+ false
-
-
-
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/CSharpSyntaxGenerator.csproj
-===================================================================
---- a/src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/CSharpSyntaxGenerator.csproj
-+++ b/src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/CSharpSyntaxGenerator.csproj
-@@ -14,6 +14,7 @@
- $(RoslynPortableRuntimeIdentifiers)
- false
- false
-+ false
-
-
-
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/PrepareTests/PrepareTests.csproj
-===================================================================
---- a/src/Tools/PrepareTests/PrepareTests.csproj
-+++ b/src/Tools/PrepareTests/PrepareTests.csproj
-@@ -7,6 +7,7 @@
- false
- false
- false
-+ false
-
-
-
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator/CompilersBoundTreeGenerator.csproj
-===================================================================
---- a/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator/CompilersBoundTreeGenerator.csproj
-+++ b/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator/CompilersBoundTreeGenerator.csproj
-@@ -11,8 +11,9 @@
- True
- netcoreapp3.1
- false
-+ false
-
-
-
-
--
-\ No newline at end of file
-+
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/CSharpErrorFactsGenerator/CSharpErrorFactsGenerator.csproj
-===================================================================
---- a/src/Tools/Source/CompilerGeneratorTools/Source/CSharpErrorFactsGenerator/CSharpErrorFactsGenerator.csproj
-+++ b/src/Tools/Source/CompilerGeneratorTools/Source/CSharpErrorFactsGenerator/CSharpErrorFactsGenerator.csproj
-@@ -10,5 +10,6 @@
- True
- netcoreapp3.1
- false
-+ false
-
--
-\ No newline at end of file
-+
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/IOperationGenerator/CompilersIOperationGenerator.csproj
-===================================================================
---- a/src/Tools/Source/CompilerGeneratorTools/Source/IOperationGenerator/CompilersIOperationGenerator.csproj
-+++ b/src/Tools/Source/CompilerGeneratorTools/Source/IOperationGenerator/CompilersIOperationGenerator.csproj
-@@ -8,5 +8,6 @@
- True
- net5.0
- false
-+ false
-
-
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicErrorFactsGenerator/VisualBasicErrorFactsGenerator.vbproj
-===================================================================
---- a/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicErrorFactsGenerator/VisualBasicErrorFactsGenerator.vbproj
-+++ b/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicErrorFactsGenerator/VisualBasicErrorFactsGenerator.vbproj
-@@ -12,5 +12,6 @@
- True
netcoreapp3.1
- false
-+ false
-
--
-\ No newline at end of file
-+
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicSyntaxGenerator/VisualBasicSyntaxGenerator.vbproj
-===================================================================
---- a/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicSyntaxGenerator/VisualBasicSyntaxGenerator.vbproj
-+++ b/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicSyntaxGenerator/VisualBasicSyntaxGenerator.vbproj
-@@ -13,6 +13,7 @@
- True
- netcoreapp3.1
- false
+
+ false
-
-
-
-Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/RunTests/RunTests.csproj
-===================================================================
---- a/src/Tools/Source/RunTests/RunTests.csproj
-+++ b/src/Tools/Source/RunTests/RunTests.csproj
-@@ -7,6 +7,7 @@
- true
- false
false
-+ false
-
diff --git a/SOURCES/roslyn-no-shared-compilation.patch b/SOURCES/roslyn-no-shared-compilation.patch
deleted file mode 100644
index 2c1f7c0..0000000
--- a/SOURCES/roslyn-no-shared-compilation.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: source-build-tarball/src/roslyn.2cb3d482e3c09760d1b204c597be93f49dba3349/eng/targets/Settings.props
-===================================================================
---- a/eng/targets/Settings.props
-+++ b/eng/targets/Settings.props
-@@ -39,6 +39,8 @@
- Microsoft.Common.CurrentVersion.targets to see how it is consumed -->
- false
-
-+ false
-+
- false
- enable
-
diff --git a/SOURCES/runtime-arm64-lld-fix.patch b/SOURCES/runtime-arm64-lld-fix.patch
index 5972f45..db6f520 100644
--- a/SOURCES/runtime-arm64-lld-fix.patch
+++ b/SOURCES/runtime-arm64-lld-fix.patch
@@ -2,12 +2,17 @@ diff --git a/eng/native/init-compiler.sh b/eng/native/init-compiler.sh
index 567d18da474..927b3071e92 100755
--- a/eng/native/init-compiler.sh
+++ b/eng/native/init-compiler.sh
-@@ -108,7 +108,7 @@ if [[ -z "$CC" ]]; then
+@@ -108,11 +108,8 @@
fi
if [[ "$compiler" == "clang" ]]; then
- if command -v "lld$desired_version" > /dev/null; then
-+ if command -v lld || command -v "lld$desired_version" > /dev/null; then
- # Only lld version >= 9 can be considered stable
- if [[ "$majorVersion" -ge 9 ]]; then
- LDFLAGS="-fuse-ld=lld"
+- # Only lld version >= 9 can be considered stable
+- if [[ "$majorVersion" -ge 9 ]]; then
+- LDFLAGS="-fuse-ld=lld"
+- fi
++ if "$CC" -fuse-ld=lld -Wl,--version >/dev/null 2>&1; then
++ LDFLAGS="-fuse-ld=lld"
+ fi
+ fi
+
diff --git a/SOURCES/runtime-bigendian-ilasm-pdb.patch b/SOURCES/runtime-bigendian-ilasm-pdb.patch
deleted file mode 100644
index 00c31ec..0000000
--- a/SOURCES/runtime-bigendian-ilasm-pdb.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-Index: a/src/coreclr/ilasm/writer.cpp
-===================================================================
---- a/src/coreclr/ilasm/writer.cpp
-+++ b/src/coreclr/ilasm/writer.cpp
-@@ -212,26 +212,28 @@ HRESULT Assembler::CreateDebugDirectory(
- param.debugDirData = NULL;
-
- // get module ID
-- DWORD rsds = 0x53445352;
-- DWORD pdbAge = 0x1;
-+ DWORD rsds = VAL32(0x53445352);
-+ DWORD pdbAge = VAL32(0x1);
-+ GUID pdbGuid = *m_pPortablePdbWriter->GetGuid();
-+ SwapGuid(&pdbGuid);
- DWORD len = sizeof(rsds) + sizeof(GUID) + sizeof(pdbAge) + (DWORD)strlen(m_szPdbFileName) + 1;
- BYTE* dbgDirData = new BYTE[len];
-
- DWORD offset = 0;
- memcpy_s(dbgDirData + offset, len, &rsds, sizeof(rsds)); // RSDS
- offset += sizeof(rsds);
-- memcpy_s(dbgDirData + offset, len, m_pPortablePdbWriter->GetGuid(), sizeof(GUID)); // PDB GUID
-+ memcpy_s(dbgDirData + offset, len, &pdbGuid, sizeof(GUID)); // PDB GUID
- offset += sizeof(GUID);
- memcpy_s(dbgDirData + offset, len, &pdbAge, sizeof(pdbAge)); // PDB AGE
- offset += sizeof(pdbAge);
- memcpy_s(dbgDirData + offset, len, m_szPdbFileName, strlen(m_szPdbFileName) + 1); // PDB PATH
-
- debugDirIDD.Characteristics = 0;
-- debugDirIDD.TimeDateStamp = m_pPortablePdbWriter->GetTimestamp();
-- debugDirIDD.MajorVersion = 0x100;
-- debugDirIDD.MinorVersion = 0x504d;
-- debugDirIDD.Type = IMAGE_DEBUG_TYPE_CODEVIEW;
-- debugDirIDD.SizeOfData = len;
-+ debugDirIDD.TimeDateStamp = VAL32(m_pPortablePdbWriter->GetTimestamp());
-+ debugDirIDD.MajorVersion = VAL16(0x100);
-+ debugDirIDD.MinorVersion = VAL16(0x504d);
-+ debugDirIDD.Type = VAL32(IMAGE_DEBUG_TYPE_CODEVIEW);
-+ debugDirIDD.SizeOfData = VAL32(len);
- debugDirIDD.AddressOfRawData = 0; // will be updated bellow
- debugDirIDD.PointerToRawData = 0; // will be updated bellow
-
-Index: a/src/coreclr/md/enc/pdbheap.cpp
-===================================================================
---- a/src/coreclr/md/enc/pdbheap.cpp
-+++ b/src/coreclr/md/enc/pdbheap.cpp
-@@ -26,6 +26,16 @@ HRESULT PdbHeap::SetData(PORT_PDB_STREAM
- (sizeof(ULONG) * data->typeSystemTableRowsSize);
- m_data = new BYTE[m_size];
-
-+#if BIGENDIAN
-+ PORT_PDB_STREAM swappedData = *data;
-+ SwapGuid(&swappedData.id.pdbGuid);
-+ swappedData.id.pdbTimeStamp = VAL32(swappedData.id.pdbTimeStamp);
-+ swappedData.entryPoint = VAL32(swappedData.entryPoint);
-+ swappedData.referencedTypeSystemTables = VAL64(swappedData.referencedTypeSystemTables);
-+ // typeSystemTableRows and typeSystemTableRowsSize handled below
-+ data = &swappedData;
-+#endif
-+
- ULONG offset = 0;
- if (memcpy_s(m_data + offset, m_size, &data->id, sizeof(data->id)))
- return E_FAIL;
-@@ -39,9 +49,17 @@ HRESULT PdbHeap::SetData(PORT_PDB_STREAM
- return E_FAIL;
- offset += sizeof(data->referencedTypeSystemTables);
-
-+#if !BIGENDIAN
- if (memcpy_s(m_data + offset, m_size, data->typeSystemTableRows, sizeof(ULONG) * data->typeSystemTableRowsSize))
- return E_FAIL;
- offset += sizeof(ULONG) * data->typeSystemTableRowsSize;
-+#else
-+ for (int i = 0; i < data->typeSystemTableRowsSize; i++)
-+ {
-+ SET_UNALIGNED_VAL32(m_data + offset, data->typeSystemTableRows[i]);
-+ offset += sizeof(ULONG);
-+ }
-+#endif
-
- _ASSERTE(offset == m_size);
-
diff --git a/SOURCES/runtime-mono-memfunc-cgroup.patch b/SOURCES/runtime-mono-memfunc-cgroup.patch
deleted file mode 100644
index b4c8fba..0000000
--- a/SOURCES/runtime-mono-memfunc-cgroup.patch
+++ /dev/null
@@ -1,755 +0,0 @@
-Index: a/src/mono/mono/utils/memfuncs.c
-===================================================================
---- a/src/mono/mono/utils/memfuncs.c
-+++ b/src/mono/mono/utils/memfuncs.c
-@@ -343,6 +343,9 @@ mono_determine_physical_ram_available_si
- host_page_size (host, &page_size);
- return (guint64) vmstat.free_count * page_size;
-
-+#elif defined (__FreeBSD__) || defined (__linux__) || defined (__APPLE__)
-+ return (getPhysicalMemoryAvail());
-+
- #elif defined (HAVE_SYSCONF)
- gint64 page_size = -1, num_pages = -1;
-
-Index: a/src/mono/mono/utils/memfuncs.h
-===================================================================
---- a/src/mono/mono/utils/memfuncs.h
-+++ b/src/mono/mono/utils/memfuncs.h
-@@ -24,5 +24,10 @@ MONO_COMPONENT_API void mono_gc_memmove_
- void mono_gc_memmove_aligned (void *dest, const void *src, size_t size);
- guint64 mono_determine_physical_ram_size (void);
- guint64 mono_determine_physical_ram_available_size (void);
-+#if defined (__FreeBSD__) || defined (__linux__) || defined (__APPLE__)
-+size_t getRestrictedPhysicalMemoryLimit(void);
-+gboolean getPhysicalMemoryUsed(size_t *);
-+size_t getPhysicalMemoryAvail(void);
-+#endif
-
- #endif
-Index: a/src/mono/mono/utils/mono-cgroup.c
-===================================================================
---- /dev/null
-+++ b/src/mono/mono/utils/mono-cgroup.c
-@@ -0,0 +1,709 @@
-+// Licensed to the .NET Foundation under one or more agreements.
-+// The .NET Foundation licenses this file to you under the MIT license.
-+
-+/*++
-+
-+Module Name:
-+
-+ mono-cgroup.cpp
-+
-+Abstract:
-+ Read the memory limit for the current process
-+--*/
-+#ifdef __FreeBSD__
-+#define _WITH_GETLINE
-+#endif
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#if defined(__APPLE__) || defined(__FreeBSD__)
-+#include
-+#include
-+#else
-+#include
-+#endif
-+#include
-+#include
-+
-+#ifndef SIZE_T_MAX
-+# define SIZE_T_MAX (~(size_t)0)
-+#endif
-+
-+#define CGROUP2_SUPER_MAGIC 0x63677270
-+#define TMPFS_MAGIC 0x01021994
-+
-+#define PROC_MOUNTINFO_FILENAME "/proc/self/mountinfo"
-+#define PROC_CGROUP_FILENAME "/proc/self/cgroup"
-+#define PROC_STATM_FILENAME "/proc/self/statm"
-+#define CGROUP1_MEMORY_LIMIT_FILENAME "/memory.limit_in_bytes"
-+#define CGROUP2_MEMORY_LIMIT_FILENAME "/memory.max"
-+#define CGROUP_MEMORY_STAT_FILENAME "/memory.stat"
-+
-+static void initialize(void);
-+static gboolean readMemoryValueFromFile(const char *, guint64 *);
-+static gboolean getPhysicalMemoryLimit(guint64 *);
-+static gboolean getPhysicalMemoryUsage(size_t *);
-+static int findCGroupVersion(void);
-+static gboolean isCGroup1MemorySubsystem(const char *);
-+static char *findCGroupPath(gboolean (*is_subsystem)(const char *));
-+static void findHierarchyMount(gboolean (*is_subsystem)(const char *), char **, char **);
-+static char *findCGroupPathForSubsystem(gboolean (*is_subsystem)(const char *));
-+static gboolean getCGroupMemoryLimit(guint64 *, const char *);
-+static gboolean getCGroupMemoryUsage(size_t *);
-+static size_t getPhysicalMemoryTotal(guint64);
-+
-+size_t getRestrictedPhysicalMemoryLimit(void);
-+gboolean getPhysicalMemoryUsed(size_t *);
-+size_t getPhysicalMemoryAvail(void);
-+
-+// the cgroup version number or 0 to indicate cgroups are not found or not enabled
-+static int s_cgroup_version;
-+
-+static char *s_memory_cgroup_path = NULL;
-+
-+static const char *s_mem_stat_key_names[4];
-+static size_t s_mem_stat_key_lengths[4];
-+static size_t s_mem_stat_n_keys = 0;
-+static long pageSize;
-+
-+/**
-+ * @initialize
-+ *
-+ * Initialize variables used by the calculation routines.
-+ */
-+static void
-+initialize()
-+{
-+ s_cgroup_version = findCGroupVersion();
-+ s_memory_cgroup_path = findCGroupPath(s_cgroup_version == 1 ? &isCGroup1MemorySubsystem : NULL);
-+
-+ if (s_cgroup_version == 1) {
-+ s_mem_stat_n_keys = 4;
-+ s_mem_stat_key_names[0] = "total_inactive_anon ";
-+ s_mem_stat_key_names[1] = "total_active_anon ";
-+ s_mem_stat_key_names[2] = "total_dirty ";
-+ s_mem_stat_key_names[3] = "total_unevictable ";
-+ } else {
-+ s_mem_stat_n_keys = 3;
-+ s_mem_stat_key_names[0] = "anon ";
-+ s_mem_stat_key_names[1] = "file_dirty ";
-+ s_mem_stat_key_names[2] = "unevictable ";
-+ }
-+
-+ for (size_t i = 0; i < s_mem_stat_n_keys; i++)
-+ s_mem_stat_key_lengths[i] = strlen(s_mem_stat_key_names[i]);
-+
-+ pageSize = sysconf(_SC_PAGE_SIZE);
-+}
-+
-+/**
-+ * @readMemoryValueFromFile
-+ *
-+ * @param[in] filename - name of file containing value
-+ * @param[out] val - pointer to the result area
-+ * @returns True or False depending if value was found
-+ *
-+ * Read a value from a specified /sys/fs/cgroup/memory file
-+ */
-+static gboolean
-+readMemoryValueFromFile(const char* filename, guint64* val)
-+{
-+ gboolean result = FALSE;
-+ char *line = NULL;
-+ size_t lineLen = 0;
-+ char *endptr = NULL;
-+ guint64 num = 0, multiplier;
-+ FILE *file = NULL;
-+
-+ if (val == NULL) {
-+ file = fopen(filename, "r");
-+ if (file != NULL) {
-+ if (getline(&line, &lineLen, file) != -1) {
-+ errno = 0;
-+ num = strtoull(line, &endptr, 0);
-+ if (line != endptr && errno == 0) {
-+ multiplier = 1;
-+
-+ switch (*endptr)
-+ {
-+ case 'g':
-+ case 'G':
-+ multiplier = 1024;
-+ case 'm':
-+ case 'M':
-+ multiplier = multiplier * 1024;
-+ case 'k':
-+ case 'K':
-+ multiplier = multiplier * 1024;
-+ }
-+
-+ *val = num * multiplier;
-+ result = TRUE;
-+ if (*val / multiplier != num)
-+ result = FALSE;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (file)
-+ fclose(file);
-+ free(line);
-+ return result;
-+}
-+
-+/**
-+ * @getPhysicalMemoryLimit
-+ *
-+ * @param[out] val - pointer to the result area
-+ * @returns True or False depending if a limit was found
-+ *
-+ * Interrogate the cgroup memory values to determine if there's
-+ * a limit on physical memory.
-+ */
-+static gboolean
-+getPhysicalMemoryLimit(guint64 *val)
-+{
-+ if (s_mem_stat_n_keys == 0)
-+ initialize();
-+
-+ if (s_cgroup_version == 0)
-+ return FALSE;
-+ else if (s_cgroup_version == 1)
-+ return getCGroupMemoryLimit(val, CGROUP1_MEMORY_LIMIT_FILENAME);
-+ else if (s_cgroup_version == 2)
-+ return getCGroupMemoryLimit(val, CGROUP2_MEMORY_LIMIT_FILENAME);
-+ else {
-+ g_assert(!"Unknown cgroup version.");
-+ return FALSE;
-+ }
-+}
-+
-+/**
-+ * @getPhysicalMemoryUsage
-+ *
-+ * @param[out] val - pointer to the result area
-+ * @returns True or False depending if a usage value was found
-+ *
-+ * Interrogate the cgroup memory values to determine how much
-+ * memory is in use.
-+ */
-+static gboolean
-+getPhysicalMemoryUsage(size_t *val)
-+{
-+ if (s_cgroup_version == 0)
-+ return FALSE;
-+ else if (s_cgroup_version == 1)
-+ return getCGroupMemoryUsage(val);
-+ else if (s_cgroup_version == 2)
-+ return getCGroupMemoryUsage(val);
-+ else {
-+ g_assert(!"Unknown cgroup version.");
-+ return FALSE;
-+ }
-+}
-+
-+/**
-+ * @findGroupVersion
-+ *
-+ * @returns cgroup version
-+ *
-+ * Inspect the /sys/fs/cgroup hierachy to determine what version of
-+ * group we are using
-+ */
-+static int
-+findCGroupVersion()
-+{
-+ // It is possible to have both cgroup v1 and v2 enabled on a system.
-+ // Most non-bleeding-edge Linux distributions fall in this group. We
-+ // look at the file system type of /sys/fs/cgroup to determine which
-+ // one is the default. For more details, see:
-+ // https://systemd.io/CGROUP_DELEGATION/#three-different-tree-setups-
-+ // We dont care about the difference between the "legacy" and "hybrid"
-+ // modes because both of those involve cgroup v1 controllers managing
-+ // resources.
-+
-+
-+ struct statfs stats;
-+ int result = statfs("/sys/fs/cgroup", &stats);
-+ if (result != 0)
-+ return 0;
-+
-+ switch (stats.f_type) {
-+ case TMPFS_MAGIC: return 1;
-+ case CGROUP2_SUPER_MAGIC: return 2;
-+ default:
-+ g_assert(!"Unexpected file system type for /sys/fs/cgroup");
-+ return 0;
-+ }
-+}
-+
-+/**
-+ * @isCGroup1MemorySubsystem
-+ *
-+ * @param[in] strTok - Token for comparison
-+ * @returns True if token matches "memory"
-+ *
-+ * Check if we've found the memory component of /sys/fs/cgroup
-+ */
-+static gboolean
-+isCGroup1MemorySubsystem(const char *strTok)
-+{
-+ return strcmp("memory", strTok) == 0;
-+}
-+
-+/**
-+ * @findCGroupPath
-+ *
-+ * @param[in] is_subsystem - Function used to compare tokens
-+ * @returns Path to cgroup
-+ *
-+ * Navigate the /sys/fs/cgroup to try and find the correct cgroup path
-+ */
-+static char *
-+findCGroupPath(gboolean (*is_subsystem)(const char *))
-+{
-+ char *cgroup_path = NULL;
-+ char *hierarchy_mount = NULL;
-+ char *hierarchy_root = NULL;
-+ char *cgroup_path_relative_to_mount = NULL;
-+ size_t common_path_prefix_len;
-+
-+ findHierarchyMount(is_subsystem, &hierarchy_mount, &hierarchy_root);
-+ if (hierarchy_mount != NULL && hierarchy_root != NULL) {
-+
-+ cgroup_path_relative_to_mount = findCGroupPathForSubsystem(is_subsystem);
-+ if (cgroup_path_relative_to_mount != NULL) {
-+
-+ cgroup_path = (char*)malloc(strlen(hierarchy_mount) + strlen(cgroup_path_relative_to_mount) + 1);
-+ if (cgroup_path != NULL) {
-+
-+ strcpy(cgroup_path, hierarchy_mount);
-+ // For a host cgroup, we need to append the relative path.
-+ // The root and cgroup path can share a common prefix of the path that should not be appended.
-+ // Example 1 (docker):
-+ // hierarchy_mount: /sys/fs/cgroup/cpu
-+ // hierarchy_root: /docker/87ee2de57e51bc75175a4d2e81b71d162811b179d549d6601ed70b58cad83578
-+ // cgroup_path_relative_to_mount: /docker/87ee2de57e51bc75175a4d2e81b71d162811b179d549d6601ed70b58cad83578/my_named_cgroup
-+ // append do the cgroup_path: /my_named_cgroup
-+ // final cgroup_path: /sys/fs/cgroup/cpu/my_named_cgroup
-+ //
-+ // Example 2 (out of docker)
-+ // hierarchy_mount: /sys/fs/cgroup/cpu
-+ // hierarchy_root: /
-+ // cgroup_path_relative_to_mount: /my_named_cgroup
-+ // append do the cgroup_path: /my_named_cgroup
-+ // final cgroup_path: /sys/fs/cgroup/cpu/my_named_cgroup
-+ common_path_prefix_len = strlen(hierarchy_root);
-+ if ((common_path_prefix_len == 1) ||
-+ (strncmp(hierarchy_root, cgroup_path_relative_to_mount, common_path_prefix_len) != 0))
-+ common_path_prefix_len = 0;
-+
-+ g_assert((cgroup_path_relative_to_mount[common_path_prefix_len] == '/') ||
-+ (cgroup_path_relative_to_mount[common_path_prefix_len] == '\0'));
-+
-+ strcat(cgroup_path, cgroup_path_relative_to_mount + common_path_prefix_len);
-+ }
-+ }
-+ }
-+
-+ free(hierarchy_mount);
-+ free(hierarchy_root);
-+ free(cgroup_path_relative_to_mount);
-+ return cgroup_path;
-+}
-+
-+/**
-+ * @findHierarchyMount
-+ *
-+ * @param[in] is_subsystem - Comparison function
-+ * @param[out] pmountpath -
-+ * @param[out] pmountroot -
-+ *
-+ * Check the /proc filesystem to determine the root and mount path of /sys/fs/cgroup data
-+ */
-+static void
-+findHierarchyMount(gboolean (*is_subsystem)(const char *), char** pmountpath, char** pmountroot)
-+{
-+ char *line = NULL;
-+ size_t lineLen = 0, maxLineLen = 0;
-+ char *filesystemType = NULL;
-+ char *options = NULL;
-+ char *mountpath = NULL;
-+ char *mountroot = NULL;
-+
-+ FILE *mountinfofile = fopen(PROC_MOUNTINFO_FILENAME, "r");
-+ if (mountinfofile == NULL)
-+ goto done;
-+
-+ while (getline(&line, &lineLen, mountinfofile) != -1) {
-+ if (filesystemType == NULL || lineLen > maxLineLen) {
-+ free(filesystemType);
-+ filesystemType = NULL;
-+ free(options);
-+ options = NULL;
-+ filesystemType = (char*)malloc(lineLen+1);
-+ if (filesystemType == NULL)
-+ goto done;
-+ options = (char*)malloc(lineLen+1);
-+ if (options == NULL)
-+ goto done;
-+ maxLineLen = lineLen;
-+ }
-+
-+ char *separatorChar = strstr(line, " - ");
-+
-+ // See man page of proc to get format for /proc/self/mountinfo file
-+ int sscanfRet = sscanf(separatorChar,
-+ " - %s %*s %s",
-+ filesystemType,
-+ options);
-+ if (sscanfRet != 2) {
-+ g_assert(!"Failed to parse mount info file contents with sscanf.");
-+ goto done;
-+ }
-+
-+ if (strncmp(filesystemType, "cgroup", 6) == 0) {
-+ gboolean isSubsystemMatch = is_subsystem == NULL;
-+ if (!isSubsystemMatch) {
-+ char *context = NULL;
-+ char *strTok = strtok_r(options, ",", &context);
-+ while (!isSubsystemMatch && strTok != NULL)
-+ {
-+ isSubsystemMatch = is_subsystem(strTok);
-+ strTok = strtok_r(NULL, ",", &context);
-+ }
-+ }
-+ if (isSubsystemMatch) {
-+ mountpath = (char*)malloc(lineLen+1);
-+ if (mountpath == NULL)
-+ goto done;
-+ mountroot = (char*)malloc(lineLen+1);
-+ if (mountroot == NULL)
-+ goto done;
-+
-+ sscanfRet = sscanf(line,
-+ "%*s %*s %*s %s %s ",
-+ mountroot,
-+ mountpath);
-+ if (sscanfRet != 2)
-+ g_assert(!"Failed to parse mount info file contents with sscanf.");
-+
-+ // assign the output arguments and clear the locals so we don't free them.
-+ *pmountpath = mountpath;
-+ *pmountroot = mountroot;
-+ mountpath = mountroot = NULL;
-+ }
-+ }
-+ }
-+done:
-+ free(mountpath);
-+ free(mountroot);
-+ free(filesystemType);
-+ free(options);
-+ free(line);
-+ if (mountinfofile)
-+ fclose(mountinfofile);
-+}
-+
-+/**
-+ * @findCGroupPathForSubsystem
-+ *
-+ * @param[in] is_subsystem - Comparison function
-+ * @returns cgroup path for the memory subsystem
-+ *
-+ * Check the /proc filesystem to determine the root and mount path of /sys/fs/cgroup data
-+ */
-+static char *
-+findCGroupPathForSubsystem(gboolean (*is_subsystem)(const char *))
-+{
-+ char *line = NULL;
-+ size_t lineLen = 0;
-+ size_t maxLineLen = 0;
-+ char *subsystem_list = NULL;
-+ char *cgroup_path = NULL;
-+ gboolean result = FALSE;
-+
-+ FILE *cgroupfile = fopen(PROC_CGROUP_FILENAME, "r");
-+ if (cgroupfile == NULL)
-+ goto done;
-+
-+ while (!result && getline(&line, &lineLen, cgroupfile) != -1) {
-+ if (subsystem_list == NULL || lineLen > maxLineLen) {
-+ free(subsystem_list);
-+ subsystem_list = NULL;
-+ free(cgroup_path);
-+ cgroup_path = NULL;
-+ subsystem_list = (char*)malloc(lineLen+1);
-+ if (subsystem_list == NULL)
-+ goto done;
-+ cgroup_path = (char*)malloc(lineLen+1);
-+ if (cgroup_path == NULL)
-+ goto done;
-+ maxLineLen = lineLen;
-+ }
-+
-+ if (s_cgroup_version == 1) {
-+ // See man page of proc to get format for /proc/self/cgroup file
-+ int sscanfRet = sscanf(line,
-+ "%*[^:]:%[^:]:%s",
-+ subsystem_list,
-+ cgroup_path);
-+ if (sscanfRet != 2) {
-+ g_assert(!"Failed to parse cgroup info file contents with sscanf.");
-+ goto done;
-+ }
-+
-+ char* context = NULL;
-+ char* strTok = strtok_r(subsystem_list, ",", &context);
-+ while (strTok != NULL) {
-+ if (is_subsystem(strTok)) {
-+ result = TRUE;
-+ break;
-+ }
-+ strTok = strtok_r(NULL, ",", &context);
-+ }
-+ } else if (s_cgroup_version == 2) {
-+ // See https://www.kernel.org/doc/Documentation/cgroup-v2.txt
-+ // Look for a "0::/some/path"
-+ int sscanfRet = sscanf(line,
-+ "0::%s",
-+ cgroup_path);
-+ if (sscanfRet == 1)
-+ {
-+ result = TRUE;
-+ }
-+ } else {
-+ g_assert(!"Unknown cgroup version in mountinfo.");
-+ goto done;
-+ }
-+ }
-+done:
-+ free(subsystem_list);
-+ if (!result) {
-+ free(cgroup_path);
-+ cgroup_path = NULL;
-+ }
-+ free(line);
-+ if (cgroupfile)
-+ fclose(cgroupfile);
-+ return cgroup_path;
-+}
-+
-+/**
-+ * @getCGroupMemoryLimit
-+ *
-+ * @param[out] val - Memory limit
-+ * @param[in] filename - name of file from which to extract limit
-+ * @returns True if value found
-+ *
-+ * Extract memory limit from specified /sys/fs/cgroup/memory file
-+ */
-+static gboolean
-+getCGroupMemoryLimit(guint64 *val, const char *filename)
-+{
-+ if (s_memory_cgroup_path == NULL)
-+ return FALSE;
-+
-+ char* mem_limit_filename = NULL;
-+ if (asprintf(&mem_limit_filename, "%s%s", s_memory_cgroup_path, filename) < 0)
-+ return FALSE;
-+
-+ gboolean result = readMemoryValueFromFile(mem_limit_filename, val);
-+ free(mem_limit_filename);
-+ return result;
-+}
-+
-+/**
-+ * @getCGroupMemoryUsage
-+ *
-+ * @param[out] val - Memory limit
-+ * @returns True if value found
-+ *
-+ * Extract memory usage from /sys/fs/cgroup/memory.stat file
-+ */
-+static gboolean
-+getCGroupMemoryUsage(size_t *val)
-+{
-+ if (s_memory_cgroup_path == NULL)
-+ return FALSE;
-+
-+ char *stat_filename = NULL;
-+ if (asprintf(&stat_filename, "%s%s", s_memory_cgroup_path, CGROUP_MEMORY_STAT_FILENAME) < 0)
-+ return FALSE;
-+
-+ FILE *stat_file = fopen(stat_filename, "r");
-+ free(stat_filename);
-+ if (stat_file == NULL)
-+ return FALSE;
-+
-+ char *line = NULL;
-+ size_t lineLen = 0;
-+ size_t readValues = 0;
-+ char *endptr;
-+
-+ *val = 0;
-+ while (getline(&line, &lineLen, stat_file) != -1 && readValues < s_mem_stat_n_keys) {
-+ for (size_t i = 0; i < s_mem_stat_n_keys; i++) {
-+ if (strncmp(line, s_mem_stat_key_names[i], s_mem_stat_key_lengths[i]) == 0) {
-+ errno = 0;
-+ const char *startptr = line + s_mem_stat_key_lengths[i];
-+ *val += strtoll(startptr, &endptr, 10);
-+ if (endptr != startptr && errno == 0)
-+ readValues++;
-+
-+ break;
-+ }
-+ }
-+ }
-+
-+ fclose(stat_file);
-+ free(line);
-+
-+ if (readValues == s_mem_stat_n_keys)
-+ return TRUE;
-+
-+ return FALSE;
-+}
-+
-+/**
-+ * @getRestrictedPhysicalMemoryLimit
-+ *
-+ * @returns Physical memory limit
-+ *
-+ * Determine if there are any limits on memory and return the value
-+ * if so. Zero represents no limit.
-+ */
-+size_t
-+getRestrictedPhysicalMemoryLimit()
-+{
-+ guint64 physical_memory_limit = 0;
-+
-+ if (s_mem_stat_n_keys == 0)
-+ initialize();
-+
-+ if (!getPhysicalMemoryLimit(&physical_memory_limit))
-+ return 0;
-+
-+ // If there's no memory limit specified on the container this
-+ // actually returns 0x7FFFFFFFFFFFF000 (2^63-1 rounded down to
-+ // 4k which is a common page size). So we know we are not
-+ // running in a memory restricted environment.
-+ if (physical_memory_limit > 0x7FFFFFFF00000000)
-+ return 0;
-+
-+ return (getPhysicalMemoryTotal(physical_memory_limit));
-+}
-+
-+/**
-+ * @getPhysicalMemoryTotal
-+ *
-+ * @param[in] physical_memory_limit - The max memory on the system
-+ * @returns Physical memory total
-+ *
-+ * Check the input limit against any system limits or actual memory on system
-+ */
-+static size_t
-+getPhysicalMemoryTotal(size_t physical_memory_limit)
-+{
-+ struct rlimit curr_rlimit;
-+ size_t rlimit_soft_limit = (size_t)RLIM_INFINITY;
-+ if (getrlimit(RLIMIT_AS, &curr_rlimit) == 0)
-+ rlimit_soft_limit = curr_rlimit.rlim_cur;
-+ physical_memory_limit = (physical_memory_limit < rlimit_soft_limit) ?
-+ physical_memory_limit : rlimit_soft_limit;
-+
-+ // Ensure that limit is not greater than real memory size
-+ long pages = sysconf(_SC_PHYS_PAGES);
-+ if (pages != -1) {
-+ if (pageSize != -1) {
-+ physical_memory_limit = (physical_memory_limit < (size_t)pages * pageSize) ?
-+ physical_memory_limit : (size_t)pages * pageSize;
-+ }
-+ }
-+
-+ if (physical_memory_limit > ULONG_MAX) {
-+ // It is observed in practice when the memory is unrestricted, Linux control
-+ // group returns a physical limit that is bigger than the address space
-+ return ULONG_MAX;
-+ } else
-+ return (size_t)physical_memory_limit;
-+}
-+
-+/**
-+ * @getPhysicalMemoryUsed
-+ *
-+ * @param[out] val - pointer to the memory usage value
-+ * @returns True if we are able to determine usage
-+ *
-+ * Determine the amount of memory in use
-+ */
-+gboolean
-+getPhysicalMemoryUsed(size_t *val)
-+{
-+ gboolean result = FALSE;
-+ size_t linelen;
-+ char *line = NULL;
-+
-+ if (val == NULL)
-+ return FALSE;
-+
-+ // Linux uses cgroup usage to trigger oom kills.
-+ if (getPhysicalMemoryUsage(val))
-+ return TRUE;
-+
-+ // process resident set size.
-+ FILE* file = fopen(PROC_STATM_FILENAME, "r");
-+ if (file != NULL && getline(&line, &linelen, file) != -1) {
-+ char* context = NULL;
-+ char* strTok = strtok_r(line, " ", &context);
-+ strTok = strtok_r(NULL, " ", &context);
-+
-+ errno = 0;
-+ *val = strtoull(strTok, NULL, 0);
-+ if (errno == 0) {
-+ if (pageSize != -1) {
-+ *val = *val * pageSize;
-+ result = TRUE;
-+ }
-+ }
-+ }
-+
-+ if (file)
-+ fclose(file);
-+ free(line);
-+ return result;
-+}
-+
-+/**
-+ * @getPhysicalMemoryAvail
-+ *
-+ * @returns Amount of memory available
-+ *
-+ * Determine the amount of memory available by examininig any limits and
-+ * checking what memory is in use.
-+ */
-+size_t
-+getPhysicalMemoryAvail()
-+{
-+ size_t max, used, avail, sysAvail;
-+
-+ max = getRestrictedPhysicalMemoryLimit();
-+
-+ if (max == 0)
-+ max = getPhysicalMemoryTotal(ULONG_MAX);
-+
-+ if (getPhysicalMemoryUsed(&used))
-+ avail = max - used;
-+ else
-+ avail = max;
-+
-+ sysAvail = sysconf(_SC_AVPHYS_PAGES) * pageSize;
-+ return (avail < sysAvail ? avail : sysAvail);
-+}
-Index: a/src/mono/mono/utils/CMakeLists.txt
-===================================================================
---- a/src/mono/mono/utils/CMakeLists.txt
-+++ b/src/mono/mono/utils/CMakeLists.txt
-@@ -32,6 +32,7 @@ set(utils_common_sources
- mono-sha1.c
- mono-logger.c
- mono-logger-internals.h
-+ mono-cgroup.c
- mono-codeman.c
- mono-counters.c
- mono-compiler.h
diff --git a/SOURCES/runtime-mono-remove-ilstrip.patch b/SOURCES/runtime-mono-remove-ilstrip.patch
new file mode 100644
index 0000000..9a711f8
--- /dev/null
+++ b/SOURCES/runtime-mono-remove-ilstrip.patch
@@ -0,0 +1,33 @@
+diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj
+index 724b704f864..3dabdc81dae 100644
+--- a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj
++++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj
+@@ -6,7 +6,7 @@
+
+
+
+-
++
+
+
+
+@@ -15,7 +15,7 @@
+
+
+
+-
++
+
+
+
+diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props
+index 8a7ede79242..cfd515eeca9 100644
+--- a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props
++++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props
+@@ -1,5 +1,5 @@
+
+-
++
+
+
+
diff --git a/SOURCES/runtime-no-shared-compilation.patch b/SOURCES/runtime-no-shared-compilation.patch
deleted file mode 100644
index fefe89e..0000000
--- a/SOURCES/runtime-no-shared-compilation.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: source-build-tarball/src/runtime.826f81a11ad17f415668fe1cb934bdaf00d36ea2/Directory.Build.props
-===================================================================
---- a/Directory.Build.props
-+++ b/Directory.Build.props
-@@ -7,6 +7,7 @@
- For offline builds we still set OfficialBuildId but we need to build all the packages for a single
- leg only, so we also take DotNetBuildFromSource into account. -->
- true
-+ false
-
-
-
diff --git a/SOURCES/sdk-22373-portablerid.patch b/SOURCES/sdk-22373-portablerid.patch
new file mode 100644
index 0000000..8b39eb3
--- /dev/null
+++ b/SOURCES/sdk-22373-portablerid.patch
@@ -0,0 +1,22 @@
+From 499fcf6e3b0e4b01a9c340a06f00cfc3e1fcc5d2 Mon Sep 17 00:00:00 2001
+From: Tom Deseyn
+Date: Tue, 5 Oct 2021 09:04:14 +0200
+Subject: [PATCH] Use the portable rid for --use-current-runtime.
+
+---
+ .../targets/Microsoft.NET.RuntimeIdentifierInference.targets | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
+index 17308aa9160..e764b2d9845 100644
+--- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
++++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
+@@ -62,7 +62,7 @@ Copyright (c) .NET Foundation. All rights reserved.
+
+
+
+- $(NETCoreSdkRuntimeIdentifier)
++ $(NETCoreSdkPortableRuntimeIdentifier)
+
+
+
diff --git a/SOURCES/sdk-23080-userlocal-workload.patch b/SOURCES/sdk-23080-userlocal-workload.patch
new file mode 100644
index 0000000..e874f20
--- /dev/null
+++ b/SOURCES/sdk-23080-userlocal-workload.patch
@@ -0,0 +1,23 @@
+From 6e57b7c1d7f9b5ce82eef106d465af81382794b3 Mon Sep 17 00:00:00 2001
+From: Tom Deseyn
+Date: Wed, 15 Dec 2021 15:06:51 +0100
+Subject: [PATCH] userlocal detection: also force last digits to zero for
+ non-preview versions.
+
+---
+ src/Common/WorkloadFileBasedInstall.cs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Common/WorkloadFileBasedInstall.cs b/src/Common/WorkloadFileBasedInstall.cs
+index f0d82c1fa9..0b27b0939c 100644
+--- a/src/Common/WorkloadFileBasedInstall.cs
++++ b/src/Common/WorkloadFileBasedInstall.cs
+@@ -21,7 +21,7 @@ internal static void SetUserLocal(string dotnetDir, string sdkFeatureBand)
+
+ private static string GetUserInstallFilePath(string dotnetDir, string sdkFeatureBand)
+ {
+- if (sdkFeatureBand.Contains("-"))
++ if (sdkFeatureBand.Contains("-") || !sdkFeatureBand.EndsWith("00", StringComparison.Ordinal))
+ {
+ // The user passed in the sdk version. Derive the feature band version.
+ if (!Version.TryParse(sdkFeatureBand.Split('-')[0], out var sdkVersionParsed))
diff --git a/SOURCES/sdk-enable-preview.patch b/SOURCES/sdk-enable-preview.patch
deleted file mode 100644
index 7a452a2..0000000
--- a/SOURCES/sdk-enable-preview.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/eng/SourceBuild.props
-+++ b/eng/SourceBuild.props
-@@ -8,6 +8,7 @@
-
-
- $(InnerBuildArgs) /p:Projects="$(InnerSourceBuildRepoRoot)\source-build.slnf"
-+ $(InnerBuildArgs) /p:EnablePreviewFeatures=true
-
-
-
diff --git a/SOURCES/source-build-reference-packages-no-shared-compilation.patch b/SOURCES/source-build-reference-packages-no-shared-compilation.patch
deleted file mode 100644
index b2932d9..0000000
--- a/SOURCES/source-build-reference-packages-no-shared-compilation.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: a/src/Directory.Build.props
-===================================================================
---- a/src/Directory.Build.props
-+++ b/src/Directory.Build.props
-@@ -9,6 +9,7 @@
-
- true
- true
-+ false
-