コード例 #1
0
ファイル: structs.cs プロジェクト: jrfl/exeopt
 /// <summary>
 /// This is too add an fpu line to a new fpu segment - all lines in here are fpu commands
 /// </summary>
 public void AddLine(LineInfo li,int LinoNo)
 {
     //Check for illegal opperand data
     if(li.StoredOperands.IndexOf(",")!=-1) {
         //TODO: Make this a bit more general
         if(li.instruction=="fdivp"&&li.operands[0].Register=="st1"&&li.operands[1].Register=="st0") {
             li=new LineInfo(li.address+" "+li.code+" fdivrp st1");
         } else {
             throw new OptimizationException("Segmenter: Fpu instruction had 2 operands");
         }
     }
     if(li.StoredOperands=="") throw new OptimizationException("Segmenter: Fpu instruction had no operands");
     //TODO: Check that this line of code doesn't break anything!
     if(Array.IndexOf(Program.FpuIgnoreInstructions,li.instruction)!=-1||li.operands[0].OpType==
         OperandType.Register) return;
     if(li.operands[0].OpType!=OperandType.rMemory)
         throw new OptimizationException("Segmenter: Cannot do anything with non memory operands");
     if(li.operands[0].MultiPart)
         throw new OptimizationException("Segmenter: Cannot do anything with multipart operands");
     if(li.operands[0].OpSize!=OperandSize.Unknown&&li.operands[0].OpSize!=OperandSize.dWord)
         throw new OptimizationException("Segmenter: Cannot do anything with non float data values");
     if(Math.Abs(li.operands[0].Offset)>65535)
         throw new OptimizationException("Segmenter: Memory offset is too great");
     //Add the operand to the appropriate arraylists
     if(Array.IndexOf(Program.FpuReadInstructions,li.instruction)!=-1) {
         ReadMem.Add(new IntString(LinoNo,li.operands[0].Operand));
         if(!ScanList(ChangedMem,LinoNo,li.operands[0].Operand,true)) throw new OptimizationException("Segmenter: Interdependent fpu calculations");
     }
     if(Array.IndexOf(Program.FpuWriteInstructions,li.instruction)!=-1) {
         ChangedMem.Add(new IntString(LinoNo,li.operands[0].Operand));
     }
     ReadReg.Add(new IntString(LinoNo,li.operands[0].Register));
 }
コード例 #2
0
ファイル: structs.cs プロジェクト: jrfl/exeopt
 //public string[] TestData;
 public FpuSegment(LineInfo[] lines,ArrayList pre,ArrayList post,int start,int end)
 {
     Lines=lines;
     Pre=(LineInfo[])pre.ToArray(typeof(LineInfo));
     Post=(LineInfo[])post.ToArray(typeof(LineInfo));
     Start=start;
     End=end;
     //TestData=(string[])testData.ToArray(typeof(string));
 }
コード例 #3
0
ファイル: structs.cs プロジェクト: jrfl/exeopt
 public bool CanMoveInstruction(LineInfo li,int LineNo,bool upward)
 {
     if(li.operands.Length>2) throw new OptimizationException("Segmenter: Cannot move instructions with 3 operands");
     if(li.operands.Length==0) throw new OptimizationException("Segmenter: Cannot move instructions with implicit operands");
     if(li.operands.Length==1) {
         switch(li.instruction) {
             case "push":
                 switch(li.operands[0].OpType) {
                     case OperandType.rMemory:
                         if(!ScanList(ChangedMem,LineNo,li.operands[0].Operand,upward)) return false;
                         break;
                     case OperandType.Immediate: throw new OptimizationException("Segmenter: Immediate operand pushed onto stack");
                 }
                 if(upward) {
                     ModEsp(LineNo,upward,4);
                 } else {
                     ModEsp(LineNo,upward,-4);
                 }
                 break;
                 //li=new LineInfo("00000000 00 mov esp,"+li.operands[0].Operand);break;
             case "pop":
                 switch(li.operands[0].OpType) {
                     case OperandType.rMemory:
                         if(!ScanList(ReadMem,LineNo,li.operands[0].Operand,upward)) return false;
                         break;
                     case OperandType.Register:
                         if(!ScanList(ReadReg,LineNo,li.operands[0].Operand,upward)) return false;
                         break;
                 }
                 if(upward) {
                     ModEsp(LineNo,upward,-4);
                 } else {
                     ModEsp(LineNo,upward,4);
                 }
                 break;
             //li=new LineInfo("00000000 00 mov esp,[esp]"); break;
             default: throw new OptimizationException("Segmenter: Cannot move instruction with one operand");
         }
     }
     if(li.operands.Length==2) {
         if(Array.IndexOf(Program.ReadOnlyInstructions,li.instruction)==-1) {
             switch(li.operands[0].OpType) {
                 case OperandType.Register:
                     if(!ScanList(ReadReg,LineNo,li.operands[0].Register,upward)) return false;
                     break;
                 case OperandType.rMemory:
                     if(!ScanList(ReadMem,LineNo,li.operands[0].Operand,upward)) return false;
                     break;
             }
         } else {
             switch(li.operands[0].OpType) {
                 case OperandType.rMemory:
                     if(!ScanList(ChangedMem,LineNo,li.operands[1].Operand,upward)) return false;
                     break;
             }
         }
         switch(li.operands[1].OpType) {
             case OperandType.rMemory:
                 if(!ScanList(ChangedMem,LineNo,li.operands[1].Operand,upward)) return false;
                 break;
         }
     }
     return true;
 }
