public static FunctionType ReplaceVarargs( IPlatform platform, FunctionType sig, IEnumerable <DataType> argumentTypes) { var fixedArgs = sig.Parameters.TakeWhile(p => p.Name != "...").ToList(); var cc = platform.GetCallingConvention(""); //$REVIEW: default CC tends to be __cdecl. //$BUG: what if platform returns null or throws? var allTypes = fixedArgs .Select(p => p.DataType) .Concat(argumentTypes) .ToList(); var ccr = new CallingConventionEmitter(); cc !.Generate( ccr, sig.ReturnValue.DataType, null, //$TODO: what to do about implicit this? allTypes); var varArgs = argumentTypes.Zip( ccr.Parameters.Skip(fixedArgs.Count), (t, s) => new Identifier("", t, s)); return(sig.ReplaceParameters(fixedArgs.Concat(varArgs).ToArray())); }
private void AssertSignature64(string sExp, params DataType[] args) { var arch = new MipsBe64Architecture(new ServiceContainer(), "mips-be-64", new Dictionary <string, object>()); var cc = new MipsCallingConvention(arch); var ccr = new CallingConventionEmitter(); cc.Generate(ccr, null, null, args.ToList()); Assert.AreEqual(sExp.Trim(), ccr.ToString()); }
private void AssertSignature(string sExp, DataType dtRet, params DataType[] args) { var arch = new XtensaArchitecture(new ServiceContainer(), "xtensa", new Dictionary <string, object>()); var cc = new XtensaCallingConvention(arch); var ccr = new CallingConventionEmitter(); cc.Generate(ccr, dtRet, null, args.ToList()); Assert.AreEqual(sExp.Trim(), ccr.ToString()); }
private void AssertSignature(string sExp, params DataType[] args) { var arch = new MipsBe32Architecture("mips-be-32"); var cc = new MipsCallingConvention(arch); var ccr = new CallingConventionEmitter(); cc.Generate(ccr, null, null, args.ToList()); Assert.AreEqual(sExp.Trim(), ccr.ToString()); }
private void AssertSignature(string sExp, DataType retType, params DataType[] args) { var arch = new PowerPcBe64Architecture(new ServiceContainer(), "ppc-be-64"); var cc = new PowerPc64CallingConvention(arch); var ccr = new CallingConventionEmitter(); cc.Generate(ccr, retType, null, args.ToList()); Assert.AreEqual(sExp.Trim(), ccr.ToString()); }
/// <summary> /// Deserializes the signature <paramref name="ss"/>. Any instantiated /// registers or stack variables are introduced into the Frame. /// </summary> /// <param name="ss"></param> /// <param name="frame"></param> /// <returns></returns> public FunctionType Deserialize(SerializedSignature ss, Frame frame) { if (ss == null) { return(null); } var retAddrSize = this.Architecture.PointerType.Size; //$TODO: deal with near/far calls in x86-realmode if (!ss.ParametersValid) { return(new FunctionType { StackDelta = ss.StackDelta, ReturnAddressOnStack = retAddrSize, }); } var parameters = new List <Identifier>(); Identifier ret = null; if (UseUserSpecifiedStorages(ss)) { this.argDeser = new ArgumentDeserializer( this, Architecture, frame, retAddrSize, Architecture.WordWidth.Size); int fpuDelta = FpuStackOffset; FpuStackOffset = 0; if (ss.ReturnValue != null) { ret = DeserializeArgument(ss.ReturnValue, -1, ""); fpuDelta += FpuStackOffset; } FpuStackOffset = 0; if (ss.Arguments != null) { for (int iArg = 0; iArg < ss.Arguments.Length; ++iArg) { var sArg = ss.Arguments[iArg]; var arg = DeserializeArgument(sArg, iArg, ss.Convention); parameters.Add(arg); } } fpuDelta -= FpuStackOffset; FpuStackOffset = fpuDelta; var sig = new FunctionType(ret, parameters.ToArray()) { IsInstanceMetod = ss.IsInstanceMethod, }; ApplyConvention(ss, sig); return(sig); } else { var dtRet = ss.ReturnValue != null && ss.ReturnValue.Type != null ? ss.ReturnValue.Type.Accept(TypeLoader) : null; var dtThis = ss.EnclosingType != null ? new Pointer(ss.EnclosingType.Accept(TypeLoader), Architecture.PointerType.BitSize) : null; var dtParameters = ss.Arguments != null ? ss.Arguments .TakeWhile(p => p.Name != "...") .Select(p => p.Type.Accept(TypeLoader)) .ToList() : new List <DataType>(); // A calling convention governs the storage of a the // parameters var cc = platform.GetCallingConvention(ss.Convention); var res = new CallingConventionEmitter(); cc.Generate(res, dtRet, dtThis, dtParameters); if (res.Return != null) { var retReg = res.Return as RegisterStorage; ret = new Identifier(retReg != null ? retReg.Name : "", dtRet, res.Return); } if (res.ImplicitThis != null) { var param = new Identifier("this", dtThis, res.ImplicitThis); parameters.Add(param); } if (ss.Arguments != null) { for (int i = 0; i < ss.Arguments.Length; ++i) { if (ss.Arguments[i].Name == "...") { var unk = new UnknownType(); parameters.Add(new Identifier("...", unk, new StackArgumentStorage(0, unk))); } else { var name = GenerateParameterName(ss.Arguments[i].Name, dtParameters[i], res.Parameters[i]); var param = new Identifier(name, dtParameters[i], res.Parameters[i]); parameters.Add(param); } } } var ft = new FunctionType(ret, parameters.ToArray()) { IsInstanceMetod = ss.IsInstanceMethod, StackDelta = ss.StackDelta != 0 ? ss.StackDelta : res.StackDelta, FpuStackDelta = res.FpuStackDelta, ReturnAddressOnStack = retAddrSize, }; return(ft); } }
public void Setup() { this.emitter = new CallingConventionEmitter(); }
private void Given_CallingConvention() { this.cc = new SuperHCallingConvention(arch); this.ccr = new CallingConventionEmitter(); }
/// <summary> /// Deserializes the signature <paramref name="ss"/>. Any instantiated /// registers or stack variables are introduced into the Frame. /// </summary> /// <param name="ss"></param> /// <param name="frame"></param> /// <returns></returns> public FunctionType Deserialize(SerializedSignature ss, Frame frame) { if (ss == null) { return(null); } // If there is no explict return address size, // use the architecture's default return address size. var retAddrSize = ss.ReturnAddressOnStack != 0 ? ss.ReturnAddressOnStack : this.Architecture.ReturnAddressOnStack; if (!ss.ParametersValid) { return(new FunctionType { StackDelta = ss.StackDelta, ReturnAddressOnStack = retAddrSize, }); } var parameters = new List <Identifier>(); Identifier ret = null; if (UseUserSpecifiedStorages(ss)) { this.argDeser = new ArgumentDeserializer( this, Architecture, frame, retAddrSize, Architecture.WordWidth.Size); int fpuDelta = FpuStackOffset; FpuStackOffset = 0; if (ss.ReturnValue != null) { ret = DeserializeArgument(ss.ReturnValue, -1, ""); fpuDelta += FpuStackOffset; } FpuStackOffset = 0; if (ss.Arguments != null) { for (int iArg = 0; iArg < ss.Arguments.Length; ++iArg) { var sArg = ss.Arguments[iArg]; var arg = DeserializeArgument(sArg, iArg, ss.Convention); if (arg != null) { parameters.Add(arg); } } } fpuDelta -= FpuStackOffset; FpuStackOffset = fpuDelta; var sig = new FunctionType(ret, parameters.ToArray()) { IsVariadic = this.IsVariadic, IsInstanceMetod = ss.IsInstanceMethod, }; ApplyConvention(ss, sig); return(sig); } else { var dtRet = ss.ReturnValue != null && ss.ReturnValue.Type != null ? ss.ReturnValue.Type.Accept(TypeLoader) : null; var dtThis = ss.EnclosingType != null ? new Pointer(ss.EnclosingType.Accept(TypeLoader), Architecture.PointerType.BitSize) : null; var dtParameters = ss.Arguments != null ? ss.Arguments .TakeWhile(p => p.Name != "...") .Select(p => p.Type.Accept(TypeLoader)) .ToList() : new List <DataType>(); // A calling convention governs the storage of a the // parameters var cc = platform.GetCallingConvention(ss.Convention); if (cc == null) { // It was impossible to determine a calling convention, // so we don't know how to decode this signature accurately. return(new FunctionType { StackDelta = ss.StackDelta, ReturnAddressOnStack = retAddrSize, }); } var res = new CallingConventionEmitter(); cc.Generate(res, dtRet, dtThis, dtParameters); if (res.Return != null) { var retReg = res.Return as RegisterStorage; ret = new Identifier(retReg != null ? retReg.Name : "", dtRet, res.Return); } if (res.ImplicitThis != null) { var param = new Identifier("this", dtThis, res.ImplicitThis); parameters.Add(param); } bool isVariadic = false; if (ss.Arguments != null) { for (int i = 0; i < ss.Arguments.Length; ++i) { if (ss.Arguments[i].Name == "...") { isVariadic = true; } else { var name = GenerateParameterName(ss.Arguments[i].Name, dtParameters[i], res.Parameters[i]); var param = new Identifier(name, dtParameters[i], res.Parameters[i]); parameters.Add(param); } } } var ft = new FunctionType(ret, parameters.ToArray()) { IsInstanceMetod = ss.IsInstanceMethod, StackDelta = ss.StackDelta != 0 ? ss.StackDelta : res.StackDelta, FpuStackDelta = res.FpuStackDelta, ReturnAddressOnStack = retAddrSize, IsVariadic = isVariadic, }; return(ft); } }
public void Setup() { this.cc = new AArch64CallingConvention(arch); this.ccr = new CallingConventionEmitter(); }