public void FixInboundEdges(Block blockToPromote) { // Get all blocks that are from "outside" blocks. var inboundBlocks = blockToPromote.Pred.Where(p => p.Procedure != ProcNew).ToArray(); foreach (var inb in inboundBlocks) { if (inb.Statements.Count > 0) { var lastAddress = GetAddressOfLastInstruction(inb); var callRetThunkBlock = Scanner.CreateCallRetThunk(lastAddress, inb.Procedure, ProcNew); ReplaceSuccessorsWith(inb, blockToPromote, callRetThunkBlock); callRetThunkBlock.Pred.Add(inb); } else { inb.Statements.Add(0, new CallInstruction( new ProcedureConstant(Program.Platform.PointerType, ProcNew), new CallSite(ProcNew.Signature.ReturnAddressOnStack, 0))); Program.CallGraph.AddEdge(inb.Statements.Last, ProcNew); inb.Statements.Add(0, new ReturnInstruction()); inb.Procedure.ControlGraph.AddEdge(inb, inb.Procedure.ExitBlock); } } foreach (var p in inboundBlocks) { blockToPromote.Pred.Remove(p); } }
public void FixInboundEdges(Block blockToPromote) { trace.Verbose("PBW: Fixing inbound edges of {0}", blockToPromote.DisplayName); // Get all blocks that are from "outside" blocks. var inboundBlocks = blockToPromote.Pred.Where(p => p.Procedure != ProcNew).ToArray(); foreach (var inb in inboundBlocks) { if (inb.Statements.Count > 0) { var lastAddress = GetAddressOfLastInstruction(inb); var callRetThunkBlock = Scanner.CreateCallRetThunk(lastAddress, inb.Procedure, ProcNew); ReplaceSuccessorsWith(inb, blockToPromote, callRetThunkBlock); callRetThunkBlock.Pred.Add(inb); } else { var stmLast = inb.Statements.Add( inb.Address.ToLinear(), new CallInstruction( new ProcedureConstant(Program.Platform.PointerType, ProcNew), new CallSite(0, 0))); Program.CallGraph.AddEdge(stmLast, ProcNew); inb.Statements.Add(inb.Address.ToLinear(), new ReturnInstruction()); inb.Procedure.ControlGraph.AddEdge(inb, inb.Procedure.ExitBlock); } } foreach (var p in inboundBlocks) { blockToPromote.Pred.Remove(p); } }
private Block FallenThroughNextProcedure(Address addrInstr, Address addrTo) { if (program.Procedures.TryGetValue(addrTo, out var procOther) && procOther != blockCur.Procedure) { // Fell into another procedure. var block = scanner.CreateCallRetThunk(addrInstr, blockCur.Procedure, procOther); return(block); } return(null); }