Skip to content

Commit

Permalink
New Invalid ISIL Instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
ds5678 authored and SamboyCoding committed Jun 19, 2024
1 parent d9e95e7 commit 82e36b7
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 54 deletions.
13 changes: 0 additions & 13 deletions Cpp2IL.Core/Exceptions/IsilConversionException.cs

This file was deleted.

9 changes: 8 additions & 1 deletion Cpp2IL.Core/ISIL/InstructionSetIndependentInstruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,11 @@ public InstructionSetIndependentInstruction(InstructionSetIndependentOpCode opCo
}

public override string ToString() => $"{InstructionIndex:000} {OpCode} {string.Join(", ", (IEnumerable<InstructionSetIndependentOperand>) Operands)}";
}

public void MakeInvalid(string reason)
{
OpCode = InstructionSetIndependentOpCode.Invalid;
Operands = [InstructionSetIndependentOperand.MakeImmediate(reason)];
FlowControl = IsilFlowControl.Continue;
}
}
12 changes: 10 additions & 2 deletions Cpp2IL.Core/ISIL/InstructionSetIndependentOpCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class InstructionSetIndependentOpCode

public static readonly InstructionSetIndependentOpCode NotImplemented = new(IsilMnemonic.NotImplemented, 1, InstructionSetIndependentOperand.OperandType.Immediate);

public static readonly InstructionSetIndependentOpCode Invalid = new(IsilMnemonic.Invalid, 1, InstructionSetIndependentOperand.OperandType.Immediate);


public readonly IsilMnemonic Mnemonic;
public readonly InstructionSetIndependentOperand.OperandType[] PermittedOperandTypes;
Expand Down Expand Up @@ -76,15 +78,21 @@ public void Validate(InstructionSetIndependentInstruction instruction)
var operands = instruction.Operands;

if (operands.Length > MaxOperands)
throw new($"Too many operands! We have {operands.Length} but we only allow {MaxOperands}");
{
instruction.MakeInvalid($"Too many operands! We have {operands.Length} but we only allow {MaxOperands}");
return;
}

if (PermittedOperandTypes.Length == 0)
return;

for (var i = 0; i < operands.Length; i++)
{
if ((operands[i].Type & PermittedOperandTypes[i]) == 0)
throw new($"Instruction {instruction}: Operand {operands[i]} at index {i} (0-based) is of type {operands[i].Type}, which is not permitted for this index of a {Mnemonic} instruction");
{
instruction.MakeInvalid($"Operand {operands[i]} at index {i} (0-based) is of type {operands[i].Type}, which is not permitted for this index of a {Mnemonic} instruction");
return;
}
}
}

Expand Down
20 changes: 9 additions & 11 deletions Cpp2IL.Core/ISIL/IsilBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,13 @@ public IsilBuilder(List<InstructionSetIndependentInstruction> backingStatementLi

private void AddInstruction(InstructionSetIndependentInstruction instruction)
{
if (InstructionAddressMap.ContainsKey(instruction.ActualAddress))
if (InstructionAddressMap.TryGetValue(instruction.ActualAddress, out var list))
{
InstructionAddressMap[instruction.ActualAddress].Add(instruction);
list.Add(instruction);
}
else
{
var newList = new List<InstructionSetIndependentInstruction>();
newList.Add(instruction);
InstructionAddressMap[instruction.ActualAddress] = newList;
InstructionAddressMap[instruction.ActualAddress] = [ instruction ];
}
BackingStatementList.Add(instruction);
instruction.InstructionIndex = (uint)BackingStatementList.Count;
Expand All @@ -51,17 +49,15 @@ public void FixJumps()
if (InstructionAddressMap.TryGetValue(tuple.Item2, out var list))
{
var target = list.First();
if (target is null)
throw new IsilConversionException("This can't ever happen");

if (target.Equals(tuple.Item1))
throw new IsilConversionException("Invalid jump target for instruction: Instruction can't jump to itself");

tuple.Item1.Operands = new[] { InstructionSetIndependentOperand.MakeInstruction(target) };
tuple.Item1.MakeInvalid("Invalid jump target for instruction: Instruction can't jump to itself");
else
tuple.Item1.Operands = [InstructionSetIndependentOperand.MakeInstruction(target)];
}
else
{
throw new IsilConversionException("Jump target not found in method. Ruh roh");
tuple.Item1.MakeInvalid("Jump target not found in method.");
}
}
}
Expand Down Expand Up @@ -124,6 +120,8 @@ private void CreateJump(ulong instructionAddress, ulong target, InstructionSetIn

public void NotImplemented(ulong instructionAddress, string text) => AddInstruction(new(InstructionSetIndependentOpCode.NotImplemented, instructionAddress, IsilFlowControl.Continue, InstructionSetIndependentOperand.MakeImmediate(text)));

public void Invalid(ulong instructionAddress, string text) => AddInstruction(new(InstructionSetIndependentOpCode.Invalid, instructionAddress, IsilFlowControl.Continue, InstructionSetIndependentOperand.MakeImmediate(text)));

public void Interrupt(ulong instructionAddress) => AddInstruction(new(InstructionSetIndependentOpCode.Interrupt, instructionAddress, IsilFlowControl.Interrupt));

private InstructionSetIndependentOperand[] PrepareCallOperands(ulong dest, InstructionSetIndependentOperand[] args)
Expand Down
3 changes: 2 additions & 1 deletion Cpp2IL.Core/ISIL/IsilMnemonic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ public enum IsilMnemonic
JumpIfLessOrEqual,
SignExtend,
Interrupt,
NotImplemented
NotImplemented,
Invalid,
}
27 changes: 15 additions & 12 deletions Cpp2IL.Core/ProcessingLayers/CallAnalysisProcessingLayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ private static void InjectAttribute(ApplicationAnalysisContext appContext)
const string Namespace = "Cpp2ILInjected.CallAnalysis";

