|
|
|
@ -17,6 +17,7 @@
@@ -17,6 +17,7 @@
|
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.ComponentModel.Composition; |
|
|
|
|
using System.Diagnostics; |
|
|
|
|
using System.Reflection.Metadata; |
|
|
|
@ -73,17 +74,13 @@ namespace ICSharpCode.ILSpy.ReadyToRun
@@ -73,17 +74,13 @@ namespace ICSharpCode.ILSpy.ReadyToRun
|
|
|
|
|
Debug.Assert(reader.Machine == Machine.I386); |
|
|
|
|
bitness = 32; |
|
|
|
|
} |
|
|
|
|
foreach (ReadyToRunMethod readyToRunMethod in reader.Methods) { |
|
|
|
|
if (readyToRunMethod.MethodHandle == method.MetadataToken) { |
|
|
|
|
// TODO: Indexing
|
|
|
|
|
foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions) { |
|
|
|
|
WriteCommentLine(output, readyToRunMethod.SignatureString); |
|
|
|
|
byte[] code = new byte[runtimeFunction.Size]; |
|
|
|
|
for (int i = 0; i < runtimeFunction.Size; i++) { |
|
|
|
|
code[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; |
|
|
|
|
foreach (List<ReadyToRunMethod> readyToRunMethodList in reader.Methods.Values) { |
|
|
|
|
foreach (ReadyToRunMethod readyToRunMethod in readyToRunMethodList) { |
|
|
|
|
if (readyToRunMethod.MethodHandle == method.MetadataToken) { |
|
|
|
|
// TODO: Indexing
|
|
|
|
|
foreach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions) { |
|
|
|
|
Disassemble(output, reader, readyToRunMethod, runtimeFunction, bitness, (ulong)runtimeFunction.StartAddress); |
|
|
|
|
} |
|
|
|
|
Disassemble(output, code, bitness, (ulong)runtimeFunction.StartAddress); |
|
|
|
|
output.WriteLine(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -95,8 +92,14 @@ namespace ICSharpCode.ILSpy.ReadyToRun
@@ -95,8 +92,14 @@ namespace ICSharpCode.ILSpy.ReadyToRun
|
|
|
|
|
output.WriteLine("; " + comment); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void Disassemble(ITextOutput output, byte[] codeBytes, int bitness, ulong address) |
|
|
|
|
private void Disassemble(ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address) |
|
|
|
|
{ |
|
|
|
|
WriteCommentLine(output, readyToRunMethod.SignatureString); |
|
|
|
|
byte[] codeBytes = new byte[runtimeFunction.Size]; |
|
|
|
|
for (int i = 0; i < runtimeFunction.Size; i++) { |
|
|
|
|
codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO: Decorate the disassembly with Unwind, GC and debug info
|
|
|
|
|
var codeReader = new ByteArrayCodeReader(codeBytes); |
|
|
|
|
var decoder = Decoder.Create(bitness, codeReader); |
|
|
|
@ -120,11 +123,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun
@@ -120,11 +123,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun
|
|
|
|
|
formatter.Options.FirstOperandCharIndex = 10; |
|
|
|
|
var tempOutput = new StringBuilderFormatterOutput(); |
|
|
|
|
foreach (var instr in instructions) { |
|
|
|
|
int byteBaseIndex = (int)(instr.IP - address); |
|
|
|
|
formatter.Format(instr, tempOutput); |
|
|
|
|
output.Write(instr.IP.ToString("X16")); |
|
|
|
|
output.Write(" "); |
|
|
|
|
int instrLen = instr.ByteLength; |
|
|
|
|
int byteBaseIndex = (int)(instr.IP - address); |
|
|
|
|
for (int i = 0; i < instrLen; i++) |
|
|
|
|
output.Write(codeBytes[byteBaseIndex + i].ToString("X2")); |
|
|
|
|
int missingBytes = 10 - instrLen; |
|
|
|
@ -133,6 +136,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
@@ -133,6 +136,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
|
|
|
|
|
output.Write(" "); |
|
|
|
|
output.WriteLine(tempOutput.ToStringAndReset()); |
|
|
|
|
} |
|
|
|
|
output.WriteLine(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, PEFile module) |
|
|
|
@ -142,7 +146,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun
@@ -142,7 +146,6 @@ namespace ICSharpCode.ILSpy.ReadyToRun
|
|
|
|
|
if (!readyToRunReaders.TryGetValue(module, out result)) { |
|
|
|
|
result = new ReadyToRunReaderCacheEntry(); |
|
|
|
|
try { |
|
|
|
|
// TODO: avoid eager parsing
|
|
|
|
|
result.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), module.Metadata, module.Reader, module.FileName); |
|
|
|
|
if (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386) { |
|
|
|
|
result.failureReason = $"Architecture {result.readyToRunReader.Machine} is not currently supported."; |
|
|
|
|