Browse Source

Display ReadyToRun header information

pull/1914/head
Andrew Au 5 years ago
parent
commit
581807ca0f
  1. 2
      ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj
  2. 63
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs

2
ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj

@ -57,7 +57,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Iced" Version="1.4.0" /> <PackageReference Include="Iced" Version="1.4.0" />
<PackageReference Include="ILCompiler.Reflection.ReadyToRun" Version="1.0.3-alpha" /> <PackageReference Include="ILCompiler.Reflection.ReadyToRun" Version="1.0.4-alpha" />
</ItemGroup> </ItemGroup>
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" /> <Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" />

63
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
[Export(typeof(Language))] [Export(typeof(Language))]
internal class ReadyToRunLanguage : Language internal class ReadyToRunLanguage : Language
{ {
private static readonly ConditionalWeakTable<PEFile, R2RReaderCacheEntry> r2rReaders = new ConditionalWeakTable<PEFile, R2RReaderCacheEntry>(); private static readonly ConditionalWeakTable<PEFile, ReadyToRunReaderCacheEntry> readyToRunReaders = new ConditionalWeakTable<PEFile, ReadyToRunReaderCacheEntry>();
public override string Name => "ReadyToRun"; public override string Name => "ReadyToRun";
public override string FileExtension { public override string FileExtension {
@ -44,16 +44,15 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{ {
PEFile module = assembly.GetPEFileOrNull(); PEFile module = assembly.GetPEFileOrNull();
R2RReaderCacheEntry r2rReaderCacheEntry = GetReader(assembly, module); ReadyToRunReaderCacheEntry cacheEntry = GetReader(assembly, module);
if (r2rReaderCacheEntry.r2rReader == null) { if (cacheEntry.readyToRunReader == null) {
WriteCommentLine(output, r2rReaderCacheEntry.failureReason); WriteCommentLine(output, cacheEntry.failureReason);
} else { } else {
R2RReader reader = r2rReaderCacheEntry.r2rReader; ReadyToRunReader reader = cacheEntry.readyToRunReader;
WriteCommentLine(output, "TODO - display ready to run information"); WriteCommentLine(output, reader.Machine.ToString());
// TODO: display other header information WriteCommentLine(output, reader.OperatingSystem.ToString());
foreach (var method in reader.R2RMethods) { WriteCommentLine(output, reader.CompilerIdentifier);
WriteCommentLine(output, method.SignatureString); WriteCommentLine(output, "TODO - display more header information");
}
} }
return base.DecompileAssembly(assembly, output, options); return base.DecompileAssembly(assembly, output, options);
@ -62,11 +61,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)
{ {
PEFile module = method.ParentModule.PEFile; PEFile module = method.ParentModule.PEFile;
R2RReaderCacheEntry r2rReaderCacheEntry = GetReader(module.GetLoadedAssembly(), module); ReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);
if (r2rReaderCacheEntry.r2rReader == null) { if (cacheEntry.readyToRunReader == null) {
WriteCommentLine(output, r2rReaderCacheEntry.failureReason); WriteCommentLine(output, cacheEntry.failureReason);
} else { } else {
R2RReader reader = r2rReaderCacheEntry.r2rReader; ReadyToRunReader reader = cacheEntry.readyToRunReader;
int bitness = -1; int bitness = -1;
if (reader.Machine == Machine.Amd64) { if (reader.Machine == Machine.Amd64) {
bitness = 64; bitness = 64;
@ -74,11 +73,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun
Debug.Assert(reader.Machine == Machine.I386); Debug.Assert(reader.Machine == Machine.I386);
bitness = 32; bitness = 32;
} }
foreach (var m in reader.R2RMethods) { foreach (ReadyToRunMethod readyToRunMethod in reader.Methods) {
if (m.MethodHandle == method.MetadataToken) { if (readyToRunMethod.MethodHandle == method.MetadataToken) {
// TODO: Indexing // TODO: Indexing
foreach (RuntimeFunction runtimeFunction in m.RuntimeFunctions) { foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions) {
WriteCommentLine(output, m.SignatureString); WriteCommentLine(output, readyToRunMethod.SignatureString);
byte[] code = new byte[runtimeFunction.Size]; byte[] code = new byte[runtimeFunction.Size];
for (int i = 0; i < runtimeFunction.Size; i++) { for (int i = 0; i < runtimeFunction.Size; i++) {
code[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; code[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
@ -136,32 +135,32 @@ namespace ICSharpCode.ILSpy.ReadyToRun
} }
} }
private R2RReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module) private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module)
{ {
R2RReaderCacheEntry result; ReadyToRunReaderCacheEntry result;
lock (r2rReaders) { lock (readyToRunReaders) {
if (!r2rReaders.TryGetValue(module, out result)) { if (!readyToRunReaders.TryGetValue(module, out result)) {
result = new R2RReaderCacheEntry(); result = new ReadyToRunReaderCacheEntry();
try { try {
// TODO: avoid eager parsing // TODO: avoid eager parsing
result.r2rReader = new R2RReader(new R2RAssemblyResolver(assembly), module.Metadata, module.Reader, module.FileName); result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), module.Metadata, module.Reader, module.FileName);
if (result.r2rReader.Machine != Machine.Amd64 && result.r2rReader.Machine != Machine.I386) { if (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386) {
result.failureReason = $"Architecture {result.r2rReader.Machine} is not currently supported."; result.failureReason = $"Architecture {result.readyToRunReader.Machine} is not currently supported.";
result.r2rReader = null; result.readyToRunReader = null;
} }
} catch (BadImageFormatException e) { } catch (BadImageFormatException e) {
result.failureReason = e.Message; result.failureReason = e.Message;
} }
r2rReaders.Add(module, result); readyToRunReaders.Add(module, result);
} }
} }
return result; return result;
} }
private class R2RAssemblyResolver : ILCompiler.Reflection.ReadyToRun.IAssemblyResolver private class ReadyToRunAssemblyResolver : ILCompiler.Reflection.ReadyToRun.IAssemblyResolver
{ {
private LoadedAssembly loadedAssembly; private LoadedAssembly loadedAssembly;
public R2RAssemblyResolver(LoadedAssembly loadedAssembly) public ReadyToRunAssemblyResolver(LoadedAssembly loadedAssembly)
{ {
this.loadedAssembly = loadedAssembly; this.loadedAssembly = loadedAssembly;
} }
@ -178,9 +177,9 @@ namespace ICSharpCode.ILSpy.ReadyToRun
} }
} }
private class R2RReaderCacheEntry private class ReadyToRunReaderCacheEntry
{ {
public R2RReader r2rReader; public ReadyToRunReader readyToRunReader;
public string failureReason; public string failureReason;
} }
} }

Loading…
Cancel
Save