var deduplicatedMethodAttributes = AttributeInjectionUtils.InjectZeroParameterAttribute(appContext, Namespace, "DeduplicatedMethodAttribute", AttributeTargets.Method, false);
var analysisFailedAttributes = AttributeInjectionUtils.InjectZeroParameterAttribute(appContext, Namespace, "CallAnalysisFailedAttribute", AttributeTargets.Method, false);
var invalidInstructionsAttributes = AttributeInjectionUtils.InjectZeroParameterAttribute(appContext, Namespace, "ContainsInvalidInstructionsAttribute", AttributeTargets.Method, false);
var unimplementedInstructionsAttributes = AttributeInjectionUtils.InjectZeroParameterAttribute(appContext, Namespace, "ContainsUnimplementedInstructionsAttribute", AttributeTargets.Method, false);
var analysisNotSupportedAttributes = AttributeInjectionUtils.InjectZeroParameterAttribute(appContext, Namespace, "CallAnalysisNotSupportedAttribute", AttributeTargets.Method, false);

var callsDeduplicatedMethodsAttributes = AttributeInjectionUtils.InjectOneParameterAttribute(appContext, Namespace, "CallsDeduplicatedMethodsAttribute", AttributeTargets.Method, false, appContext.SystemTypes.SystemInt32Type, "Count");
Expand All @@ -50,7 +51,8 @@ private static void InjectAttribute(ApplicationAnalysisContext appContext)

foreach (var assemblyAnalysisContext in appContext.Assemblies)
{
var analysisFailedConstructor = analysisFailedAttributes[assemblyAnalysisContext];
var invalidInstructionsConstructor = invalidInstructionsAttributes[assemblyAnalysisContext];
var unimplementedInstructionsConstructor = unimplementedInstructionsAttributes[assemblyAnalysisContext];
var analysisNotSupportedConstructor = analysisNotSupportedAttributes[assemblyAnalysisContext];
var deduplicatedMethodConstructor = deduplicatedMethodAttributes[assemblyAnalysisContext];

Expand All @@ -65,16 +67,7 @@ private static void InjectAttribute(ApplicationAnalysisContext appContext)
AttributeInjectionUtils.AddZeroParameterAttribute(m, deduplicatedMethodConstructor);
}

try
{
m.Analyze();
}
catch
{
m.ConvertedIsil = null;
AttributeInjectionUtils.AddZeroParameterAttribute(m, analysisFailedConstructor);
continue;
}
m.Analyze();

if (m.ConvertedIsil is { Count: 0 })
{
Expand All @@ -85,6 +78,16 @@ private static void InjectAttribute(ApplicationAnalysisContext appContext)
continue;
}

if (m.ConvertedIsil.Any(i => i.OpCode == InstructionSetIndependentOpCode.Invalid))
{
AttributeInjectionUtils.AddZeroParameterAttribute(m, invalidInstructionsConstructor);
}

if (m.ConvertedIsil.Any(i => i.OpCode == InstructionSetIndependentOpCode.NotImplemented))
{
AttributeInjectionUtils.AddZeroParameterAttribute(m, unimplementedInstructionsConstructor);
}

foreach (var instruction in m.ConvertedIsil)
{
if (instruction.OpCode != InstructionSetIndependentOpCode.Call && instruction.OpCode != InstructionSetIndependentOpCode.CallNoReturn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,7 @@ private static void AnalyzeMethod(ApplicationAnalysisContext appContext, MethodA
if (m.UnderlyingPointer == 0)
return;

try
{
m.Analyze();
}
catch (Exception ex)
{
#if DEBUG
if (ex.Message is not "Failed to convert to ISIL. Reason: Jump target not found in method. Ruh roh" && !ex.Message.StartsWith("Instruction "))
{
}
#endif
m.ConvertedIsil = null;
return;
}
m.Analyze();

if (m.ConvertedIsil is { Count: 0 })
{
Expand Down

0 comments on commit 82e36b7

Please sign in to comment.