From 1b492493a52ad1e9d31a441a168b18bbbf91a070 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 4 Feb 2025 13:00:51 -0600 Subject: [PATCH 1/5] make sure the memorystream is disposed --- src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs index a71e2b69321f7d..fcf0dc87203898 100644 --- a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs +++ b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs @@ -305,33 +305,32 @@ private Dictionary ComputeMethodBodyUsage(MetadataReader mr, StreamRea private void CreateTrimmedAssembly(PEReader peReader, string trimmedAssemblyFilePath, FileStream fs, Dictionary methodBodyUses) { using FileStream os = File.Open(trimmedAssemblyFilePath, FileMode.Create); - { - fs.Position = 0; - MemoryStream memStream = new MemoryStream((int)fs.Length); - fs.CopyTo(memStream); + using MemoryStream memStream = new MemoryStream((int)fs.Length); + + fs.Position = 0; + fs.CopyTo(memStream); - foreach (var kvp in methodBodyUses) + foreach (var kvp in methodBodyUses) + { + int rva = kvp.Key; + int count = kvp.Value; + if (count == 0) { - int rva = kvp.Key; - int count = kvp.Value; - if (count == 0) - { - int methodSize = ComputeMethodSize(peReader, rva); - int actualLoc = ComputeMethodHash(peReader, rva); - int headerSize = ComputeMethodHeaderSize(memStream, actualLoc); - if (headerSize == 1) //Set code size to zero for TinyFormat - SetCodeSizeToZeroForTiny(ref memStream, actualLoc); - ZeroOutMethodBody(ref memStream, methodSize, actualLoc, headerSize); - } - else if (count < 0) - { - Log.LogError($"Method usage count is less than zero for rva: {rva}."); - } + int methodSize = ComputeMethodSize(peReader, rva); + int actualLoc = ComputeMethodHash(peReader, rva); + int headerSize = ComputeMethodHeaderSize(memStream, actualLoc); + if (headerSize == 1) //Set code size to zero for TinyFormat + SetCodeSizeToZeroForTiny(ref memStream, actualLoc); + ZeroOutMethodBody(ref memStream, methodSize, actualLoc, headerSize); + } + else if (count < 0) + { + Log.LogError($"Method usage count is less than zero for rva: {rva}."); } - - memStream.Position = 0; - memStream.CopyTo(os); } + + memStream.Position = 0; + memStream.CopyTo(os); } private static int ComputeMethodSize(PEReader peReader, int rva) => peReader.GetMethodBody(rva).Size; From 20b70959851b64d39f62f37ce9c0670f830926d6 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 4 Feb 2025 13:23:54 -0600 Subject: [PATCH 2/5] more cleanup --- src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs index fcf0dc87203898..54cfe4b34db3f4 100644 --- a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs +++ b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs @@ -320,8 +320,8 @@ private void CreateTrimmedAssembly(PEReader peReader, string trimmedAssemblyFile int actualLoc = ComputeMethodHash(peReader, rva); int headerSize = ComputeMethodHeaderSize(memStream, actualLoc); if (headerSize == 1) //Set code size to zero for TinyFormat - SetCodeSizeToZeroForTiny(ref memStream, actualLoc); - ZeroOutMethodBody(ref memStream, methodSize, actualLoc, headerSize); + SetCodeSizeToZeroForTiny(memStream, actualLoc); + ZeroOutMethodBody(memStream, methodSize, actualLoc, headerSize); } else if (count < 0) { @@ -350,17 +350,15 @@ private static int ComputeMethodHeaderSize(MemoryStream memStream, int actualLoc return (headerFlag == 2 ? 1 : 4); } - private static void SetCodeSizeToZeroForTiny(ref MemoryStream memStream, int actualLoc) + private static void SetCodeSizeToZeroForTiny(MemoryStream memStream, int actualLoc) { memStream.Position = actualLoc; - byte[] header = {0b10}; - memStream.Write(header, 0, 1); + memStream.WriteByte(0b10); } - private static void ZeroOutMethodBody(ref MemoryStream memStream, int methodSize, int actualLoc, int headerSize) + private static void ZeroOutMethodBody(MemoryStream memStream, int methodSize, int actualLoc, int headerSize) { memStream.Position = actualLoc + headerSize; - byte[] zeroBuffer; zeroBuffer = ArrayPool.Shared.Rent(methodSize); Array.Clear(zeroBuffer, 0, zeroBuffer.Length); From f2a358ec4751e7fc9180ab9a68c56ce1e8509931 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 5 Feb 2025 10:16:31 -0600 Subject: [PATCH 3/5] Just write to the filestream directly --- src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs index 54cfe4b34db3f4..5c3d28ef9f273c 100644 --- a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs +++ b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs @@ -305,10 +305,10 @@ private Dictionary ComputeMethodBodyUsage(MetadataReader mr, StreamRea private void CreateTrimmedAssembly(PEReader peReader, string trimmedAssemblyFilePath, FileStream fs, Dictionary methodBodyUses) { using FileStream os = File.Open(trimmedAssemblyFilePath, FileMode.Create); - using MemoryStream memStream = new MemoryStream((int)fs.Length); fs.Position = 0; - fs.CopyTo(memStream); + fs.CopyTo(os); + fs.Flush(); foreach (var kvp in methodBodyUses) { @@ -318,19 +318,16 @@ private void CreateTrimmedAssembly(PEReader peReader, string trimmedAssemblyFile { int methodSize = ComputeMethodSize(peReader, rva); int actualLoc = ComputeMethodHash(peReader, rva); - int headerSize = ComputeMethodHeaderSize(memStream, actualLoc); + int headerSize = ComputeMethodHeaderSize(fs, actualLoc); if (headerSize == 1) //Set code size to zero for TinyFormat - SetCodeSizeToZeroForTiny(memStream, actualLoc); - ZeroOutMethodBody(memStream, methodSize, actualLoc, headerSize); + SetCodeSizeToZeroForTiny(os, actualLoc); + ZeroOutMethodBody(os, methodSize, actualLoc, headerSize); } else if (count < 0) { Log.LogError($"Method usage count is less than zero for rva: {rva}."); } } - - memStream.Position = 0; - memStream.CopyTo(os); } private static int ComputeMethodSize(PEReader peReader, int rva) => peReader.GetMethodBody(rva).Size; @@ -342,27 +339,29 @@ private static int ComputeMethodHash(PEReader peReader, int rva) return (peReader.PEHeaders.SectionHeaders[sectionIndex].PointerToRawData + relativeOffset); } - private static int ComputeMethodHeaderSize(MemoryStream memStream, int actualLoc) + private static int ComputeMethodHeaderSize(Stream stream, int actualLoc) { - memStream.Position = actualLoc; - int firstbyte = memStream.ReadByte(); + stream.Position = actualLoc; + int firstbyte = stream.ReadByte(); int headerFlag = firstbyte & 0b11; return (headerFlag == 2 ? 1 : 4); } - private static void SetCodeSizeToZeroForTiny(MemoryStream memStream, int actualLoc) + private static void SetCodeSizeToZeroForTiny(Stream stream, int actualLoc) { - memStream.Position = actualLoc; - memStream.WriteByte(0b10); + stream.Position = actualLoc; + stream.WriteByte(0b10); + stream.Flush(); } - private static void ZeroOutMethodBody(MemoryStream memStream, int methodSize, int actualLoc, int headerSize) + private static void ZeroOutMethodBody(Stream stream, int methodSize, int actualLoc, int headerSize) { - memStream.Position = actualLoc + headerSize; + stream.Position = actualLoc + headerSize; byte[] zeroBuffer; - zeroBuffer = ArrayPool.Shared.Rent(methodSize); + zeroBuffer = ArrayPool.Shared.Rent(methodSize - headerSize); Array.Clear(zeroBuffer, 0, zeroBuffer.Length); - memStream.Write(zeroBuffer, 0, methodSize - headerSize); + stream.Write(zeroBuffer, 0, zeroBuffer.Length); + stream.Flush(); ArrayPool.Shared.Return(zeroBuffer); } From f1fe0c666f1741477ea3b86b2898830876e94439 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 5 Feb 2025 11:28:50 -0600 Subject: [PATCH 4/5] Remove explicit flushes --- src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs index 5c3d28ef9f273c..b8ec9f0695f00a 100644 --- a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs +++ b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs @@ -308,7 +308,6 @@ private void CreateTrimmedAssembly(PEReader peReader, string trimmedAssemblyFile fs.Position = 0; fs.CopyTo(os); - fs.Flush(); foreach (var kvp in methodBodyUses) { @@ -351,7 +350,6 @@ private static void SetCodeSizeToZeroForTiny(Stream stream, int actualLoc) { stream.Position = actualLoc; stream.WriteByte(0b10); - stream.Flush(); } private static void ZeroOutMethodBody(Stream stream, int methodSize, int actualLoc, int headerSize) @@ -361,7 +359,6 @@ private static void ZeroOutMethodBody(Stream stream, int methodSize, int actualL zeroBuffer = ArrayPool.Shared.Rent(methodSize - headerSize); Array.Clear(zeroBuffer, 0, zeroBuffer.Length); stream.Write(zeroBuffer, 0, zeroBuffer.Length); - stream.Flush(); ArrayPool.Shared.Return(zeroBuffer); } From 3c550c156d44bf33f89eb0250a7820ed0fbcbf57 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 5 Feb 2025 11:42:48 -0600 Subject: [PATCH 5/5] just write bytes --- src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs index b8ec9f0695f00a..288c7ef3711c8a 100644 --- a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs +++ b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs @@ -15,7 +15,6 @@ using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; -using System.Buffers; using System.Collections.Concurrent; public class ILStrip : Microsoft.Build.Utilities.Task @@ -355,11 +354,10 @@ private static void SetCodeSizeToZeroForTiny(Stream stream, int actualLoc) private static void ZeroOutMethodBody(Stream stream, int methodSize, int actualLoc, int headerSize) { stream.Position = actualLoc + headerSize; - byte[] zeroBuffer; - zeroBuffer = ArrayPool.Shared.Rent(methodSize - headerSize); - Array.Clear(zeroBuffer, 0, zeroBuffer.Length); - stream.Write(zeroBuffer, 0, zeroBuffer.Length); - ArrayPool.Shared.Return(zeroBuffer); + for (int i = 0; i < methodSize - headerSize; i++) + { + stream.WriteByte(0); + } } private static TaskItem GetTrimmedAssemblyItem(ITaskItem assemblyItem, string trimmedAssemblyFilePath, string originAssemblyFilePath)