示例#1
0
文件: ILOp.cs 项目: Orvid/Cosmos
 public static string GetLabel(MethodInfo aMethod, ILOpCode aOpCode) {
   return GetLabel(aMethod, aOpCode.Position);
 }
示例#2
0
文件: ILOp.cs 项目: Orvid/Cosmos
 // This is called execute and not assemble, as the scanner
 // could be used for other things, profiling, analysis, reporting, etc
 public abstract void Execute(MethodInfo aMethod, ILOpCode aOpCode);
示例#3
0
文件: ILOp.cs 项目: Orvid/Cosmos
    public static void EmitExceptionLogic(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup, string aJumpTargetNoException = null) {
      if (aJumpTargetNoException == null)
      {
        aJumpTargetNoException = ILOp.GetLabel(aMethodInfo, aCurrentOpCode.NextPosition);
      }
      string xJumpTo = null;
      if (aCurrentOpCode != null && aCurrentOpCode.CurrentExceptionHandler != null) {
        // todo add support for nested handlers, see comment in Engine.cs
        //if (!((aMethodInfo.CurrentHandler.HandlerOffset < aCurrentOpOffset) || (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset)) {
        new Comment(String.Format("CurrentOffset = {0}, HandlerStartOffset = {1}", aCurrentOpCode.Position, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset));
        if (aCurrentOpCode.CurrentExceptionHandler.HandlerOffset > aCurrentOpCode.Position) {
          switch (aCurrentOpCode.CurrentExceptionHandler.Flags) {
            case ExceptionHandlingClauseOptions.Clause: {
                xJumpTo = ILOp.GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset);
                break;
              }
            case ExceptionHandlingClauseOptions.Finally: {
                xJumpTo = ILOp.GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset);
                break;
              }
            default: {
                throw new Exception("ExceptionHandlerType '" + aCurrentOpCode.CurrentExceptionHandler.Flags.ToString() + "' not supported yet!");
              }
          }
        }
      }
      // if aDoTest is true, we check ECX for exception flags
      if (!aDoTest) {
        //new CPU.Call("_CODE_REQUESTED_BREAK_");
        if (xJumpTo == null) {
          Jump_Exception(aMethodInfo);
        } else {
          new CPU.Jump { DestinationLabel = xJumpTo };
        }

      } else {
        new CPU.Test { DestinationReg = CPU.Registers.ECX, SourceValue = 2 };

        if (aCleanup != null) {
          new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Equal, DestinationLabel = aJumpTargetNoException };
          aCleanup();
          if (xJumpTo == null) {
            new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = GetMethodLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException };
          } else {
            new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = xJumpTo };
          }
        } else {
          if (xJumpTo == null) {
            new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = GetMethodLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException };
          } else {
            new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = xJumpTo };
          }
        }
      }
    }
示例#4
0
        protected void EmitTracer(MethodInfo aMethod, ILOpCode aOp, string aNamespace, bool emitInt3NotNop, out bool INT3Emitted, out bool INT3PlaceholderEmitted, bool isNewSourcePoint)
        {
            // NOTE - These if statements can be optimized down - but clarity is
            // more important than the optimizations. Furthermore the optimizations available
            // would not offer much benefit

            // Determine if a new DebugStub should be emitted

            INT3Emitted = false;
            INT3PlaceholderEmitted = false;

            if (aOp.OpCode == ILOpCode.Code.Nop)
            {
                // Skip NOOP's so we dont have breakpoints on them
                //TODO: Each IL op should exist in IL, and descendants in IL.X86.
                // Because of this we have this hack
                return;
            }
            else if (DebugEnabled == false)
            {
                return;
            }
            else if (DebugMode == DebugMode.Source)
            {
                // If the current position equals one of the offsets, then we have
                // reached a new atomic C# statement
                if (!isNewSourcePoint)
                {
                    return;
                }
            }

            // Check if the DebugStub has been disabled for this method
            if ((!IgnoreDebugStubAttribute) && (aMethod.DebugStubOff))
            {
                return;
            }

            // This test fixes issue #15638
            if (null != aNamespace)
            {
                // Check options for Debug Level
                // Set based on TracedAssemblies
                if (TraceAssemblies > TraceAssemblies.None)
                {
                    if (TraceAssemblies < TraceAssemblies.All)
                    {
                        if (aNamespace.StartsWith("System.", StringComparison.InvariantCultureIgnoreCase))
                        {
                            return;
                        }
                        if (aNamespace.ToLower() == "system")
                        {
                            return;
                        }
                        if (aNamespace.StartsWith("Microsoft.", StringComparison.InvariantCultureIgnoreCase))
                        {
                            return;
                        }
                    }

                    if (TraceAssemblies < TraceAssemblies.Cosmos)
                    {
                        //TODO: Maybe an attribute that could be used to turn tracing on and off
                        if (aNamespace.StartsWith("Cosmos.", StringComparison.InvariantCultureIgnoreCase))
                        {
                            return;
                        }
                    }
                }
                else
                {
                    return;
                }
            }
            else
            {
                return;
            }
            // If we made it this far without a return, emit the Tracer
            // We used to emit an INT3, but this meant the DS would brwak after every C# line
            // Breaking that frequently is of course, pointless and slow.
            // So now we emit mostly NOPs and only put an INT3 when told to.
            // We should only be told to put an INT3 at the start of method but this may change so search for more comments on this.
            if (emitInt3NotNop)
            {
                INT3Emitted = true;
                new INT3();
            }
            else
            {
                INT3PlaceholderEmitted = true;
                new DebugNoop();
            }
        }
