Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable IlasmRoundTrip tests for merged tests #93368

Merged
merged 42 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8dd8951
Initial work
TIHan Oct 11, 2023
d348160
Tweak
TIHan Oct 11, 2023
41394cb
Tweak
TIHan Oct 11, 2023
d5afb0e
Do not generate _ilasmroundtrip.py for tests that have a generated ru…
TIHan Oct 11, 2023
c59ea7d
Reduce imports
TIHan Oct 11, 2023
a3a41cf
Force fail to see where CI fails
TIHan Oct 12, 2023
20adfcd
Revert forcing failure. Run roundtrip on build.
TIHan Oct 12, 2023
b91c82d
Trying to fix script
TIHan Oct 12, 2023
fa91e26
Backslash tweak
TIHan Oct 12, 2023
a825fe8
Do not roundtrip the same assembly
TIHan Oct 12, 2023
ede1994
Fixing
TIHan Oct 12, 2023
828c4b0
Remove import glob
TIHan Oct 12, 2023
844eb49
Added is_managed_assembly
TIHan Oct 12, 2023
265d870
remove print
TIHan Oct 12, 2023
cd497ac
Fixed paths
TIHan Oct 12, 2023
969369b
Support bash. Ignore certain tests for arm. Fix poison test.
TIHan Oct 13, 2023
c1e0b1f
Update CLRTest.Jit.targets
TIHan Oct 13, 2023
f654a59
Feedback. Added AssemblyChecker.
TIHan Oct 16, 2023
54d65a8
Merge branch 'ilasm-roundtrip-fix' of https://github.com/TIHan/runtim…
TIHan Oct 16, 2023
b06879a
Fix paths
TIHan Oct 17, 2023
9f8d9e8
Update src/tests/Common/Directory.Build.targets
TIHan Oct 17, 2023
9b7bf31
Feedback
TIHan Oct 17, 2023
0b14d98
Feedback
TIHan Oct 17, 2023
7aca653
Update AssemblyChecker.csproj
TIHan Oct 17, 2023
e9abeb4
Update Program.cs
TIHan Oct 17, 2023
5f57ed6
Trying to fix calling python on helix.
TIHan Oct 17, 2023
ca91893
Remove old roundtrip script calls. Added --is-exe option for Assembly…
TIHan Oct 17, 2023
ba6fc6f
Tweak option:
TIHan Oct 17, 2023
d564396
Remove check
TIHan Oct 17, 2023
c9d1e49
Remove imports
TIHan Oct 17, 2023
18914d8
Fix build
TIHan Oct 18, 2023
1a6476a
Fix syntax errors. Fixed Popen arguments
TIHan Oct 18, 2023
4e97e05
Fixed Popen arguments
TIHan Oct 18, 2023
b2c85b9
Fixing debug check
TIHan Oct 18, 2023
e25f1d4
Fixing tests
TIHan Oct 18, 2023
2ed31da
Update ILVerificationTests.csproj
TIHan Oct 19, 2023
f9c41e9
Fixing tests
TIHan Oct 19, 2023
fe51ff1
Feedback
TIHan Oct 23, 2023
703e89b
Feedback
TIHan Oct 24, 2023
7b4796a
Update CLRTest.Jit.targets
TIHan Oct 27, 2023
dcff071
Added help usage flag for AssemblyChecker
TIHan Oct 27, 2023
4a2442e
Feedback on assembly-checker
TIHan Oct 29, 2023
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
3 changes: 2 additions & 1 deletion eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@
$(CoreClrProjectRoot)tools\r2rdump\R2RDump.csproj;
$(CoreClrProjectRoot)tools\dotnet-pgo\dotnet-pgo.csproj;
$(CoreClrProjectRoot)tools\aot\ILCompiler\repro\repro.csproj;
$(CoreClrProjectRoot)tools\r2rtest\R2RTest.csproj" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
$(CoreClrProjectRoot)tools\r2rtest\R2RTest.csproj;
$(CoreClrProjectRoot)tools\AssemblyChecker\AssemblyChecker.csproj" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\crossgen2\crossgen2.csproj" Category="clr" />
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\ILCompiler.Build.Tasks\ILCompiler.Build.Tasks.csproj" Category="clr" Condition="'$(NativeAotSupported)' == 'true'" />
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\ILCompiler\ILCompiler.csproj" Category="clr" Condition="'$(NativeAotSupported)' == 'true'" />
Expand Down
58 changes: 58 additions & 0 deletions src/coreclr/tools/AssemblyChecker/AssemblyChecker.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>AssemblyChecker</AssemblyName>
<OutputType>Exe</OutputType>
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
<PlatformTarget>AnyCPU</PlatformTarget>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendTargetFrameworkToOutputPath Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</AppendTargetFrameworkToOutputPath>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputPath>$(RuntimeBinDir)\AssemblyChecker</OutputPath>
<RunAnalyzers>false</RunAnalyzers>
</PropertyGroup>