コード例 #4
0
ファイル: Program.cs プロジェクト: jrfl/exeopt
        public static void ReadCode() {
#if clean
            File.Delete("Morrowind.exe");
            File.Delete("code");
            File.Copy("clean\\Morrowind.exe","Morrowind.exe");
            File.Copy("clean\\code","code");
#endif
            Console.WriteLine("Loading code segments");
            StreamReader sr=new StreamReader("dcode.txt");
            ArrayList segLines=new ArrayList();
            int count=0;
            bool DropSegment=false;
            bool StartedSegment=true;
            LineInfo li;
#if !fulltest||partialtest
            int count2=0;
#endif
            count3=0;
            while(sr.Peek()!=-1) {
                string s=sr.ReadLine();
#if !fulltest||partialtest
                count2++;
                LineNo=count2;
                if(count2<500000||count2>510000) continue;
#endif
                try {
                    li=new LineInfo(s);
                } catch(Exception) { DropSegment=true; li=new LineInfo("00000000 00 int3"); }
                if(Array.IndexOf(JumpInstructions,li.instruction)==-1) {
                    if(StartedSegment) {
                        segLines.Add(li);
                    } else if(Array.IndexOf(FpuInstructions,li.instruction)!=-1) {
                        StartedSegment=true;
                        segLines.Add(li);
                    }
                } else if(StartedSegment) {
                    if(!DropSegment) {
                        segLines.Add(li);
                        CodeSegment cs=new CodeSegment(segLines);
                        try {
                            if(OptimizeSegment(ref cs)) count3++;
#if !fulltest
                        } catch(OptimizationException ex) {
                            if(thingy) {
                                try {
                                    LogFile.WriteLine(CurrentSeg.Lines[0].address);
                                    LogFile.WriteLine("\nPatched:");
                                    LogFile.Write(CurrentSeg.ToString());
                                    LogFile.WriteLine("\nwith:");
                                    s=string.Join("\n",fpu.Result);
                                    LogFile.WriteLine(s);
                                    //LogFile.Write(tempFpu.PreString()+File.ReadAll("out.txt")+tempFpu.PostString());
                                    LogFile.WriteLine("------------------------------------------------");
                                } catch { }
                                string ss=ex.ToString();
                                Console.WriteLine(ss);
                                thingy=false;
                            }

#else
                        } catch(OptimizationException) {
#endif
                        }
                        count++;
#if useconsole
                        if(count%100==0) {
                            Console.WriteLine("Processed "+count.ToString()+" segments and found "+count3+" patches.");
                        }
#else
                        Console.WriteLine("Processed "+count.ToString()+" segments and found "+count3+" patches.");
#endif
                    }
                    segLines.Clear();
                    DropSegment=false;
                    StartedSegment=false;
                } else DropSegment=false;
            }
            sr.Close();
        }
