Пример #1
0
 private bool IsTerminatingInstruction(CILInstruction cilInstr)
 {
     // Return or throw instructions are terminating instructions
     if (cilInstr is Instr) {
         if (((Instr)cilInstr).GetOp() == Op.ret) return true;
         if (((Instr)cilInstr).GetOp() == Op.throwOp) return true;
         if (((Instr)cilInstr).GetOp() == Op.rethrow) return true;
     }
     // jmp is a terminating instruction
     if (cilInstr is MethInstr) {
         if (((MethInstr)cilInstr).GetMethodOp() == MethodOp.jmp) return true;
     }
     return false;
 }
Пример #2
0
 /*------------------------- private methods ----------------------------*/
 private void AddToBuffer(CILInstruction inst)
 {
     if (tide >= buffer.Length) {
         CILInstruction[] tmp = buffer;
         buffer = new CILInstruction[tmp.Length * 2];
         for (int i=0; i < tide; i++) {
             buffer[i] = tmp[i];
         }
     }
     //Console.WriteLine("Adding instruction at offset " + offset + " with size " + inst.size);
     //inst.offset = offset;
     //offset += inst.size;
     inst.index = (uint)tide;
     buffer[tide++] = inst;
 }
Пример #3
0
 private void InsertInstructions(int ix, CILInstruction[] newInsts, int numNew)
 {
     CILInstruction[] newBuff = buffer, oldBuff = buffer;
     int newSize = tide + numNew - numReplace;
     if (buffer.Length < newSize) {
         newBuff = new CILInstruction[newSize];
         for (int i=0; i < ix; i++) {
             newBuff[i] = oldBuff[i];
         }
     }
     // shuffle up
     int offset = numNew-numReplace;
     int end = ix + numReplace;
     for (int i=tide-1; i >= end; i--) {
         newBuff[i+offset] = oldBuff[i];
     }
     // insert new instructions
     for (int i=0; i < numNew; i++) {
         newBuff[ix+i] = newInsts[i];
     }
     buffer = newBuff;
     tide += numNew - numReplace;
     UpdateIndexesFrom(ix);
 }
Пример #4
0
 internal void SetAndResolveInstructions(CILInstruction[] insts)
 {
     offset = 0;
     ArrayList labels = new ArrayList();
     for (int i=0; i < insts.Length; i++) {
         insts[i].offset = offset;
         offset += insts[i].size;
         if (insts[i] is BranchInstr) {
             ((BranchInstr)insts[i]).MakeTargetLabel(labels);
         } else if (insts[i] is SwitchInstr) {
             ((SwitchInstr)insts[i]).MakeTargetLabels(labels);
         }
     }
     if (exceptions != null) {
         for (int i=0; i < exceptions.Count; i++) {
             exceptions[i] = ((EHClause)exceptions[i]).MakeTryBlock(labels);
         }
     }
     if (labels.Count == 0) { buffer = insts; tide = buffer.Length; return; }
     buffer = new CILInstruction[insts.Length + labels.Count];
     int currentPos = 0;
     tide = 0;
     for (int i=0; i < labels.Count; i++) {
         CILLabel lab = (CILLabel)labels[i];
         while ((currentPos < insts.Length) && (insts[currentPos].offset < lab.offset))
             buffer[tide++] = insts[currentPos++];
         buffer[tide++] = lab;
     }
     while (currentPos < insts.Length) {
         buffer[tide++] = insts[currentPos++];
     }
 }
Пример #5
0
 /// <summary>
 /// Set the instruction to be the new array of instructions, this will replace
 /// any existing instructions.  This method cannot be called when in "insert" mode.
 /// </summary>
 /// <param name="insts">The new instructions</param>
 public void SetInstructions(CILInstruction[] insts)
 {
     if (inserting) throw new Exception("Cannot replace instructions during insert.");
     buffer = insts;
     tide = buffer.Length;
     for (int i=0; i < tide; i++) {
         if (insts[i] == null)
             tide = i;
         insts[i].index = (uint)i;
     }
 }