<PropertyGroup>
<!-- Massage the OutputRID into an JITTools package RID that we can download -->
<_jitToolsRidPlatformIndex>$(OutputRID.LastIndexOf('-'))</_jitToolsRidPlatformIndex>
<JITToolsRidWithoutPlatform>$(OutputRID.Substring(0, $(_jitToolsRidPlatformIndex)))</JITToolsRidWithoutPlatform>
<JITToolsRidPlatform>$(OutputRID.Substring($(_jitToolsRidPlatformIndex)).TrimStart('-'))</JITToolsRidPlatform>

<!-- If it's not win/osx/linux-musl, it's a non-portable Linux. Treat as Linux. -->
<JITToolsRidWithoutPlatform Condition="'$(JITToolsRidWithoutPlatform)' != 'win' and '$(JITToolsRidWithoutPlatform)' != 'osx' and '$(JITToolsRidWithoutPlatform)' != 'linux-musl'">linux</JITToolsRidWithoutPlatform>

<!-- There are no x86 packages, so use x64 -->
<JITToolsRidPlatform Condition="'$(JITToolsRidPlatform)' == 'x86'">x64</JITToolsRidPlatform>
<JITToolsRidPlatform Condition="'$(JITToolsRidPlatform)' == 'arm' and '$(JITToolsRidWithoutPlatform)' == 'win'">arm64</JITToolsRidPlatform>
<JITToolsRid Condition="'$(JITToolsRid)' == ''">$(JITToolsRidWithoutPlatform)-$(JITToolsRidPlatform)</JITToolsRid>

