Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ projects that use the Microsoft.Android framework in .NET 6+.
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)Java.Interop.dll" />
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)Mono.Android.dll" />
<_AndroidRuntimePackAssemblies Include="$(_MonoAndroidNETDefaultOutDir)Mono.Android.Runtime.dll" />
<!-- Always include a stable version of System.IO.Hashing. -->
<_AndroidRuntimePackAssemblies
Include="$(_MonoAndroidNETOutputRoot)$(AndroidLatestStableApiLevel)\System.IO.Hashing.dll"
NoSymbols="true"
/>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
<ProjectReference Include="..\Mono.Android\Mono.Android.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.IO.Hashing" Version="$(SystemIOHashingPackageVersion)" />
</ItemGroup>

<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />

<!-- Copy runtime assemblies to bin/$(Configuration)/dotnet/packs folder -->
Expand Down
2 changes: 0 additions & 2 deletions src/Mono.Android/Mono.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.IO.Hashing" Version="$(SystemIOHashingPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="5.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down Expand Up @@ -432,7 +431,6 @@
<_RefExtras Include="$(OutputPath)*.*" Exclude="$(OutputPath)*.dll" />
<_SourceFiles Include="$(OutputPath)Mono.Android.*" />
<_SourceFiles Include="$(OutputPath)Java.Interop.*" />
<_SourceFiles Include="$(OutputPath)System.IO.Hashing.dll" />
</ItemGroup>
<Copy
SourceFiles="@(_RefExtras)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Hashing" Version="$(SystemIOHashingPackageVersion)" />
<ProjectReference Include="..\..\..\Xamarin.Android.Tools.AndroidSdk\Xamarin.Android.Tools.AndroidSdk.csproj">
<Project>{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157}</Project>
<Name>Xamarin.Android.Tools.AndroidSdk</Name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Hashing;

using Microsoft.Android.Build.Tasks;
using Microsoft.Build.Utilities;
Expand Down Expand Up @@ -140,8 +141,8 @@ string Generate (string baseOutputDirectory, AndroidTargetArch arch, List<Assemb
throw new InvalidOperationException ($"Internal error: corrupted store '{storePath}' stream");
}

uint name_with_ext_hash = TypeMapHelper.HashBytesForCLR (info.AssemblyNameBytes);
uint name_no_ext_hash = TypeMapHelper.HashBytesForCLR (info.AssemblyNameNoExtBytes);
uint name_with_ext_hash = HashAssemblyName (info.AssemblyNameBytes);
uint name_no_ext_hash = HashAssemblyName (info.AssemblyNameNoExtBytes);
index.Add (new AssemblyStoreIndexEntry (info.AssemblyName, name_with_ext_hash, entryIndex, info.Ignored));
index.Add (new AssemblyStoreIndexEntry (info.AssemblyNameNoExt, name_no_ext_hash, entryIndex, info.Ignored));

Expand Down Expand Up @@ -285,4 +286,13 @@ void WriteNames (BinaryWriter writer, List<AssemblyStoreAssemblyInfo> infos)
writer.Write (info.AssemblyNameBytes);
}
}

