Ejemplo n.º 1
0
        public void Bwslc_x86_RegisterHack()
        {
            // In old x86 binaries we see this mechanism
            // for zero extending a register.
            arch = new Reko.Arch.X86.X86ArchitectureReal(sc, "x86-real-16", new Dictionary <string, object>());
            var bl   = binder.EnsureRegister(arch.GetRegister("bl"));
            var bh   = binder.EnsureRegister(arch.GetRegister("bh"));
            var bx   = binder.EnsureRegister(arch.GetRegister("bx"));
            var si   = binder.EnsureRegister(arch.GetRegister("si"));
            var SCZO = binder.EnsureFlagGroup(arch.GetFlagGroup("SCZO"));
            var SZO  = binder.EnsureFlagGroup(arch.GetFlagGroup("SZO"));
            var c    = binder.EnsureFlagGroup(arch.GetFlagGroup("C"));

            var b = Given_Block(0x0100);

            Given_Instrs(b, m =>
            {
                m.Assign(bl, m.Mem8(si));
            });
            Given_Instrs(b, m =>
            {
                m.Assign(SCZO, m.Cond(m.ISub(bl, 2)));
            });
            Given_Instrs(b, m => {
                m.Branch(new TestCondition(ConditionCode.UGT, SCZO), Address.Ptr16(0x120), InstrClass.ConditionalTransfer);
            });

            var b2 = Given_Block(0x200);

            Given_Instrs(b2, m =>
            {
                m.Assign(bh, m.Xor(bh, bh));
                m.Assign(SCZO, new ConditionOf(bh));
            });
            Given_Instrs(b2, m =>
            {
                m.Assign(bx, m.IAdd(bx, bx));
                m.Assign(SCZO, new ConditionOf(bx));
            });
            Given_Instrs(b2, m => {
                m.Goto(m.Mem16(m.IAdd(bx, 0x8400)));
            });

            graph.Nodes.Add(b);
            graph.Nodes.Add(b2);
            graph.AddEdge(b, b2);

            var bwslc = new BackwardSlicer(host, b, processorState);

            Assert.IsTrue(bwslc.Start(b2, 3, Target(b2))); // indirect jump
            Assert.IsTrue(bwslc.Step());                   // assign flags
            Assert.IsTrue(bwslc.Step());                   // add bx,bx
            Assert.IsTrue(bwslc.Step());                   // assign flags
            Assert.IsTrue(bwslc.Step());                   // xor high-byte of bx
            Assert.IsTrue(bwslc.Step());                   // branch.
            Assert.IsFalse(bwslc.Step());                  // cmp.

            Assert.AreEqual("Mem0[CONVERT(SLICE(bx, byte, 0), byte, word16) * 2<16> + 0x8400<16>:word16]", bwslc.JumpTableFormat.ToString());
            Assert.AreEqual("1[0,2]", bwslc.JumpTableIndexInterval.ToString());
        }
Ejemplo n.º 2
0
        public Identifier VisitRegister(Register_v1 reg)
        {
            var      regStorage = arch.GetRegister(reg.Name.Trim());
            DataType dt;

            if (this.argCur.Type != null)
            {
                dt = this.argCur.Type.Accept(procSer.TypeLoader);
            }
            else
            {
                dt = regStorage.DataType;
            }
            if (dt is VoidType)
            {
                return(null);
            }
            var idArg = procSer.CreateId(
                argCur.Name ?? regStorage.Name,
                dt,
                regStorage);

            if (argCur.OutParameter)
            {
                idArg = frame.EnsureOutArgument(idArg, arch.FramePointerType);
            }
            return(idArg);
        }
Ejemplo n.º 3
0
        public Identifier VisitRegister(Register_v1 reg)
        {
            var      regStorage = arch.GetRegister(reg.Name.Trim());
            DataType dt;

            if (this.argCur.Type != null)
            {
                dt = this.argCur.Type.Accept(procSer.TypeLoader);
            }
            else
            {
                dt = regStorage.DataType;
            }
            if (dt is VoidType)
            {
                return(null);
            }
            var idArg = procSer.CreateId(
                argCur.Name ?? regStorage.Name,
                dt,
                regStorage);

            if (argCur.OutParameter)
            {
                //$REVIEW: out arguments are weird, as they are synthetic. It's possible that
                // future versions of reko will opt to model multiple values return from functions
                // explicitly instead of using destructive updates of this kind.
                idArg = frame.EnsureOutArgument(idArg, PrimitiveType.Create(Domain.Pointer, arch.FramePointerType.BitSize));
            }
            return(idArg);
        }