Пример #6
0
        /*
        private long GetOffset(int rva) {
          for (int i=0; i < inputSections.Length; i++) {
            long offs = inputSections[i].GetOffset(rva);
            if (offs > 0) return offs;
          }
          return 0;
        }

        public bool ReadPadding(int boundary) {
          while ((Position % boundary) != 0) {
            if (buffer[index++] != 0) { return false; }
          }
          return true;
        }

        public String ReadName() {
          int len = NAMELEN;
          char [] nameStr = new char[NAMELEN];
          char ch = (char)ReadByte();
          int i=0;
          for (; (i < NAMELEN) && (ch != '\0'); i++) {
            nameStr[i] = ch;
            ch = (char)ReadByte();
          }
          return new String(nameStr,0,i);
        }

        internal String ReadString() {
          char [] str = new char[STRLEN];
          int i=0;
          char ch = (char)ReadByte();
          for (; ch != '\0'; i++) {
            str[i] = ch;
            ch = (char)ReadByte();
          }
          return new String(str,0,i);
        }

        public long GetPos() {
          return BaseStream.Position;
        }

        public void SetPos(int ix) {
          BaseStream.Position = ix;
        }
        */
        /*
        public void SetToRVA(int rva) {
          index = PESection.GetOffset(rva);
        //      Console.WriteLine("Setting buffer to rva " + PEConsts.Hex(rva) + " = index " + PEConsts.Hex(index));
        //      Console.WriteLine("Setting buffer to rva " + rva + " = index " + index);
        }

        public byte[] GetBuffer() {
          return buffer;
        }
        */
        private CILInstruction[] DoByteCodes(uint len, MethodDef thisMeth)
        {
            uint pos = 0;
            ArrayList instrList = new ArrayList();
            //int instrIx = 0;
            while (pos < len) {
                uint offset = pos;
                uint opCode = ReadByte();
                pos++;
                IType iType = IType.op;
                if (opCode == 0xFE) {
                    uint ix = ReadByte();
                    pos++;
                    opCode = (opCode << 8) + ix;
                    iType = FileImage.longInstrMap[ix];
                } else
                    iType = FileImage.instrMap[opCode];
                if (Diag.DiagOn) Console.WriteLine("Got instruction type " + iType);
                CILInstruction nextInstr = null;
                if (iType == IType.specialOp) {
                    pos += 4;
                    if (Diag.DiagOn) Console.WriteLine("Got instruction " + Hex.Byte((int)opCode));
                    switch (opCode) {
                        case ((int)SpecialOp.ldc_i8) :
                            nextInstr = new LongInstr((SpecialOp)opCode,ReadInt64());
                            pos += 4; break;
                        case ((int)SpecialOp.ldc_r4) :
                            nextInstr = new FloatInstr((SpecialOp)opCode,ReadSingle());
                            break;
                        case ((int)SpecialOp.ldc_r8) :
                            nextInstr = new DoubleInstr((SpecialOp)opCode,ReadDouble());
                            pos += 4; break;
                        case ((int)SpecialOp.calli) :
                            nextInstr = new SigInstr((SpecialOp)opCode,(CalliSig)GetTokenElement(ReadUInt32()));
                            break;
                        case ((int)SpecialOp.Switch) : // switch
                            uint count = ReadUInt32();
                            int[] offsets = new int[count];
                            for (uint i=0; i < count; i++)
                                offsets[i] = ReadInt32();
                            pos += (4 * count);
                            nextInstr = new SwitchInstr(offsets);
                            break;
                        case ((int)SpecialOp.ldstr) : // ldstr
                            uint strIx = ReadUInt32();
                            strIx = strIx & FileImage.ElementMask;
                            nextInstr = new StringInstr((SpecialOp)opCode,userstring.GetUserString(strIx));
                            break;
                        case ((int)MethodOp.ldtoken) :
                            MetaDataElement elem = GetTokenElement(ReadUInt32());
                            if (elem is Method)
                                nextInstr = new MethInstr((MethodOp)opCode,(Method)elem);
                            else if (elem is Field)
                                nextInstr = new FieldInstr((FieldOp)opCode,(Field)elem);
                            else
                                nextInstr =new TypeInstr((TypeOp)opCode,(Type)elem);
                            break;
                    }
                } else if (iType == IType.branchOp) {
                    if (Diag.DiagOn) Console.WriteLine("Got instruction " + Hex.Byte((int)opCode));
                    if ((opCode < 0x38) || (opCode == 0xDE)) { // br or leave.s
                        nextInstr = new BranchInstr(opCode,ReadSByte());
                        pos++;
                    } else {
                        nextInstr = new BranchInstr(opCode,ReadInt32());
                        pos += 4;
                    }
                } else {
                    if (Diag.DiagOn) Console.Write(Hex.Byte((int)opCode));
                    switch (iType) {
                        case (IType.op) :
                            if (Diag.DiagOn) Console.WriteLine("Got instruction " + (Op)opCode);
                            nextInstr = new Instr((Op)opCode); break;
                        case (IType.methOp) :
                            if (Diag.DiagOn) Console.WriteLine("Got instruction " + (MethodOp)opCode);
                            nextInstr = new MethInstr((MethodOp)opCode,(Method)GetTokenElement(ReadUInt32()));
                            pos += 4;
                            break;
                        case (IType.typeOp) :
                            if (Diag.DiagOn) Console.WriteLine("Got instruction " + (TypeOp)opCode);
                            uint ttok = ReadUInt32();
                            Type typeToken = (Type)GetTokenElement(ttok);
                            if (typeToken is GenericParTypeSpec)
                                typeToken = ((GenericParTypeSpec)typeToken).GetGenericParam(thisMeth);
                            nextInstr = new TypeInstr((TypeOp)opCode,typeToken);
                            pos += 4;
                            break;
                        case (IType.fieldOp) :
                            if (Diag.DiagOn) Console.WriteLine("Got instruction " + (FieldOp)opCode);
                            nextInstr = new FieldInstr((FieldOp)opCode,(Field)GetTokenElement(ReadUInt32()));
                            pos += 4;
                            break;
                        case (IType.int8Op) :
                            nextInstr = new IntInstr((IntOp)opCode,ReadSByte());
                            pos++;
                            break;
                        case (IType.uint8Op) :
                            nextInstr = new UIntInstr((IntOp)opCode,ReadByte());
                            pos++;
                            break;
                        case (IType.uint16Op) :
                            nextInstr =new UIntInstr((IntOp)opCode,ReadUInt16());
                            pos++;
                            break;
                        case (IType.int32Op) :
                            nextInstr =new IntInstr((IntOp)opCode,ReadInt32());
                            pos += 4;
                            break;
                    }
                }
                if (nextInstr != null) nextInstr.Resolve();
                instrList.Add(nextInstr);
            }
            CILInstruction[] instrs = new CILInstruction[instrList.Count];
            for (int i=0; i < instrs.Length; i++) {
                instrs[i] = (CILInstruction)instrList[i];
            }
            return instrs;
        }
Пример #7
0
        public void Add(CILInstruction inst, uint offset)
        {
            while (_current < _buffer.Length && _buffer[_current].offset < offset)
             _debugBuffer.Add(_buffer[_current++]);
               if (_debugBuffer.Count > 0 && offset >= ((CILInstruction) _debugBuffer[_debugBuffer.Count - 1]).offset) {
             inst.offset = offset;
             _debugBuffer.Add(inst);
               } else {
             int i;

             for (i = 0; i < _debugBuffer.Count; i++)
               if (((CILInstruction) _debugBuffer[i]).offset > offset)
                 break;

             inst.offset = offset;
             _debugBuffer.Insert((i > 0 ? i - 1 : i), inst);
               }
        }
Пример #8
0
 public MergeBuffer(CILInstruction[] buffer)
 {
     _debugBuffer = new ArrayList();
        _buffer = buffer;
 }