From 9086d2e7539d9b0740e829c3d1d2917fa0e57f4c Mon Sep 17 00:00:00 2001 From: Arvind Shyamsundar Date: Thu, 12 Dec 2019 21:07:49 -0800 Subject: [PATCH] Eliminate extra dependencies --- .../Microsoft.Diagnostics.Runtime.csproj | 6 -- .../src/Extensions/SpanExtensions.cs | 58 ------------------- .../src/Utilities/PEFile/PEFile.cs | 2 +- .../src/Utilities/PEFile/ResourceNode.cs | 3 +- .../src/Utilities/PEImage/FileVersionInfo.cs | 34 ++++++++--- .../src/Utilities/PEImage/PEImage.cs | 37 +++--------- .../src/Utilities/PEImage/ResourceEntry.cs | 36 ++++-------- 7 files changed, 47 insertions(+), 129 deletions(-) delete mode 100644 src/Microsoft.Diagnostics.Runtime/src/Extensions/SpanExtensions.cs diff --git a/src/Microsoft.Diagnostics.Runtime/Microsoft.Diagnostics.Runtime.csproj b/src/Microsoft.Diagnostics.Runtime/Microsoft.Diagnostics.Runtime.csproj index 5948e6e19..1af31773c 100644 --- a/src/Microsoft.Diagnostics.Runtime/Microsoft.Diagnostics.Runtime.csproj +++ b/src/Microsoft.Diagnostics.Runtime/Microsoft.Diagnostics.Runtime.csproj @@ -30,10 +30,4 @@ - - - - - - diff --git a/src/Microsoft.Diagnostics.Runtime/src/Extensions/SpanExtensions.cs b/src/Microsoft.Diagnostics.Runtime/src/Extensions/SpanExtensions.cs deleted file mode 100644 index f842a511d..000000000 --- a/src/Microsoft.Diagnostics.Runtime/src/Extensions/SpanExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Buffers; -using System.IO; -using System.Runtime.InteropServices; - -namespace Microsoft.Diagnostics.Runtime -{ - internal static class SpanExtensions - { - public static int Read(this Stream stream, Span span) - { - byte[] buffer = ArrayPool.Shared.Rent(span.Length); - try - { - int numRead = stream.Read(buffer, 0, span.Length); - new ReadOnlySpan(buffer, 0, numRead).CopyTo(span); - return numRead; - } - finally - { - ArrayPool.Shared.Return(buffer); - } - } - - public static ulong AsPointer(this Span span, int index = 0) - { - if (index != 0) - span = span.Slice(index * IntPtr.Size, IntPtr.Size); - - DebugOnly.Assert(span.Length >= IntPtr.Size); - return IntPtr.Size == 4 - ? MemoryMarshal.Read(span) - : MemoryMarshal.Read(span); - } - - public static int AsInt32(this Span span) - { - DebugOnly.Assert(span.Length >= sizeof(int)); - return MemoryMarshal.Read(span); - } - - public static uint AsUInt32(this Span span) - { - DebugOnly.Assert(span.Length >= sizeof(uint)); - return MemoryMarshal.Read(span); - } - - public static ulong AsUInt64(this Span span) - { - DebugOnly.Assert(span.Length >= sizeof(ulong)); - return MemoryMarshal.Read(span); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/PEFile.cs b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/PEFile.cs index 8354ccba5..4cb6d8fe7 100644 --- a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/PEFile.cs +++ b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/PEFile.cs @@ -206,7 +206,7 @@ public FileVersionInfo GetFileVersionInfo() PEBuffer buff = AllocBuff(); byte* bytes = versionNode.FetchData(0, versionNode.DataLength, buff); - FileVersionInfo ret = new FileVersionInfo(new Span(bytes, versionNode.DataLength)); + FileVersionInfo ret = new FileVersionInfo(bytes, versionNode.DataLength); FreeBuff(buff); return ret; diff --git a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/ResourceNode.cs b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/ResourceNode.cs index cfea6d4f7..cd85c4fe6 100644 --- a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/ResourceNode.cs +++ b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEFile/ResourceNode.cs @@ -26,8 +26,7 @@ public FileVersionInfo GetFileVersionInfo() { PEBuffer buff = _file.AllocBuff(); byte* bytes = FetchData(0, DataLength, buff); - - FileVersionInfo ret = new FileVersionInfo(new Span(bytes, DataLength)); + FileVersionInfo ret = new FileVersionInfo(bytes, DataLength); _file.FreeBuff(buff); return ret; } diff --git a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/FileVersionInfo.cs b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/FileVersionInfo.cs index 51d834f04..6e1e78fc2 100644 --- a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/FileVersionInfo.cs +++ b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/FileVersionInfo.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Text; namespace Microsoft.Diagnostics.Runtime.Utilities { @@ -27,16 +28,33 @@ public sealed unsafe class FileVersionInfo /// public string? Comments { get; } - internal FileVersionInfo(Span data) + internal FileVersionInfo(byte[] data, int dataLen) { - data = data.Slice(DataOffset); - fixed (byte* ptr = data) - { - string dataAsString = new string((char*)ptr, 0, data.Length / 2); + FileVersion = ""; + if (dataLen <= DataOffset) + return; - FileVersion = GetDataString(dataAsString, "FileVersion"); - Comments = GetDataString(dataAsString, "Comments"); - } + var dataAsString = Encoding.Unicode.GetString(data, DataOffset, dataLen - DataOffset); + + FileVersion = GetDataString(dataAsString, "FileVersion"); + Comments = GetDataString(dataAsString, "Comments"); + } + + [Obsolete] + internal FileVersionInfo(byte* data, int dataLen) + { + FileVersion = ""; + if (dataLen <= 0x5c) + return; + + // See http://msdn.microsoft.com/en-us/library/ms647001(v=VS.85).aspx + byte* stringInfoPtr = data + 0x5c; // Gets to first StringInfo + + // TODO search for FileVersion string ... + string dataAsString = new string((char*)stringInfoPtr, 0, (dataLen - 0x5c) / 2); + + FileVersion = GetDataString(dataAsString, "FileVersion"); + Comments = GetDataString(dataAsString, "Comments"); } private static string? GetDataString(string dataAsString, string fileVersionKey) diff --git a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/PEImage.cs b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/PEImage.cs index aa8c07cdf..871f0c8d4 100644 --- a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/PEImage.cs +++ b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/PEImage.cs @@ -1,8 +1,8 @@ using Microsoft.Diagnostics.Runtime.Interop; using System; -using System.Buffers; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Data; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -220,27 +220,11 @@ public int Read(byte[] dest, int virtualAddress, int bytesRequested) return read; } - /// - /// Reads data out of PE image into a native buffer. - /// - /// The address to read from. - /// The location to write the data. - /// The number of bytes actually read from the image and written to dest. - public int Read(int virtualAddress, Span dest) - { - int offset = RvaToOffset(virtualAddress); - if (offset == -1) - return 0; - - SeekTo(offset); - return Stream.Read(dest); - } - /// /// Gets the File Version Information that is stored as a resource in the PE file. (This is what the /// version tab a file's property page is populated with). /// - public FileVersionInfo? GetFileVersionInfo() + public unsafe FileVersionInfo? GetFileVersionInfo() { ResourceEntry? versionNode = Resources.Children.FirstOrDefault(r => r.Name == "Version"); if (versionNode == null || versionNode.Children.Count != 1) @@ -254,18 +238,11 @@ public int Read(int virtualAddress, Span dest) if (size <= FileVersionInfo.DataOffset) return null; - byte[] buffer = ArrayPool.Shared.Rent(size); - try - { - int count = versionNode.GetData(buffer); - Span span = new Span(buffer, 0, count); - FileVersionInfo result = new FileVersionInfo(span); - return result; - } - finally - { - ArrayPool.Shared.Return(buffer); - } + byte[] bytes = versionNode.GetData(); + + FileVersionInfo ret = new FileVersionInfo(bytes, versionNode.Size); + + return ret; } private ResourceEntry CreateResourceRoot() diff --git a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/ResourceEntry.cs b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/ResourceEntry.cs index a842b43c5..b684aa39a 100644 --- a/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/ResourceEntry.cs +++ b/src/Microsoft.Diagnostics.Runtime/src/Utilities/PEImage/ResourceEntry.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; namespace Microsoft.Diagnostics.Runtime.Utilities @@ -98,36 +98,24 @@ public byte[] GetData() return result; } - /// - /// Get the data associated with this entry. - /// - /// The location to write the data - /// The number of bytes actually read from the image and written to dest - public int GetData(Span span) - { - GetDataVaAndSize(out int va, out int size); - if (size == 0 || va == 0) - return 0; - - return Image.Read(va, span); - } - /// /// A convenience function to get structured data out of this entry. /// /// A struct type to convert. /// The offset into the data. /// The struct that was read out of the data section. - public unsafe T GetData(int offset = 0) where T : unmanaged + public T GetData(int offset = 0) where T : struct { - int size = Unsafe.SizeOf(); - GetDataVaAndSize(out int va, out int sectionSize); - if (va == 0 || sectionSize < size + offset) - return default; - - T output; - int read = Image.Read(va + offset, new Span(&output, size)); - return read == size ? output : default; + byte[] data = GetData(); + int size = Marshal.SizeOf(typeof(T)); + if (size + offset > data.Length) + throw new IndexOutOfRangeException(); + + GCHandle hnd = GCHandle.Alloc(data, GCHandleType.Pinned); + T result = (T)Marshal.PtrToStructure(hnd.AddrOfPinnedObject(), typeof(T)); + hnd.Free(); + + return result; } private ResourceEntry[] GetChildren()