static uint HashAssemblyName (ReadOnlySpan<byte> bytes)
{
if (bytes.Length == 0) {
return UInt32.MaxValue;
}

return Crc32.HashToUInt32 (bytes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Hashing;

using Java.Interop.Tools.TypeNameMappings;
using Microsoft.Android.Build.Tasks;
Expand Down Expand Up @@ -66,7 +67,7 @@ public byte [] Create ()
{
var state = CreateDsoCache ();
foreach (var entry in state.Entries) {
entry.Hash = TypeMapHelper.HashNameForCLR (entry.HashedName);
entry.Hash = HashLibraryName (entry.HashedName);
}
state.Entries.Sort ((a, b) => a.Hash.CompareTo (b.Hash));

Expand Down Expand Up @@ -206,4 +207,13 @@ static ICollection<string> MakeJniPreloadIgnoreCollection (TaskLoggingHelper log
}
return name;
}

static uint HashLibraryName (string name)
{
if (name.Length == 0) {
return UInt32.MaxValue;
}

return Crc32.HashToUInt32 (MonoAndroidHelper.Utf8StringToBytes (name));
Comment thread
simonrozsival marked this conversation as resolved.
Resolved
Comment thread
simonrozsival marked this conversation as resolved.
Resolved
}
}
20 changes: 3 additions & 17 deletions src/Xamarin.Android.Build.Tasks/Utilities/MibcProfileWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.IO.Hashing;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Security.Cryptography;
using System.Text;

namespace Xamarin.Android.Tasks;
Expand Down Expand Up @@ -557,22 +557,8 @@ void WritePE (string outputPath, BlobContentId contentId)
/// </param>
static BlobContentId ContentId (string fingerprint)
{
// This is only a content fingerprint, so a non cryptographic hash is fine, and unlike
// System.Security.Cryptography the System.IO.Hashing APIs are span based on netstandard2.0.
int byteCount = Encoding.UTF8.GetByteCount (fingerprint);
Span<byte> bytes = byteCount <= TypeMapHelper.StackallocThresholdBytes
? stackalloc byte [byteCount]
: new byte [byteCount];
TypeMapHelper.GetBytes (fingerprint, Encoding.UTF8, bytes);

// BlobContentId.FromHash turns hash bytes into an MVID and timestamp for us, including the
// RFC 4122 version and variant bits and the byte order of the Guid fields. It reads 20
// bytes: 0..16 become the MVID and 16..20 become the timestamp. XxHash128 only produces
// 16, so the timestamp slot repeats the first four rather than hashing the input again.
// This cannot be a stackalloc: FromHash only overloads on byte[] and ImmutableArray<byte>.
var hash = new byte [20];
XxHash128.Hash (bytes, hash.AsSpan (0, 16));
hash.AsSpan (0, 4).CopyTo (hash.AsSpan (16));
using var sha256 = SHA256.Create ();
byte[] hash = sha256.ComputeHash (Encoding.UTF8.GetBytes (fingerprint));
return BlobContentId.FromHash (hash);
Comment on lines -560 to 562

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did we lose the stackalloc above? seems like we could keep that partially?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mibc is Release mode, so probably OK.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.Hashing;
using System.Text;

using Xamarin.Android.Tools;
Expand Down Expand Up @@ -218,18 +217,6 @@ public static string MakeDiscreteAssembliesEntryName (string name, string? cultu
}

public static byte[] Utf8StringToBytes (string str) => Encoding.UTF8.GetBytes (str);
public static byte[] Utf16StringToBytes (string str) => Encoding.Unicode.GetBytes (str);

public static ulong GetXxHash (string str, bool is64Bit) => GetXxHash (Utf8StringToBytes (str), is64Bit);

public static ulong GetXxHash (byte[] stringBytes, bool is64Bit)
{
if (is64Bit) {
return XxHash3.HashToUInt64 (stringBytes);
}

return (ulong)XxHash32.HashToUInt32 (stringBytes);
}

/// <summary>
/// Helper method to compare two strings with specified comparison mode.
Expand Down
98 changes: 0 additions & 98 deletions src/Xamarin.Android.Build.Tasks/Utilities/TypeMapHelper.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/native/clr/include/runtime-base/crc32.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace xamarin::android {
{
// An empty input deliberately maps to UINT32_MAX rather than to the standard CRC32 of the
// empty string (0). This is a sentinel that must stay in lockstep with the managed generators
// (TypeMapHelper.HashNameForCLR / HashBytesForCLR, which likewise special-case a zero-length
// (AssemblyStoreGenerator and CoreClrBootstrapBuilder, which likewise special-case a zero-length
// input to UInt32.MaxValue); the build-time and runtime hashes must agree, so do not "fix"
// this to 0.
if (len == 0) [[unlikely]] {
Expand Down
23 changes: 21 additions & 2 deletions tools/tmt/XamarinAppReleaseDSO_V2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Text;

using ELFSharp.ELF.Sections;
using Xamarin.Android.Tasks;

namespace tmt;

Expand Down Expand Up @@ -353,7 +352,7 @@ List<string> LoadJavaTypeNames (string filePath)

ret.Add (name ?? String.Empty);

ulong hash = TypeMapHelper.HashJavaName (name ?? String.Empty, Is64Bit);
ulong hash = HashJavaName (name ?? String.Empty, Is64Bit);
int javaTypeIndex = javaTypeNameHashes!.IndexOf (hash);

if (javaTypeIndex < 0) {
Expand Down Expand Up @@ -537,4 +536,24 @@ string GetJavaTypeName (TypeMapJava tmj)
}

string HashToHexString (ulong hash) => Is64Bit ? $"{hash:X16}" : $"{hash:X8}";

static ulong HashJavaName (string name, bool is64Bit)
{
if (name.Length == 0) {
return UInt64.MaxValue;
}

const int StackallocThresholdBytes = 256;
int byteCount = Encoding.Unicode.GetByteCount (name);
Span<byte> buffer = byteCount <= StackallocThresholdBytes
? stackalloc byte [byteCount]
: new byte [byteCount];
Encoding.Unicode.GetBytes (name.AsSpan (), buffer);

if (is64Bit) {
return XxHash3.HashToUInt64 (buffer);
}

return (ulong)XxHash32.HashToUInt32 (buffer);
}
}
2 changes: 0 additions & 2 deletions tools/tmt/tmt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<OutputPath>../../bin/$(Configuration)/bin/typemap-tool</OutputPath>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<RollForward>Major</RollForward>
</PropertyGroup>

<ItemGroup>
<Compile Include="../../src/Xamarin.Android.Build.Tasks/Utilities/TypeMapHelper.cs" />
<Compile Include="..\..\.github\skills\read-assembly-store\src\AssemblyStore\V1\*.cs" />
<Compile Include="..\..\.github\skills\read-assembly-store\src\AssemblyStore\AssemblyCompression.cs" />
</ItemGroup>
Expand Down
Loading