示例#5
0
文件: ILOp.cs 项目: iSalva/Cosmos
 public static void EmitExceptionLogic(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup) {
   EmitExceptionLogic(aAssembler, aMethodInfo, aCurrentOpCode, aDoTest, aCleanup, ILOp.GetLabel(aMethodInfo, aCurrentOpCode.NextPosition));
 }
示例#6
0
        protected void BeforeOp(MethodInfo aMethod, ILOpCode aOpCode, bool emitInt3NotNop, out bool INT3Emitted, bool hasSourcePoint)
        {
            string xLabel = TmpPosLabel(aMethod, aOpCode);
            Assembler.CurrentIlLabel = xLabel;
            new Cosmos.Assembler.Label(xLabel);

            if (aMethod.MethodBase.DeclaringType != typeof(VTablesImpl))
            {
                Assembler.EmitAsmLabels = false;
                try
                {
                    //Assembler.WriteDebugVideo(String.Format("Method {0}:{1}.", aMethod.UID, aOpCode.Position.ToString("X")));
                    //Assembler.WriteDebugVideo(xLabel);
                }
                finally
                {
                    Assembler.EmitAsmLabels = true;
                }
            }

            uint? xStackDifference = null;

            if (mSymbols != null)
            {
                var xMLSymbol = new MethodIlOp();
                xMLSymbol.LabelName = xLabel;

                var xStackSize = aOpCode.StackOffsetBeforeExecution.Value;

                xMLSymbol.StackDiff = -1;
                if (aMethod.MethodBase != null)
                {
                    var xBody = aMethod.MethodBase.GetMethodBody();
                    if (xBody != null)
                    {
                        var xLocalsSize = (from item in xBody.LocalVariables
                                           select ILOp.Align(ILOp.SizeOfType(item.LocalType), 4)).Sum();
                        xMLSymbol.StackDiff = checked((int)(xLocalsSize + xStackSize));
                        xStackDifference = (uint?)xMLSymbol.StackDiff;
                    }
                }
                xMLSymbol.IlOffset = aOpCode.Position;
                xMLSymbol.MethodID = mCurrentMethodGuid;

                mSymbols.Add(xMLSymbol);
                DebugInfo.AddSymbols(mSymbols);
            }
            DebugInfo.AddSymbols(mSymbols, false);

            bool INT3PlaceholderEmitted = false;
            EmitTracer(aMethod, aOpCode, aMethod.MethodBase.DeclaringType.Namespace, emitInt3NotNop, out INT3Emitted, out INT3PlaceholderEmitted, hasSourcePoint);

            if (INT3Emitted || INT3PlaceholderEmitted)
            {
                var xINT3Label = new INT3Label();
                xINT3Label.LabelName = xLabel;
                xINT3Label.MethodID = mCurrentMethodGuid;
                xINT3Label.LeaveAsINT3 = INT3Emitted;
                mINT3Labels.Add(xINT3Label);
                DebugInfo.AddINT3Labels(mINT3Labels);
            }

            if (DebugEnabled && StackCorruptionDetection && StackCorruptionDetectionLevel == StackCorruptionDetectionLevel.AllInstructions)
            {
                // if debugstub is active, emit a stack corruption detection. at this point, the difference between EBP and ESP
                // should be equal to the local variables sizes and the IL stack.
                // if not, we should break here.

                // first, calculate the expected difference
                if (xStackDifference == null)
                {
                    xStackDifference = aMethod.LocalVariablesSize;
                    xStackDifference += aOpCode.StackOffsetBeforeExecution;
                }

                new Comment("Stack difference = " + xStackDifference);

                // if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
                // if not, we should somehow break here.
                new Mov { DestinationReg = Registers.EAX, SourceReg = RegistersEnum.ESP };
                new Mov { DestinationReg = Registers.EBX, SourceReg = RegistersEnum.EBP };
                if (xStackDifference != 0)
                {
                    new Add { DestinationReg = Registers.EAX, SourceValue = xStackDifference };
                }
                new Compare { SourceReg = RegistersEnum.EAX, DestinationReg = RegistersEnum.EBX };
                new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabel + ".StackCorruptionCheck_End" };
                new ClearInterruptFlag();
                // don't remove the call. It seems pointless, but we need it to retrieve the EIP value
                new Call { DestinationLabel = xLabel + ".StackCorruptionCheck_GetAddress" };
                new Assembler.Label(xLabel + ".StackCorruptionCheck_GetAddress");
                new Pop { DestinationReg = RegistersEnum.EAX };
                new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
                new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
                new Halt();
                new Assembler.Label(xLabel + ".StackCorruptionCheck_End");

            }
        }
示例#7
0
 protected void AfterOp(MethodInfo aMethod, ILOpCode aOpCode)
 {
 }
示例#8
0
 public static string TmpBranchLabel(MethodInfo aMethod, ILOpCode aOpCode)
 {
     return TmpPosLabel(aMethod, ((ILOpCodes.OpBranch)aOpCode).Value);
 }
示例#9
0
 public OpCodeAttribute(ILOpCode.Code OpCode)
 {
     this.opCode = OpCode;
 }
示例#10
0
文件: ILOpCode.cs 项目: iSalva/Cosmos
 protected void InterpretInstruction(ILOpCode xNextOpCode, IDictionary<int, ILOpCode> aOpCodes, Stack<Type> aStack, ref bool aSituationChanged, int aMaxRecursionDepth)
 {
   xNextOpCode.InterpretStackTypes(aOpCodes, aStack, ref aSituationChanged, aMaxRecursionDepth - 1);
 }