コード例 #5
0
ファイル: fpu.cs プロジェクト: jrfl/exeopt
 public static void PerformOp(LineInfo op,byte LineNo)
 {
     string l="\0"+LineNo.ToString().PadLeft(10,'0');
     CurrentOp=op;
     switch(op.instruction) {
         case "fld": Registers.Push(loc(),l); break;
         case "fst":
             if(CurrentOp.operands[0].OpType==OperandType.Register) {
                 byte b=Convert.ToByte(""+CurrentOp.operands[0].Register[2]);
                 Registers.Assign(b,Registers.Peek(),l);
             } else {
                 Results.Add(l+loc()+"="+Registers.Peek());
             }
             break;
         case "fstp":
             //This is backwards! Assign first, then pop!
             if(CurrentOp.operands[0].OpType==OperandType.Register) {
                 byte b=Convert.ToByte(""+CurrentOp.operands[0].Register[2]);
                 Registers.Assign(b,Registers.Peek(),l);
                 Registers.Pop();
             } else {
                 Results.Add(l+loc()+"="+Registers.Pop());
             }
             break;
         case "fadd": Registers.Op(l+"+",loc()); break;
         case "faddp": Registers.ToOp(l+"+",loc()); Registers.Pop(); break;
         case "fmul": Registers.Op(l+"*",loc()); break;
         case "fmulp": Registers.ToOp(l+"*",loc()); Registers.Pop(); break;
         case "fdiv": Registers.Op(l+"/",loc()); break;
         case "fdivp": Registers.ToOp(l+"/",loc()); Registers.Pop(); break;
         case "fdivr": Registers.ROp(l+"/",loc()); break;
         case "fdivrp": Registers.RToOp(l+"/",loc()); Registers.Pop(); break;
         case "fsub": Registers.Op(l+"-",loc()); break;
         case "fsubp": Registers.ToOp(l+"-",loc()); Registers.Pop(); break;
         case "fsubr": Registers.ROp(l+"-",loc()); break;
         case "fsubrp": Registers.RToOp(l+"-",loc()); Registers.Pop(); break;
         case "fxch": Registers.Exchange(loc(),l); break;
         default: throw new OptimizationException("FPU: Unrecognised operation");
     }
 }
コード例 #6
0
        public bool CanMoveInstruction(LineInfo li, int LineNo, bool upward)
        {
            if (li.operands.Length > 2)
            {
                throw new OptimizationException("Segmenter: Cannot move instructions with 3 operands");
            }
            if (li.operands.Length == 0)
            {
                throw new OptimizationException("Segmenter: Cannot move instructions with implicit operands");
            }
            if (li.operands.Length == 1)
            {
                switch (li.instruction)
                {
                case "push":
                    switch (li.operands[0].OpType)
                    {
                    case OperandType.rMemory:
                        if (!ScanList(ChangedMem, LineNo, li.operands[0].Operand, upward))
                        {
                            return(false);
                        }
                        break;

                    case OperandType.Immediate: throw new OptimizationException("Segmenter: Immediate operand pushed onto stack");
                    }
                    if (upward)
                    {
                        ModEsp(LineNo, upward, 4);
                    }
                    else
                    {
                        ModEsp(LineNo, upward, -4);
                    }
                    break;

                //li=new LineInfo("00000000 00 mov esp,"+li.operands[0].Operand);break;
                case "pop":
                    switch (li.operands[0].OpType)
                    {
                    case OperandType.rMemory:
                        if (!ScanList(ReadMem, LineNo, li.operands[0].Operand, upward))
                        {
                            return(false);
                        }
                        break;

                    case OperandType.Register:
                        if (!ScanList(ReadReg, LineNo, li.operands[0].Operand, upward))
                        {
                            return(false);
                        }
                        break;
                    }
                    if (upward)
                    {
                        ModEsp(LineNo, upward, -4);
                    }
                    else
                    {
                        ModEsp(LineNo, upward, 4);
                    }
                    break;

                //li=new LineInfo("00000000 00 mov esp,[esp]"); break;
                default: throw new OptimizationException("Segmenter: Cannot move instruction with one operand");
                }
            }
            if (li.operands.Length == 2)
            {
                if (Array.IndexOf(Program.ReadOnlyInstructions, li.instruction) == -1)
                {
                    switch (li.operands[0].OpType)
                    {
                    case OperandType.Register:
                        if (!ScanList(ReadReg, LineNo, li.operands[0].Register, upward))
                        {
                            return(false);
                        }
                        break;

                    case OperandType.rMemory:
                        if (!ScanList(ReadMem, LineNo, li.operands[0].Operand, upward))
                        {
                            return(false);
                        }
                        break;
                    }
                }
                else
                {
                    switch (li.operands[0].OpType)
                    {
                    case OperandType.rMemory:
                        if (!ScanList(ChangedMem, LineNo, li.operands[1].Operand, upward))
                        {
                            return(false);
                        }
                        break;
                    }
                }
                switch (li.operands[1].OpType)
                {
                case OperandType.rMemory:
                    if (!ScanList(ChangedMem, LineNo, li.operands[1].Operand, upward))
                    {
                        return(false);
                    }
                    break;
                }
            }
            return(true);
        }