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()); }
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); }
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); }
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(); }
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(); }
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(); }
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); }
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(); }
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(); }
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(); }
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"); }
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") !; }
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 }; }
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 }; }
/// <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); } }
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"); }
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") !); } }
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")); }
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; } }
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") !); } }
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); }
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); }
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()); }
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; }
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()); }
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); }
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); }
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(); }
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); }
private Identifier RegId( string name, IProcessorArchitecture arch, string reg, DataType dt) { return(new Identifier( name, dt, arch.GetRegister(reg))); }
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; } }
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")); } }
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()); }
private Identifier RegId( string name, IProcessorArchitecture arch, string reg, DataType dt) { return new Identifier( name, dt, arch.GetRegister(reg)); }
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; }