<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'linux-arm64'">$(runtimelinuxarm64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'linux-x64'">$(runtimelinuxx64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'linux-musl-arm64'">$(runtimelinuxmuslarm64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'linux-musl-x64'">$(runtimelinuxmuslx64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'win-arm64'">$(runtimewinarm64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'win-x64'">$(runtimewinx64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'osx-arm64'">$(runtimeosxarm64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
<JITToolsVersion Condition="'$(JITToolsVersion)' == '' and '$(JITToolsRid)' == 'osx-x64'">$(runtimeosxx64MicrosoftNETCoreRuntimeJITToolsVersion)</JITToolsVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpVersion)" />
<PackageDownload Condition="'$(DotNetBuildFromSource)' != 'true'" Include="runtime.$(JITToolsRid).Microsoft.NETCore.Runtime.JIT.Tools">
<Version>[$(JITToolsVersion)]</Version>
</PackageDownload>
</ItemGroup>

<Target Name="CopyJitTools" AfterTargets="Build">
<ItemGroup>
<JitToolsFiles Include="$(NuGetPackageRoot)\runtime.$(JITToolsRid).microsoft.netcore.runtime.jit.tools\$(JITToolsVersion)\runtimes\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(JitToolsFiles)"
SkipUnchangedFiles="true"
OverwriteReadOnlyFiles="true"
DestinationFolder="$(OutputPath)\runtimes\%(RecursiveDir)" />
</Target>

</Project>
116 changes: 116 additions & 0 deletions src/coreclr/tools/AssemblyChecker/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text;
using System.Diagnostics;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

namespace AssemblyChecker
{
public class Program
{
static bool IsAssembly(string path)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// Try to read CLI metadata from the PE file.
using var peReader = new PEReader(fs);

if (!peReader.HasMetadata)
{
return false; // File does not have CLI metadata.
}

// Check that file has an assembly manifest.
MetadataReader reader = peReader.GetMetadataReader();
return reader.IsAssembly;
}

static bool HasDebuggableAttribute(MetadataReader reader, EntityHandle entity)
{
if (entity.IsNil)
return false;

switch (entity.Kind)
{
case HandleKind.MemberReference:
{
var memRef = reader.GetMemberReference((MemberReferenceHandle)entity);
switch (memRef.Parent.Kind)
{
case HandleKind.TypeReference:
{
var tyRef = reader.GetTypeReference((TypeReferenceHandle)memRef.Parent);
return reader.GetString(tyRef.Name) == "DebuggableAttribute";
}

default:
return false;
}
}

default:
return false;
}

}

static bool IsDebug(string path)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// Try to read CLI metadata from the PE file.
using var peReader = new PEReader(fs);

if (!peReader.HasMetadata)
{
return false; // File does not have CLI metadata.
}

// Check that file has an assembly manifest.
MetadataReader reader = peReader.GetMetadataReader();

var attrs = reader.GetAssemblyDefinition().GetCustomAttributes();
return attrs.Any(x => HasDebuggableAttribute(reader, reader.GetCustomAttribute(x).Constructor));
}

static int Main(string[] args)
{
if (args.Length == 0)
{
throw new ArgumentException("Expected assembly file-path.");
}

if (args.Length > 2)
{
throw new ArgumentException("Too many arguments.");
}

if (args.Length == 1)
{
if (IsAssembly(args[0]))
return 0;
else
return 1;
}

if (args.Length == 2)
{
if (args[0] == "--is-debug")
{
if (IsDebug(args[1]))
return 0;
else
return 1;
}
else
{
throw new ArgumentException("Invalid option.");
}
}

return -1;
}
}
}
96 changes: 96 additions & 0 deletions src/tests/Common/CLRTest.Jit.targets
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export RunningIlasmRoundTrip=
if [ -z "$DoLink" -a ! -z "$RunningIlasmRoundTrip" ];
then
mkdir IL-RT
if [ "$(IsMergedTestRunnerAssembly)" = "true" ]
then
python $(AssemblyName)_ilasmroundtrip.py
fi
cp $(InputAssemblyName) $(TargetAssemblyName)
echo "$CORE_ROOT/ildasm" -raweh -unicode -out=$(DisassemblyName) $(TargetAssemblyName)
"$CORE_ROOT/ildasm" -raweh -unicode -out=$(DisassemblyName) $(TargetAssemblyName)
Expand Down Expand Up @@ -147,6 +151,9 @@ REM Todo: Ilasm round-trip on linked binaries.
IF NOT DEFINED DoLink (
IF DEFINED RunningIlasmRoundTrip (
mkdir IL-RT
IF "$(IsMergedTestRunnerAssembly)"=="true" (
python $(AssemblyName)_ilasmroundtrip.py
)
copy $(InputAssemblyName) $(TargetAssemblyName)
ECHO %CORE_ROOT%\ildasm.exe /raweh /unicode /out=$(DisassemblyName) $(TargetAssemblyName)
%CORE_ROOT%\ildasm.exe /raweh /unicode /out=$(DisassemblyName) $(TargetAssemblyName)
Expand Down Expand Up @@ -365,6 +372,95 @@ set DOTNET_JitPath=%CORE_ROOT%\superpmi-shim-collector.dll
</PropertyGroup>
</Target>

<!--
***********************************************************************************************
IlasmRoundTrip for merged tests
***********************************************************************************************
-->

<Target Name="IlasmRoundTripCommand" AfterTargets="AfterBuild" Condition="'$(IsMergedTestRunnerAssembly)' == 'true'">
<PropertyGroup>
<InputAssemblyName>$(AssemblyName).dll</InputAssemblyName>
<DisassemblyName>IL-RT/$(AssemblyName).il</DisassemblyName>
<TargetAssemblyName>IL-RT/$(AssemblyName).dll</TargetAssemblyName>
<_IlasmRoundTripScriptText><![CDATA[
import os
import shutil
import subprocess
import sys
import glob
import struct
import platform

def is_managed_assembly(file):
proc = subprocess.Popen(f'{os.environ["CORE_ROOT"]}/corerun {os.environ["CORE_ROOT"]}/AssemblyChecker/AssemblyChecker.dll {file}')

try:
proc.communicate()
return proc.returncode == 0
except:
proc.kill()
return False

def is_managed_debug_assembly(file):
proc = subprocess.Popen(f'{os.environ["CORE_ROOT"]}/corerun {os.environ["CORE_ROOT"]}/AssemblyChecker/AssemblyChecker.dll --is-debug {file}')

try:
proc.communicate()
return proc.returncode == 0
except:
proc.kill()
return False

print("")
print("ILASM RoundTrips")

if not os.path.exists("IL-RT"):
os.mkdir("IL-RT")

for inputAssemblyName in glob.glob("*.dll"):
# Roundtrips library assemblies. Executable assemblies are done in the bash/batch scripts.
# We filter out the executable assembly that this script gets generated from.
if (not inputAssemblyName.endswith("$(AssemblyName).dll")) and is_managed_assembly(inputAssemblyName):
print("ILASM RoundTrip for " + inputAssemblyName)

ilasmSwitches = ""
if is_managed_debug_assembly(inputAssemblyName):
ilasmSwitches = "-DEBUG"

disassemblyName = os.path.join("IL-RT", os.path.splitext(os.path.basename(inputAssemblyName))[0] + ".il")
targetAssemblyName = os.path.join("IL-RT", os.path.basename(inputAssemblyName))

shutil.copyfile(inputAssemblyName, targetAssemblyName)

proc = subprocess.Popen(f'{os.environ["CORE_ROOT"]}/ildasm /raweh /unicode /out={disassemblyName} {targetAssemblyName}')

try:
proc.communicate()
except:
proc.kill()
sys.exit(1)

proc = subprocess.Popen(f'{os.environ["CORE_ROOT"]}/ilasm /DLL /output={inputAssemblyName} {ilasmSwitches} {disassemblyName}')

try:
proc.communicate()
except:
proc.kill()
sys.exit(1)

print("")

print("")

]]></_IlasmRoundTripScriptText>
</PropertyGroup>
<WriteLinesToFile
File="$(OutputPath)$(AssemblyName)_ilasmroundtrip.py"
Lines="$(_IlasmRoundTripScriptText)"
Overwrite="true" />
</Target>

<!--
***********************************************************************************************
GCStress settings
Expand Down
5 changes: 5 additions & 0 deletions src/tests/Common/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@
<IncludeSubFolders>True</IncludeSubFolders>
</RunTimeArtifactsIncludeFolders>

<!-- Used to determine if a file is a mananaged assembly or a managed assembly built with DEBUG -->
<RunTimeArtifactsIncludeFolders Include="AssemblyChecker/" TargetDir="AssemblyChecker/">
<IncludeSubFolders>True</IncludeSubFolders>
</RunTimeArtifactsIncludeFolders>

<!-- XUnit runner harness assemblies that we don't want to mix in with the framework in Core_Root -->
<RunTimeArtifactsIncludeFolders Include="xunit/" TargetDir="xunit/" />
</ItemGroup>
Expand Down