Ejemplo n.º 4
0
 public Arm64CallingConvention(IProcessorArchitecture arch)
 {
     this.arch = arch;
     argRegs   = new[] { "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7" }
     .Select(r => arch.GetRegister(r) !).ToArray();
     floatRegs = new[] { "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7" }
     .Select(r => arch.GetRegister(r) !).ToArray();
 }
Ejemplo n.º 5
0
 public Nios2CallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.retLo = arch.GetRegister("r2") !;
     this.retHi = arch.GetRegister("r3") !;
     this.iregs = new[] { "r4", "r5", "r6", "r7" }
     .Select(n => arch.GetRegister(n) !)
     .ToArray();
 }
Ejemplo n.º 6
0
 public zSeriesCallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.iregs = new[] { "r2", "r3", "r4", "r5", "r6" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.fregs = new[] { "f0", "f2", "f4", "f6" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
 }
Ejemplo n.º 7
0
        public Identifier Deserialize(Register_v1 reg)
        {
            var idArg = frame.EnsureRegister(arch.GetRegister(reg.Name.Trim()));

            if (argCur.OutParameter)
            {
                idArg = frame.EnsureOutArgument(idArg, arch.FramePointerType);
            }
            return(idArg);
        }
Ejemplo n.º 8
0
 public PowerPcCallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.iregs = new[] { "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.fregs = new[] { "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
 }
Ejemplo n.º 9
0
 public AlphaCallingConvention(IProcessorArchitecture arch)
 {
     this.iRegs = new[] { "r16", "r17", "r18", "r19", "r20", "r21" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.iRet  = arch.GetRegister("r0");
     this.fRegs = new[] { "f12", "f13", "f14", "f15" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
 }
Ejemplo n.º 10
0
 public RiscVCallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.iregs = new[] { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.fregs = new[] { "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
 }
Ejemplo n.º 11
0
 public SparcCallingConvention(IProcessorArchitecture arch)
 {
     this.arch = arch;
     this.regs = new[] { "o0", "o1", "o2", "o3", "o4", "o5" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.iret  = arch.GetRegister("o0");
     this.fret0 = arch.GetRegister("f0");
     this.fret1 = arch.GetRegister("f1");
 }
Ejemplo n.º 12
0
 public SuperHCallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.iregs = NamesToRegs("r4", "r5", "r6", "r7");
     this.fregs = NamesToRegs("fr4", "fr5", "fr6", "fr7");
     this.dregs = NamesToRegs("dr4", "dr6");
     this.iret  = arch.GetRegister("r0") !;
     this.fret  = arch.GetRegister("fr0") !;
     this.dret  = arch.GetRegister("dr0") !;
 }
Ejemplo n.º 13
0
        public WinAArch64Platform(IServiceProvider services, IProcessorArchitecture arch) :
            base(services, arch, "winArm64")
        {
            var framePointer = arch.GetRegister("x29") !;
            var linkRegister = arch.GetRegister("x30") !;

            implicitRegs = new HashSet <RegisterStorage>
            {
                framePointer, linkRegister
            };
        }
Ejemplo n.º 14
0
        public Win32MipsPlatform(IServiceProvider services, IProcessorArchitecture arch) :
            base(services, arch, "winMips")
        {
            var gp = arch.GetRegister("r28") !;
            var sp = arch.GetRegister("sp") !;

            implicitRegs = new HashSet <RegisterStorage>
            {
                gp, sp
            };
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Computes the trashed registers for all the procedures in the
        /// SCC group.
        /// </summary>
        /// <remarks>
        /// To deal with recursive functions -- including deeply nested
        /// mutually recursive functions, we first compute what registers
        /// are trashed when recursion is disregarded. If there are no
        /// recursive calls, we are done and leave early.
        /// If there are recursive calls, we make one unwarranted but
        /// highly likely assumption: for each involved procedure,
        /// the stack pointer will have the same value in the exit block
        /// after traversing both non-recursive and recursive paths
        /// of the program.
        /// </remarks>
        public void Compute()
        {
            CreateState();
            this.propagateToCallers = false;

            Block block;

            while (worklist.GetWorkItem(out block))
            {
                ProcessBlock(block);
            }

            if (!selfRecursiveCalls)
            {
                return;
            }

            // We make a big, but very reasonable assumption here: if a procedure
            // has a recursive branch and a non-recursive branch, the stack pointer
            // will have the same value at the point where the branches join.
            // It certainly possible for an assembly language programmer to construct
            // a program where procedures deliberately put the stack in imbalance
            // after calling a procedure, but using such a procedure is very difficult
            // to do as you must somehow understand how the procedure changes the
            // stack pointers depending on ... anything!
            // It seems safe to assume that all branches leading to the exit block
            // have the same stack pointer value.

            var savedSps = CollectStackPointers(flow, arch.StackRegister);
            //$REVIEW: Ew. This hardwires a dependency on x87 in common code.
            // We need a general mechanism for dealing with "stack pointers"
            // that abstracts over platform integer stack pointers and the
            // x87 FPU stack pointer.
            var savedTops = new Dictionary <Procedure, int?>();

            if (arch.TryGetRegister("Top", out var top))
            {
                savedTops = CollectStackPointers(flow, arch.GetRegister("Top"));
            }

            CreateState();

            ApplyStackPointers(savedSps, flow);
            ApplyStackPointers(savedTops, flow);

            BypassRegisterOffsets(savedSps, arch.StackRegister);

            this.propagateToCallers = true;
            while (worklist.GetWorkItem(out block))
            {
                ProcessBlock(block);
            }
        }
Ejemplo n.º 16
0
 public MipsCallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.iregs = new[] { "r4", "r5", "r6", "r7" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.fregs = new[] { "f12", "f13", "f14", "f15" }
     .Select(r => arch.GetRegister(r))
     .ToArray();
     this.iret = arch.GetRegister("r2");
     this.fret = arch.GetRegister("f1");
 }
Ejemplo n.º 17
0
 public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
 {
     //$BUG: this is all just to get the ELF loader up and running.
     ccr.LowLevelDetails(4, 0);
     if (dtRet != null && !(dtRet is VoidType))
     {
         ccr.RegReturn(arch.GetRegister("r0") !);
     }
     foreach (var dt in dtParams)
     {
         ccr.RegParam(arch.GetRegister("r0") !);
     }
 }
Ejemplo n.º 18
0
        public override Storage GetReturnRegister(Argument_v1 sArg, int bitSize)
        {
            var prim = sArg.Type as PrimitiveType_v1;

            if (prim != null)
            {
                if (prim.Domain == Domain.Real)
                {
                    return(arch.GetRegister("f1"));
                }
            }
            return(arch.GetRegister("r3"));
        }
Ejemplo n.º 19
0
 public RiscVCallingConvention(IProcessorArchitecture arch)
 {
     this.arch  = arch;
     this.iregs = new[] { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7" }
     .Select(r => arch.GetRegister(r) !)
     .ToArray();
     this.fregs = new[] { "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7" }
     .Select(r => arch.GetRegister(r) !)
     .ToArray();
     if (((ProcessorArchitecture)arch).Options.TryGetValue("FloatAbi", out var oFloatAbi) &&
         oFloatAbi is int floatAbi)
     {
         this.floatAbi = floatAbi;
     }
 }
Ejemplo n.º 20
0
 public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
 {
     //$BUG: this is all just to get the ELF loader up and running.
     // fill in with details from
     // https://blackfin.uclinux.org/doku.php?id=toolchain:application_binary_interface
     ccr.LowLevelDetails(4, 0);
     if (dtRet != null && !(dtRet is VoidType))
     {
         ccr.RegReturn(arch.GetRegister("R0") !);
     }
     foreach (var dt in dtParams)
     {
         ccr.RegParam(arch.GetRegister("R0") !);
     }
 }
Ejemplo n.º 21
0
        public SystemService Build(IProcessorArchitecture arch)
        {
            SystemService svc = new SystemService();

            svc.Name               = Name;
            svc.SyscallInfo        = new SyscallInfo();
            svc.SyscallInfo.Vector = Convert.ToInt32(SyscallInfo.Vector, 16);
            if (SyscallInfo.RegisterValues != null)
            {
                svc.SyscallInfo.RegisterValues = new RegValue[SyscallInfo.RegisterValues.Length];
                for (int i = 0; i < SyscallInfo.RegisterValues.Length; ++i)
                {
                    svc.SyscallInfo.RegisterValues[i] = new RegValue
                    {
                        Register = arch.GetRegister(SyscallInfo.RegisterValues[i].Register),
                        Value    = Convert.ToInt32(SyscallInfo.RegisterValues[i].Value, 16),
                    };
                }
            }
            else
            {
                svc.SyscallInfo.RegisterValues = new RegValue[0];
            }
            TypeLibraryLoader   loader = new TypeLibraryLoader(arch, true);
            ProcedureSerializer sser   = arch.CreateProcedureSerializer(loader, "stdapi");

            svc.Signature       = sser.Deserialize(Signature, arch.CreateFrame());
            svc.Characteristics = Characteristics != null ? Characteristics : DefaultProcedureCharacteristics.Instance;
            return(svc);
        }
Ejemplo n.º 22
0
            private Identifier GenerateWideIdentifier(DataType dt, SsaIdentifier[] sids)
            {
                var        sd = sids[0].Identifier.Storage.Domain;
                Identifier idWide;

                if (AllSame(sids, (a, b) => a.Identifier.Storage.Domain == b.Identifier.Storage.Domain))
                {
                    var bits = sids.Aggregate(
                        new BitRange(),
                        (br, sid) => br | sid.Identifier.Storage.GetBitRange());
                    var regWide = arch.GetRegister(sd, bits);
                    idWide = ssa.Procedure.Frame.EnsureRegister(regWide);
                }
                else if (sids.All(sid => sid.Identifier.Storage is StackStorage))
                {
                    idWide = CombineAdjacentStorages(sids);
                }
                else
                {
                    idWide = ssa.Procedure.Frame.EnsureSequence(
                        dt,
                        sids.Select(s => s.Identifier.Storage).ToArray());
                }
                return(idWide);
            }
Ejemplo n.º 23
0
        public void Scanner_ScanProcedure_AssumeRegisterValues()
        {
            var scanner = CreateScanner(0x1000, 0x2000);

            var address = Address.Ptr32(0x1000);

            program.User.Procedures.Add(Address.Ptr32(0x1000), new UserProcedure(address, NamingPolicy.Instance.ProcedureName(address))
            {
                Assume =
                {
                    new RegisterValue_v2 {
                        Register = "r1", Value = "0DC0"
                    }
                }
            });
            Given_Trace(new RtlTrace(0x1000)
            {
                m => { m.Return(0, 0); }
            });
            var proc = (Procedure)scanner.ScanProcedure(
                arch,
                Address.Ptr32(0x1000),
                "fnFoo",
                arch.CreateProcessorState());

            var r1 = proc.Frame.EnsureIdentifier(arch.GetRegister("r1"));

            Assert.AreEqual("0xDC0<32>", scanner.Test_State.GetValue(r1).ToString());
        }
Ejemplo n.º 24
0
		public SystemService Build(IProcessorArchitecture arch)
		{
			SystemService svc = new SystemService();
			svc.Name = Name;
			svc.SyscallInfo = new SyscallInfo();
			svc.SyscallInfo.Vector = Convert.ToInt32(SyscallInfo.Vector, 16);
			if (SyscallInfo.RegisterValues != null)
			{
				svc.SyscallInfo.RegisterValues = new RegValue[SyscallInfo.RegisterValues.Length];
				for (int i = 0; i < SyscallInfo.RegisterValues.Length; ++i)
				{
                    svc.SyscallInfo.RegisterValues[i] = new RegValue
                    {
                        Register = arch.GetRegister(SyscallInfo.RegisterValues[i].Register),
                        Value = Convert.ToInt32(SyscallInfo.RegisterValues[i].Value, 16),
                    };
				}
			}
			else
			{
				svc.SyscallInfo.RegisterValues = new RegValue[0];
			}
            TypeLibraryLoader loader = new TypeLibraryLoader(arch, true);
			ProcedureSerializer sser = arch.CreateProcedureSerializer(loader, "stdapi");
            svc.Signature = sser.Deserialize(Signature, arch.CreateFrame());
			svc.Characteristics = Characteristics != null ? Characteristics : DefaultProcedureCharacteristics.Instance;
			return svc;
		}
Ejemplo n.º 25
0
        public void Scanner_ScanProcedure_AssumeRegisterValues()
        {
            var scanner = CreateScanner(0x1000, 0x2000);

            program.User.Procedures.Add(Address.Ptr32(0x1000), new Reko.Core.Serialization.Procedure_v1
            {
                Assume = new RegisterValue_v2[] {
                    new RegisterValue_v2 {
                        Register = "r1", Value = "0DC0"
                    }
                }
            });
            Given_Trace(new RtlTrace(0x1000)
            {
                m => { m.Return(0, 0); }
            });
            var state = arch.CreateProcessorState();
            var proc  = (Procedure)scanner.ScanProcedure(
                Address.Ptr32(0x1000),
                "fnFoo",
                arch.CreateProcessorState());

            var r1 = proc.Frame.EnsureIdentifier(arch.GetRegister("r1"));

            Assert.AreEqual("0x00000DC0", scanner.Test_State.GetValue(r1).ToString());
        }
Ejemplo n.º 26
0
        public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(2, 2);
            if (dtRet != null)
            {
                SetReturnRegisters(ccr, dtRet);
            }

            int gr = 0;

            for (int iArg = 0; iArg < dtParams.Count; ++iArg)
            {
                var arg = arch.GetRegister("r" + gr) !;
                ++gr;
                ccr.RegParam(arg);
            }
            ccr.CallerCleanup(arch.PointerType.Size);
        }
Ejemplo n.º 27
0
 public void Setup()
 {
     mr = new MockRepository();
     fakeArch = new FakeArchitecture();
     importResolver = mr.StrictMock<IImportResolver>();
     callSigs = new Dictionary<Address, ProcedureSignature>();
     arch = fakeArch;
     var r1 = arch.GetRegister(1);
     reg1 = new Identifier(r1.Name, PrimitiveType.Word32, r1);
 }
Ejemplo n.º 28
0
        private HashSet <RegisterStorage> GenerateTrashedRegisters(IProcessorArchitecture arch)
        {
            switch (arch.Name)
            {
            case "arm-64":
                // ARM64 ABI defines registers r19-r29 and SP as callee-save.
                return(Enumerable.Range(0, 32)
                       .Where(n => n < 19 || n == 30)
                       .Select(n => arch.GetRegister(n + StorageDomain.Register, new BitRange(0, 64)) !)
                       .ToHashSet());

            case "x86-protected-64":
                return(new[] {
                    "rax", "rcx", "rdx", "rsp", "rsi", "rdi", "r8", "r9", "r10", "r11"
                }
                       .Select(s => arch.GetRegister(s) !)
                       .ToHashSet());
            }
            throw new NotImplementedException();
        }
Ejemplo n.º 29
0
        public void Setup()
        {
            mr             = new MockRepository();
            fakeArch       = new FakeArchitecture();
            importResolver = mr.StrictMock <IImportResolver>();
            callSigs       = new Dictionary <Address, ProcedureSignature>();
            arch           = fakeArch;
            var r1 = arch.GetRegister(1);

            reg1 = new Identifier(r1.Name, PrimitiveType.Word32, r1);
        }
Ejemplo n.º 30
0
 private Identifier RegId(
     string name,
     IProcessorArchitecture arch,
     string reg,
     DataType dt)
 {
     return(new Identifier(
                name,
                dt,
                arch.GetRegister(reg)));
 }
Ejemplo n.º 31
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(4, 0);
            if (dtRet != null)
            {
                var a2 = (StorageDomain)2;
                //$TODO: size > 4 bytes?
                ccr.RegReturn(arch.GetRegister(a2, r32));
            }
            int iReg = 2;

            foreach (var dtParam in dtParams)
            {
                //$TODO: size > 4 bytes?
                //$TODO: iReg > 6?
                var arg = (StorageDomain)iReg;
                ccr.RegParam(arch.GetRegister(arg, r32));
                ++iReg;
            }
        }
Ejemplo n.º 32
0
 public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
 {
     ccr.LowLevelDetails(4, 0);
     foreach (var dt in dtParams)
     {
         ccr.StackParam(dt);
     }
     if (dtRet != null)
     {
         ccr.RegReturn(arch.GetRegister("r12"));
     }
 }
Ejemplo n.º 33
0
 public void Setup()
 {
     mr = new MockRepository();
     fakeArch = new FakeArchitecture();
     importResolver = mr.StrictMock<IImportResolver>();
     callSigs = new Dictionary<Address, ProcedureSignature>();
     arch = fakeArch;
     var r1 = arch.GetRegister(1);
     reg1 = new Identifier(r1.Name, PrimitiveType.Word32, r1);
     this.sc = new ServiceContainer();
     sc.AddService<DecompilerHost>(new FakeDecompilerHost());
     sc.AddService<DecompilerEventListener>(new FakeDecompilerEventListener());
     sc.AddService<IFileSystemService>(new FileSystemServiceImpl());
 }
Ejemplo n.º 34
0
 private Identifier RegId(
     string name,
     IProcessorArchitecture arch,
     string reg,
     DataType dt)
 {
     return new Identifier(
         name,
         dt,
         arch.GetRegister(reg));
 }
Ejemplo n.º 35
0
 private ProcessorState CreateInitialState(IProcessorArchitecture arch, Dictionary<string, object> args)
 {
     var state = arch.CreateProcessorState();
     if (!args.ContainsKey("--reg"))
         return state;
     var regs = (List<string>)args["--reg"];
     foreach (var regValue in regs.Where(r => !string.IsNullOrEmpty(r)))
     {
         var rr = regValue.Split(':');
         if (rr == null || rr.Length != 2)
             continue;
         var reg = arch.GetRegister(rr[0]);
         state.SetRegister(reg, Constant.Create(reg.DataType, Convert.ToInt64(rr[1], 16)));
     }
     return state;
 }