예제 #1
0
		public void AddUseInstructionsForOutArguments(Procedure proc)
		{
			foreach (Identifier id in proc.Signature.Parameters)
			{
				var os = id.Storage as OutArgumentStorage;
				if (os == null)
					continue;
				var r = os.OriginalIdentifier.Storage as RegisterStorage;
				if (r == null)
					continue;

				proc.ExitBlock.Statements.Add(0, new UseInstruction(os.OriginalIdentifier, id));
			}
		}
예제 #2
0
		/// <summary>
		/// Creates a signature for this procedure, and ensures that all registers accessed by the procedure are in the procedure
		/// Frame.
		/// </summary>
		public void EnsureSignature(Procedure proc, ProcedureFlow flow)
		{
			if (proc.Signature != null && proc.Signature.ParametersValid)
				return;

			SignatureBuilder sb = new SignatureBuilder(proc, Program.Architecture);
			Frame frame = proc.Frame;
			if (flow.grfLiveOut != 0)
			{
				sb.AddFlagGroupReturnValue(flow.grfLiveOut, frame);
			}

            var implicitRegs = Program.Platform.CreateImplicitArgumentRegisters();
            BitSet mayUse = flow.MayUse - implicitRegs;
			foreach (int r in mayUse)
			{
				if (!IsSubRegisterOfRegisters(r, mayUse))
				{
					sb.AddRegisterArgument(r);
				}
			}

			foreach (KeyValuePair<int,Identifier> de in GetSortedStackArguments(proc.Frame))
			{
				AddStackArgument(de.Key, de.Value, flow, sb);
			}

            foreach (KeyValuePair<int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, 0))
			{
				sb.AddFpuStackArgument(de.Key, de.Value);
			}

            BitSet liveOut = flow.LiveOut - implicitRegs;
			foreach (int r in liveOut)
			{
				if (!IsSubRegisterOfRegisters(r, liveOut))
				{
					sb.AddArgument(frame.EnsureRegister(Program.Architecture.GetRegister(r)), true);
				}
			}

            foreach (KeyValuePair<int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, -proc.Signature.FpuStackDelta))
			{
				int i = de.Key;
				if (i <= proc.Signature.FpuStackOutArgumentMax)
				{
					sb.AddArgument(frame.EnsureFpuStackVariable(i, de.Value.DataType), true);
				}
			}

            var sig = sb.BuildSignature();
            flow.Signature = sig;
			proc.Signature = sig;
		}
예제 #3
0
		/// <summary>
		/// Having identified the return variable -- if any, rewrite all 
		/// return statements to return that variable.
		/// </summary>
		/// <param name="proc"></param>
        private void RewriteReturns(Procedure proc)
        {
            Identifier idRet = proc.Signature.ReturnValue;
            if (idRet == null)
                return;
            foreach (Statement stm in proc.Statements)
            {
                var ret = stm.Instruction as ReturnInstruction;
                if (ret != null)
                {
                    ret.Expression = idRet;
                }
            }
        }