Skip to content

Commit

Permalink
Merge branch 'release-1.7.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
zvonimir committed Dec 18, 2016
2 parents 46ccd17 + 860fdce commit 435044d
Show file tree
Hide file tree
Showing 32 changed files with 823 additions and 432 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ add_library(smackTranslator STATIC
include/smack/SmackRep.h
include/smack/SmackRepFlatMem.h
include/smack/MemorySafetyChecker.h
include/smack/SignedIntegerOverflowChecker.h
lib/smack/BoogieAst.cpp
lib/smack/BplFilePrinter.cpp
lib/smack/BplPrinter.cpp
Expand All @@ -175,6 +176,7 @@ add_library(smackTranslator STATIC
lib/smack/SmackRep.cpp
lib/smack/SmackRepFlatMem.cpp
lib/smack/MemorySafetyChecker.cpp
lib/smack/SignedIntegerOverflowChecker.cpp
)

add_executable(llvm2bpl
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = smack
PROJECT_NUMBER = 1.7.0
PROJECT_NUMBER = 1.7.1
PROJECT_BRIEF = "A bounded software verifier."
PROJECT_LOGO =
OUTPUT_DIRECTORY = docs
Expand Down
3 changes: 2 additions & 1 deletion bin/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ INSTALL_DEPENDENCIES=1
BUILD_Z3=1
BUILD_BOOGIE=1
BUILD_CORRAL=1
BUILD_LOCKPWN=0
BUILD_LOCKPWN=1
BUILD_SMACK=1
TEST_SMACK=1
BUILD_LLVM=0 # LLVM is typically installed from packages (see below)
Expand Down Expand Up @@ -369,6 +369,7 @@ then
cd ${ROOT}
git clone https://github.com/smackers/lockpwn.git
cd ${LOCKPWN_DIR}
git reset --hard ${LOCKPWN_COMMIT}
xbuild lockpwn.sln /p:Configuration=Release
ln -s ${Z3_DIR}/bin/z3 ${LOCKPWN_DIR}/Binaries/z3.exe

Expand Down
2 changes: 1 addition & 1 deletion bin/package-smack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Note: this script requires CDE to be downloaded from
# http://www.pgbovine.net/cde.html

VERSION=1.7.0
VERSION=1.7.1
PACKAGE=smack-$VERSION-64

# Create folder to export
Expand Down
8 changes: 6 additions & 2 deletions bin/smack-svcomp-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@

ROOT="$( cd "$(dirname "$(readlink -f "${0}")")" && pwd )"
SMACK_BIN="${ROOT}/smack/bin"
BOOGIE_BIN="${ROOT}/boogie"
CORRAL_BIN="${ROOT}/corral"
LOCKPWN_BIN="${ROOT}/lockpwn"
LLVM_BIN="${ROOT}/llvm/bin"
LLVM_LIB="${ROOT}/llvm/lib"

# Setting mono heap size to 9GB
export MONO_GC_PARAMS=max-heap-size=9g
# Setting mono heap size to 13GB
export MONO_GC_PARAMS=max-heap-size=13g

export PATH=${LLVM_BIN}:$SMACK_BIN:$PATH
export BOOGIE="mono ${BOOGIE_BIN}/Boogie.exe"
export CORRAL="mono ${CORRAL_BIN}/corral.exe"
export LOCKPWN="mono ${LOCKPWN_BIN}/lockpwn.exe"
export LD_LIBRARY_PATH=${LLVM_LIB}:$LD_LIBRARY_PATH

smack -x=svcomp --verifier=svcomp -q $@

1 change: 1 addition & 0 deletions bin/versions
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
MONO_VERSION=3.8.0
BOOGIE_COMMIT=4e4c3a5252
CORRAL_COMMIT=874a078e39
LOCKPWN_COMMIT=a4d802a1cb
8 changes: 8 additions & 0 deletions include/smack/BoogieAst.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ class Attr {
public:
Attr(std::string n, std::initializer_list<const Expr*> vs) : name(n), vals(vs) {}
void print(std::ostream& os) const;
std::string getName() const { return name; }

static const Attr* attr(std::string s);
static const Attr* attr(std::string s, std::string v);
Expand Down Expand Up @@ -268,6 +269,13 @@ class AssumeStmt : public Stmt {
void add(const Attr* a) {
attrs.push_back(a);
}
bool hasAttr(std::string name) const {
for (auto a = attrs.begin(); a != attrs.end(); ++a) {
if ((*a)->getName() == name)
return true;
}
return false;
}
void print(std::ostream& os) const;
static bool classof(const Stmt* S) { return S->getKind() == ASSUME; }
};
Expand Down
27 changes: 27 additions & 0 deletions include/smack/SignedIntegerOverflowChecker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// This file is distributed under the MIT License. See LICENSE for details.
//
#ifndef SIGNEDINTEGEROVERFLOWCHECKER_H
#define SIGNEDINTEGEROVERFLOWCHECKER_H

#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include <map>

namespace smack {

class SignedIntegerOverflowChecker: public llvm::ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
SignedIntegerOverflowChecker() : llvm::ModulePass(ID) {}
virtual bool runOnModule(llvm::Module& m);
private:
static std::map<std::string, llvm::Instruction::BinaryOps> INSTRUCTION_TABLE;
static std::map<int, std::string> INT_MAX_TABLE;
static std::map<int, std::string> INT_MIN_TABLE;
void replaceValue(llvm::Value* ee, llvm::Value* er);
};

}

#endif //SIGNEDINTEGEROVERFLOWCHECKER_H
1 change: 1 addition & 0 deletions include/smack/SmackInstGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class SmackInstGenerator : public llvm::InstVisitor<SmackInstGenerator> {
Naming& naming;

Block* currBlock;
llvm::BasicBlock::const_iterator nextInst;
std::map<const llvm::BasicBlock*, Block*> blockMap;
std::map<const llvm::Value*, std::string> sourceNames;

Expand Down
6 changes: 3 additions & 3 deletions include/smack/SmackRep.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class SmackRep {

const Expr* cast(unsigned opcode, const llvm::Value* v, const llvm::Type* t);
const Expr* bop(unsigned opcode, const llvm::Value* lhs, const llvm::Value* rhs, const llvm::Type* t);
const Expr* cmp(unsigned predicate, const llvm::Value* lhs, const llvm::Value* rhs);
const Expr* cmp(unsigned predicate, const llvm::Value* lhs, const llvm::Value* rhs, bool isUnsigned);

std::string procName(const llvm::User& U);
std::string procName(llvm::Function* F, const llvm::User& U);
Expand Down Expand Up @@ -99,14 +99,14 @@ class SmackRep {
std::string type(const llvm::Type* t);
std::string type(const llvm::Value* v);

const Expr* lit(const llvm::Value* v);
const Expr* lit(const llvm::Value* v, bool isUnsigned=false);
const Expr* lit(const llvm::Value* v, unsigned flag);

const Expr* ptrArith(const llvm::GetElementPtrInst* I);
const Expr* ptrArith(const llvm::ConstantExpr* CE);
const Expr* ptrArith(const llvm::Value* p, std::vector< std::pair<llvm::Value*,llvm::Type*> > args);

const Expr* expr(const llvm::Value* v);
const Expr* expr(const llvm::Value* v, bool isConstIntUnsigned=false);

const Expr* cast(const llvm::Instruction* I);
const Expr* cast(const llvm::ConstantExpr* CE);
Expand Down
125 changes: 125 additions & 0 deletions lib/smack/SignedIntegerOverflowChecker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//
// This file is distributed under the MIT License. See LICENSE for details.
//
#include "smack/SignedIntegerOverflowChecker.h"
#include "smack/Naming.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Constants.h"
#include "llvm/Support/Debug.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/Regex.h"
#include <string>

namespace smack {

using namespace llvm;

Regex OVERFLOW_INTRINSICS("^llvm.s(add|sub|mul).with.overflow.i(32|64)$");

std::map<std::string, Instruction::BinaryOps> SignedIntegerOverflowChecker::INSTRUCTION_TABLE {
{"add", Instruction::Add},
{"sub", Instruction::Sub},
{"mul", Instruction::Mul}
};

std::map<int, std::string> SignedIntegerOverflowChecker::INT_MAX_TABLE {
{32, "2147483647"},
{64, "9223372036854775807"}
};

std::map<int, std::string> SignedIntegerOverflowChecker::INT_MIN_TABLE {
{32, "-2147483648"},
{64, "-9223372036854775808"}
};

void SignedIntegerOverflowChecker::replaceValue(Value* ee, Value* er) {
for (auto u : ee->users()) {
if (auto inst = dyn_cast<Instruction>(u)) {
if (inst != cast<Instruction>(ee)) {
for (unsigned i = 0; i < inst->getNumOperands(); ++i) {
if (inst->getOperand(i) == ee)
inst->setOperand(i, er);
}
}
}
}
}

bool SignedIntegerOverflowChecker::runOnModule(Module& m) {
DataLayout* dataLayout = new DataLayout(&m);
Function* va = m.getFunction("__SMACK_overflow_false");
Function* co = m.getFunction("__SMACK_check_overflow");

for (auto& F : m) {
if (!Naming::isSmackName(F.getName())) {
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
if (auto ci = dyn_cast<CallInst>(&*I)) {
Function* f = ci->getCalledFunction();
if (f && f->hasName() && f->getName() == "llvm.trap") {
ci->setCalledFunction(va);
}
}
if (auto ei = dyn_cast<ExtractValueInst>(&*I)) {
if (auto ci = dyn_cast<CallInst>(ei->getAggregateOperand())) {
Function* f = ci->getCalledFunction();
SmallVectorImpl<StringRef> *ar = new SmallVector<StringRef, 3>;
if (f && f->hasName() && OVERFLOW_INTRINSICS.match(f->getName().str(), ar)) {
std::string op = ar->begin()[1].str();
std::string len = ar->begin()[2].str();
int bits = std::stoi(len);
if (ei->getIndices()[0] == 0) {
Value* o1 = ci->getArgOperand(0);
Value* o2 = ci->getArgOperand(1);
CastInst* so1 = CastInst::CreateSExtOrBitCast(o1, IntegerType::get(F.getContext(), bits*2), "", &*I);
CastInst* so2 = CastInst::CreateSExtOrBitCast(o2, IntegerType::get(F.getContext(), bits*2), "", &*I);
BinaryOperator* ai = BinaryOperator::Create(INSTRUCTION_TABLE.at(op), so1, so2, "", &*I);
CastInst* tr = CastInst::CreateTruncOrBitCast(ai, IntegerType::get(F.getContext(), bits), "", &*I);
//replaceValue(&*I, tr);
(*I).replaceAllUsesWith(tr);
//I->eraseFromParent();
}
if (ei->getIndices()[0] == 1) {
auto ai = std::prev(std::prev(std::prev(I)));
ConstantInt* max = ConstantInt::get(IntegerType::get(F.getContext(), bits*2), INT_MAX_TABLE.at(bits), 10);
ConstantInt* min = ConstantInt::get(IntegerType::get(F.getContext(), bits*2), INT_MIN_TABLE.at(bits), 10);
ICmpInst* gt = new ICmpInst(&*I, CmpInst::ICMP_SGT, &*ai, max, "");
ICmpInst* lt = new ICmpInst(&*I, CmpInst::ICMP_SLT, &*ai, min, "");
BinaryOperator* flag = BinaryOperator::Create(Instruction::Or, gt, lt, "", &*I);
//replaceValue(&*I, flag);
(*I).replaceAllUsesWith(flag);
}
}
}
}
if (auto sdi = dyn_cast<BinaryOperator>(&*I)) {
if (sdi->getOpcode() == Instruction::SDiv) {
int bits = sdi->getType()->getIntegerBitWidth();
Value* o1 = sdi->getOperand(0);
Value* o2 = sdi->getOperand(1);
CastInst* so1 = CastInst::CreateSExtOrBitCast(o1, IntegerType::get(F.getContext(), bits*2), "", &*I);
CastInst* so2 = CastInst::CreateSExtOrBitCast(o2, IntegerType::get(F.getContext(), bits*2), "", &*I);
BinaryOperator* lsdi = BinaryOperator::Create(Instruction::SDiv, so1, so2, "", &*I);
ConstantInt* max = ConstantInt::get(IntegerType::get(F.getContext(), bits*2), INT_MAX_TABLE.at(bits), 10);
ConstantInt* min = ConstantInt::get(IntegerType::get(F.getContext(), bits*2), INT_MIN_TABLE.at(bits), 10);
ICmpInst* gt = new ICmpInst(&*I, CmpInst::ICMP_SGT, lsdi, max, "");
ICmpInst* lt = new ICmpInst(&*I, CmpInst::ICMP_SLT, lsdi, min, "");
BinaryOperator* flag = BinaryOperator::Create(Instruction::Or, gt, lt, "", &*I);
CastInst* tf = CastInst::CreateSExtOrBitCast(flag, co->getArgumentList().begin()->getType(), "", &*I);
CallInst* ci = CallInst::Create(co, {tf}, "", &*I);
CastInst* tv = CastInst::CreateTruncOrBitCast(lsdi, sdi->getType(), "", &*I);
//replaceValue(&*I, tv);
(*I).replaceAllUsesWith(tv);
}
}
}
}
}
return true;
}

// Pass ID variable
char SignedIntegerOverflowChecker::ID = 0;
}
52 changes: 40 additions & 12 deletions lib/smack/SmackInstGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Regex VAR_DECL("^[[:space:]]*var[[:space:]]+([[:alpha:]_.$#'`~^\\?][[:alnum:]_.$
// Procedures whose return value should not be marked as external
Regex EXTERNAL_PROC_IGNORE("^(malloc|__VERIFIER_nondet)$");

std::string i2s(llvm::Instruction& i) {
std::string i2s(const llvm::Instruction& i) {
std::string s;
llvm::raw_string_ostream ss(s);
ss << i;
Expand Down Expand Up @@ -87,9 +87,11 @@ void SmackInstGenerator::processInstruction(llvm::Instruction& inst) {
annotate(inst, currBlock);
ORIG(inst);
nameInstruction(inst);
nextInst++;
}

void SmackInstGenerator::visitBasicBlock(llvm::BasicBlock& bb) {
nextInst = bb.begin();
currBlock = getBlock(&bb);
}

Expand Down Expand Up @@ -278,10 +280,14 @@ void SmackInstGenerator::visitBinaryOperator(llvm::BinaryOperator& I) {

void SmackInstGenerator::visitExtractValueInst(llvm::ExtractValueInst& evi) {
processInstruction(evi);
const Expr* e = rep.expr(evi.getAggregateOperand());
for (unsigned i = 0; i < evi.getNumIndices(); i++)
e = Expr::fn(Naming::EXTRACT_VALUE, e, Expr::lit((unsigned long) evi.getIndices()[i]));
emit(Stmt::assign(rep.expr(&evi),e));
if (!SmackOptions::BitPrecise) {
const Expr* e = rep.expr(evi.getAggregateOperand());
for (unsigned i = 0; i < evi.getNumIndices(); i++)
e = Expr::fn(Naming::EXTRACT_VALUE, e, Expr::lit((unsigned long) evi.getIndices()[i]));
emit(Stmt::assign(rep.expr(&evi),e));
} else {
WARN("Ignoring extract instruction under bit vector mode.");
}
}

void SmackInstGenerator::visitInsertValueInst(llvm::InsertValueInst& ivi) {
Expand Down Expand Up @@ -353,8 +359,12 @@ void SmackInstGenerator::visitStoreInst(llvm::StoreInst& si) {

if (SmackOptions::SourceLocSymbols) {
if (const llvm::GlobalVariable* G = llvm::dyn_cast<const llvm::GlobalVariable>(P)) {
assert(G->hasName() && "Expected named global variable.");
emit(Stmt::call("boogie_si_record_" + rep.type(V), {rep.expr(V)}, {}, {Attr::attr("cexpr", G->getName().str())}));
if (const llvm::PointerType* t = llvm::dyn_cast<const llvm::PointerType>(G->getType())) {
if (!t->getElementType()->isPointerTy()) {
assert(G->hasName() && "Expected named global variable.");
emit(Stmt::call("boogie_si_record_" + rep.type(V), {rep.expr(V)}, {}, {Attr::attr("cexpr", G->getName().str())}));
}
}
}
}

Expand Down Expand Up @@ -589,17 +599,35 @@ void SmackInstGenerator::visitCallInst(llvm::CallInst& ci) {
}
}

bool isSourceLoc(const Stmt* stmt) {
return (stmt->getKind() == Stmt::ASSUME
&& (llvm::cast<const AssumeStmt>(stmt))->hasAttr("sourceloc"))
|| (stmt->getKind() == Stmt::CALL);
}

void SmackInstGenerator::visitDbgValueInst(llvm::DbgValueInst& dvi) {
processInstruction(dvi);

if (SmackOptions::SourceLocSymbols) {
const Value* V = dvi.getValue();
const llvm::DILocalVariable *var = dvi.getVariable();
if (V) {
V = V->stripPointerCasts();
std::stringstream recordProc;
recordProc << "boogie_si_record_" << rep.type(V);
emit(Stmt::call(recordProc.str(), {rep.expr(V)}, {}, {Attr::attr("cexpr", var->getName().str())}));
//if (V && !V->getType()->isPointerTy() && !llvm::isa<ConstantInt>(V)) {
if (V && !V->getType()->isPointerTy()) {
//if (currBlock->begin() != currBlock->end()
//&& currBlock->getStatements().back()->getKind() == Stmt::ASSUME) {
// && isSourceLoc(currBlock->getStatements().back())) {
//assert(&*currInst == &dvi && "Current Instruction mismatch!");
auto currInst = std::prev(nextInst);
if (currInst != dvi.getParent()->begin()) {
const Instruction& pi = *std::prev(currInst);
V = V->stripPointerCasts();
WARN(i2s(pi));
if (!llvm::isa<const PHINode>(&pi) && V == llvm::dyn_cast<const Value>(&pi)) {
std::stringstream recordProc;
recordProc << "boogie_si_record_" << rep.type(V);
emit(Stmt::call(recordProc.str(), {rep.expr(V)}, {}, {Attr::attr("cexpr", var->getName().str())}));
}
}
}
}
}
Expand Down
Loading

0 comments on commit 435044d

Please sign in to comment.