XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
param(
    [string]$ToolRoot = '',
    [string]$ProjectPath = '',
    [string]$OutputDirectory = ''
)
$ErrorActionPreference = 'Stop'
$taskRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../../..'))
. (Join-Path $PSScriptRoot 'InputHashes.ps1')
. (Join-Path $taskRoot 'Tools/TlsEntropyPatch/VerifyReceipt.ps1')
if(!$ToolRoot) { $ToolRoot=Join-Path $taskRoot '.tools' }
& (Join-Path $PSScriptRoot 'VerifyToolchain.ps1')
if (!$OutputDirectory) { $OutputDirectory = Join-Path $taskRoot ('build/IndependentKernel/RuntimeProbe/Probe-' + [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()) }
$OutputDirectory = [IO.Path]::GetFullPath($OutputDirectory)
[void][IO.Directory]::CreateDirectory($OutputDirectory)
$taskNugetRoot = if ($env:NUGET_PACKAGES) { $env:NUGET_PACKAGES } else { Join-Path ([Environment]::GetFolderPath('UserProfile')) '.nuget/packages' }
$version = '10.0.12'
$ilc = Join-Path $taskNugetRoot "runtime.win-x64.microsoft.dotnet.ilcompiler/$version/tools/ilc.exe"
$pack = Join-Path $taskNugetRoot "microsoft.netcore.app.runtime.nativeaot.linux-x64/$version/runtimes/linux-x64"
$native = Join-Path $pack 'native'
$llvm = Join-Path $ToolRoot 'llvm/bin'
$project = if ($ProjectPath) { [IO.Path]::GetFullPath($ProjectPath) } else { Join-Path $taskRoot 'Source/XFESystem.NativeRuntime/Probe/NativeRuntimeProbe.csproj' }
$projectName = [IO.Path]::GetFileNameWithoutExtension($project)
$artifacts = Join-Path $OutputDirectory 'Artifacts'
& dotnet restore $project --locked-mode --artifacts-path $artifacts > (Join-Path $OutputDirectory 'ManagedRestore.log') 2>&1
if ($LASTEXITCODE -ne 0) { throw 'Managed project restore failed; see ManagedRestore.log.' }
$sourceHashes=Get-RuntimeProjectInputs $taskRoot $project
foreach($path in @($PSCommandPath,(Join-Path $PSScriptRoot 'InputHashes.ps1'),(Join-Path $taskRoot 'Tools/TlsEntropyPatch/VerifyReceipt.ps1'),(Join-Path $PSScriptRoot 'VerifyToolchain.ps1'),(Join-Path $PSScriptRoot 'NativeToolchain.json'),(Join-Path $PSScriptRoot 'NativeToolchain.csproj'))) {
    $sourceHashes[(Get-RuntimeRelativeInput $taskRoot $path)]=Get-RuntimeInputHash $path
}
& dotnet build $project -c Release --no-restore --artifacts-path $artifacts -p:XfeNativeEntropyPort=true > (Join-Path $OutputDirectory 'ManagedBuild.log') 2>&1
if ($LASTEXITCODE -ne 0) { throw 'Managed probe build failed; see ManagedBuild.log.' }
$applicationOutput = Join-Path $artifacts ('bin/' + $projectName + '/release')
$managedInputPath = Join-Path $applicationOutput ($projectName + '.dll')
$tlsEntropyPort=$null
$privateBc=Join-Path $applicationOutput 'BouncyCastle.Cryptography.dll'
if(Test-Path -LiteralPath $privateBc) {
    $adapter=Join-Path $applicationOutput 'XFESystem.NativeEntropy.dll'; $entropyReceipt=$privateBc+'.XfeEntropy.json'
    $tlsEntropyPort=Assert-XfeNativeEntropyPort $taskRoot ([pscustomobject]@{
        ReceiptPath=$entropyReceipt;ReceiptSha256=(Get-RuntimeInputHash $entropyReceipt);
        BouncyCastlePath=$privateBc;BouncyCastleSha256=(Get-RuntimeInputHash $privateBc);
        AdapterPath=$adapter;AdapterSha256=(Get-RuntimeInputHash $adapter)})
}
$object = Join-Path $OutputDirectory 'NativeRuntimeProbe.o'
$arguments = @(('"' + $managedInputPath + '"'), ('-o:"' + $object + '"'), '--targetos:linux', '--targetarch:x64', '--instruction-set:x86-64', '-O', '-g', '--stacktracedata', '--scanreflection', '--export-unmanaged-entrypoints', '--initassembly:System.Private.CoreLib', '--directpinvoke:xfe_pal', '--runtimeopt:gcConcurrent=0', '--runtimeopt:gcServer=0', '--runtimeknob:System.GC.Concurrent=false')
$arguments += @('--generateunmanagedentrypoints:System.Private.CoreLib,HIDDEN', '--initassembly:System.Private.TypeLoader', '--initassembly:System.Private.Reflection.Execution', '--initassembly:System.Private.StackTraceMetadata', '--feature:System.Globalization.Invariant=true', '--feature:System.Diagnostics.Tracing.EventSource.IsSupported=false', '--feature:System.Diagnostics.Debugger.IsSupported=false')
$arguments += '--directpinvoke:System.Native'
$assemblies = @(Get-ChildItem -LiteralPath (Join-Path $pack 'lib/net10.0') -Filter '*.dll') + @(Get-ChildItem -LiteralPath $native -Filter '*.dll')
# $input is a PowerShell automatic pipeline variable. Using it in this filter
# can discard every dependency when this script is called by BuildSystem.
$assemblies += @(Get-ChildItem -LiteralPath $applicationOutput -Filter '*.dll' | Where-Object { $_.FullName -ne $managedInputPath -and $_.Name -notlike 'System.*' })
$managedDependencies=Assert-RuntimeManagedDependencies $managedInputPath @($assemblies.FullName)
foreach ($assembly in $assemblies) { $arguments += '-r:"' + $assembly.FullName + '"' }
$assemblyHashes=[ordered]@{}
foreach($path in (@($managedInputPath)+@($assemblies.FullName) | Sort-Object -Unique)) { $assemblyHashes[$path]=Get-RuntimeInputHash $path }
$response = Join-Path $OutputDirectory 'Ilc.rsp'
[IO.File]::WriteAllLines($response, $arguments, [Text.UTF8Encoding]::new($false))
$ErrorActionPreference = 'Continue'
& $ilc ('@' + $response) > (Join-Path $OutputDirectory 'Ilc.log') 2>&1
$ilcExit = $LASTEXITCODE
$ErrorActionPreference = 'Stop'
if ($ilcExit -ne 0) { throw 'NativeAOT ELF compilation failed; see Ilc.log.' }
# ILC may return zero after emitting IL1005 and replacing Main with an
# unconditional TypeLoader exception. Such an object is not a successful build.
Assert-RuntimeIlcDiagnostics (Join-Path $OutputDirectory 'Ilc.log')
& (Join-Path $llvm 'llvm-readobj.exe') --file-headers --sections $object > (Join-Path $OutputDirectory 'ElfObject.txt')
$combined = Join-Path $OutputDirectory 'RuntimeAndProbe.o'
$libraries = @('libbootstrapper.o', 'libRuntime.WorkstationGC.a', 'libRuntime.VxsortDisabled.a', 'libaotminipal.a', 'libeventpipe-disabled.a', 'libstandalonegc-disabled.a', 'libstdc++compat.a') | ForEach-Object { Join-Path $native $_ }
& (Join-Path $llvm 'ld.lld.exe') -r -u main $object @libraries -o $combined > (Join-Path $OutputDirectory 'PartialLink.log') 2>&1
if ($LASTEXITCODE -ne 0) { throw 'Relocatable runtime link failed; see PartialLink.log.' }
$symbols = @(& (Join-Path $llvm 'llvm-nm.exe') --undefined-only --format=posix $combined | ForEach-Object { ($_ -split ' ')[0] } | Sort-Object -Unique)
[IO.File]::WriteAllLines((Join-Path $OutputDirectory 'RequiredNativeSymbols.txt'), $symbols, [Text.UTF8Encoding]::new($false))
& (Join-Path $llvm 'llvm-readobj.exe') --sections --relocations $combined > (Join-Path $OutputDirectory 'RuntimeSectionsAndRelocations.txt')
$ErrorActionPreference = 'Continue'
$linkOutput = @(& (Join-Path $llvm 'ld.lld.exe') -static -nostdlib --error-limit=0 -e main $object @libraries -o (Join-Path $OutputDirectory 'UnsupportedWithoutPal.elf') 2>&1)
$linkExit = $LASTEXITCODE
$ErrorActionPreference = 'Stop'
[IO.File]::WriteAllLines((Join-Path $OutputDirectory 'MissingPalLink.log'), @($linkOutput | ForEach-Object { $_.ToString() }), [Text.UTF8Encoding]::new($false))
$actualMissing = @($linkOutput | ForEach-Object { if ($_.ToString() -match '^ld.lld: error: undefined symbol: (.+)$') { $Matches[1] } } | Sort-Object -Unique)
[IO.File]::WriteAllLines((Join-Path $OutputDirectory 'ActualMissingLinkSymbols.txt'), $actualMissing, [Text.UTF8Encoding]::new($false))
Assert-RuntimeSourceInputs $taskRoot $sourceHashes
if($tlsEntropyPort) {$null=Assert-XfeNativeEntropyPort $taskRoot $tlsEntropyPort}
foreach($entry in $assemblyHashes.GetEnumerator()) { if((Get-RuntimeInputHash $entry.Key) -cne $entry.Value) { throw ('A compiler input assembly changed: '+$entry.Key) } }
if((Get-RuntimeInputHash $managedDependencies.Path) -cne $managedDependencies.Sha256) { throw 'The managed dependency manifest changed during compilation.' }
$receipt = [ordered]@{
    Schema = 'XfeIndependentNativeRuntimeProbe1'; MicrosoftRuntimeVersion = $version
    Toolchain = 'Microsoft NativeAOT ILCompiler / LLVM'; Target = 'System V x86_64 ELF'
    CosmosReferenced = $false; ManagedBuildPassed = $true; ElfObjectGenerated = $true
    NativeAotAnalysisPassed = $true; ManagedDependenciesVerified = $true
    ManagedDependencyManifest = $managedDependencies
    OfficialRuntimeRelocatableLinkPassed = $true; FinalExecutableLinkExitCode = $linkExit
    FinalExecutableSupported = ($linkExit -eq 0); NativeGuestTested = $false
    UndefinedObjectSymbolCount = $symbols.Count; UndefinedObjectSymbols = $symbols
    MissingNativeSymbolCount = $actualMissing.Count; MissingNativeSymbols = $actualMissing
    ObjectSha256 = (Get-FileHash -LiteralPath $object -Algorithm SHA256).Hash.ToLowerInvariant()
    SourceSha256 = $sourceHashes; AssemblySha256 = $assemblyHashes
    NativeTlsEntropyPort = $tlsEntropyPort
    CompilerSha256 = (Get-RuntimeInputHash $ilc); LlvmLinkerSha256 = (Get-RuntimeInputHash (Join-Path $llvm 'ld.lld.exe'))
    ProjectPath = $project; DotNetSdkVersion = (& dotnet --version)
    RuntimeSha256 = (Get-FileHash -LiteralPath (Join-Path $native 'libRuntime.WorkstationGC.a') -Algorithm SHA256).Hash.ToLowerInvariant()
    ObjectPath = $object; RequiredNativeSymbolsPath = (Join-Path $OutputDirectory 'RequiredNativeSymbols.txt')
    Limitation = 'Cross compilation and symbol inventory only. No PAL, guest initialization, collection, exception or thread execution has passed.'
}
$receipt | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $OutputDirectory 'ProbeReceipt.json') -Encoding UTF8
Write-Output ('NativeAOT ELF object generated; actual missing link symbols: ' + $actualMissing.Count + '; final link exit: ' + $linkExit)
Write-Output ('Receipt: ' + (Join-Path $OutputDirectory 'ProbeReceipt.json'))