/* * ILBuilder.java - This file is part of the Jakstab project. * Copyright 2007-2015 Johannes Kinder <jk@jakstab.org> * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, see <http://www.gnu.org/licenses/>. */ package org.jakstab.rtl.statements; import org.jakstab.Program; import org.jakstab.asm.AbsoluteAddress; import org.jakstab.cfa.RTLLabel; import org.jakstab.rtl.expressions.ExpressionFactory; import org.jakstab.rtl.expressions.RTLExpression; import org.jakstab.rtl.expressions.RTLVariable; import org.jakstab.ssl.Architecture; public class ILBuilder { private static ILBuilder instance = new ILBuilder(); public static ILBuilder getInstance() { return instance; } private RTLVariable sp; private Architecture arch; private ILBuilder() { Program program = Program.getProgram(); arch = program.getArchitecture(); sp = arch.stackPointer(); } /** * Add a the statements equivalent to a push instruction to the end of a sequence. * * @param value the value to push * @param seq the sequence to add the statements to */ public void createPush(RTLExpression value, StatementSequence seq) { createSPIncrement(-(value.getBitWidth() / 8), seq); seq.addLast(new RTLMemoryAssignment(ExpressionFactory.createMemoryLocation( sp, arch.getAddressBitWidth()), value)); } public void createSPIncrement(int delta, StatementSequence seq) { seq.addLast(new RTLVariableAssignment( sp.getBitWidth(), sp, ExpressionFactory.createPlus(sp, delta))); } public void linkAndStoreSequence(AbsoluteAddress address, StatementSequence seq) { int rtlId = 0; for (RTLStatement stmt : seq) { stmt.setLabel(address, rtlId++); stmt.setNextLabel(new RTLLabel(address, rtlId)); } seq.getLast().setNextLabel(null); // add stub statements to program for (RTLStatement s : seq) Program.getProgram().putStatement(s); } }