Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Z3 all the things #282

Merged
merged 57 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
e83f9c1
WIP: Z3 all the things
frabert Jul 8, 2022
58d2e34
Fix bugs
frabert Jul 21, 2022
5d33d07
Fix bug
frabert Jul 21, 2022
b9e3264
Combine whiles
frabert Jul 21, 2022
4ed0040
Improve simplification
frabert Jul 21, 2022
7739b45
Better condition generation. Still slow.
frabert Jul 22, 2022
29f02ed
Revert to simple substitution
frabert Aug 1, 2022
1b2d720
Refactor ZCS
frabert Aug 2, 2022
4739b4a
Refactor NCP
frabert Aug 2, 2022
9223a8f
Fix NCP bugs
frabert Aug 4, 2022
61b5a27
Fix condition sharing bug
frabert Aug 8, 2022
30ba945
Fix CBR
frabert Aug 8, 2022
06de4fb
Temporarily disable RBR
frabert Aug 8, 2022
6547998
Improve `else-if` recognition
frabert Aug 8, 2022
f352e0f
Improve switch conditions generation
frabert Aug 9, 2022
e244c00
Factor out `Sort`
frabert Aug 9, 2022
8309f2a
Sort during simplification, use faster simplify
frabert Aug 9, 2022
e8af6c2
Improve NCP
frabert Aug 9, 2022
4258686
Remove RBR
frabert Aug 9, 2022
791de8e
Fix bug
frabert Aug 9, 2022
47ccf7e
Try improve performance
frabert Aug 10, 2022
5d1c7ee
Reintroduce RBR
frabert Aug 11, 2022
a85e490
Fix NCP
frabert Aug 11, 2022
d5d68bf
Remove `IsConstant`
frabert Aug 11, 2022
367a1c6
Reactivate RBR
frabert Aug 11, 2022
a1de89d
Remove ignored tests
frabert Aug 11, 2022
d5f2f7d
Fix CBR & RBR
frabert Aug 12, 2022
7005059
Factor out RBR lambda
frabert Aug 12, 2022
3747557
CBR & RBR review
frabert Aug 12, 2022
1b8d3d5
Cleanup
frabert Aug 19, 2022
3661cc0
Remove `nc` from tools
frabert Aug 19, 2022
0526a4a
Maybe this time `HeavySimplify` will work?
frabert Aug 19, 2022
7319504
Rename "Provenance" to "DecompilationContext"
frabert Aug 22, 2022
39edaa3
Remove temporary variables for `load`s
frabert Aug 26, 2022
fed7db1
Rename `POISON_IDX`
frabert Aug 31, 2022
94b4dd5
Put all aliases inside `DecompilationContext`
frabert Aug 31, 2022
923fb57
Rename `Sort` to `OrderById`
frabert Aug 31, 2022
e8ece29
Revert useless change
frabert Aug 31, 2022
23e9e75
Simplify exit
frabert Aug 31, 2022
886db0b
Short-circuit slow condition
frabert Aug 31, 2022
e79a3bf
Add explanation
frabert Aug 31, 2022
0752a67
Add comments for `KnownExprs`
frabert Aug 31, 2022
51e5397
Map expression directly by id
frabert Aug 31, 2022
ee48c73
Add small comment
frabert Aug 31, 2022
1a438e4
Factor out CBR
frabert Aug 31, 2022
4560a7a
Rename parameter for clarity
frabert Aug 31, 2022
70be302
Factor out `ToExpr`
frabert Aug 31, 2022
a6e4e56
Early returns
frabert Aug 31, 2022
599fa46
More cleanup
frabert Aug 31, 2022
88fa360
More cleanup
frabert Aug 31, 2022
0bd968c
Factor out stuff in NCP
frabert Aug 31, 2022
af24ad2
Create wrapper method for Z3 expressions
frabert Aug 31, 2022
c65fe31
Add comments for maps
frabert Sep 1, 2022
27924aa
Cleanup and comment `ConvertExpr`
frabert Sep 1, 2022
7510837
More comments
frabert Sep 1, 2022
e052b36
Remove old comment
frabert Sep 2, 2022
389250e
More comments
frabert Sep 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions ci/angha_1k_test_settings.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
{
"tests.ignore": [
"amd64/linux/tools/perf/bench/extr_numa.c___bench_numa.bc",
"amd64/SoftEtherVPN/src/See/extr_memory_t.h_SW_LONG_AT.bc",
"arm64/linux/tools/perf/bench/extr_numa.c___bench_numa.bc",
"arm64/SoftEtherVPN/src/See/extr_memory_t.h_SW_LONG_AT.bc",
"armv7/linux/tools/perf/bench/extr_numa.c___bench_numa.bc",
"armv7/SoftEtherVPN/src/See/extr_memory_t.h_SW_LONG_AT.bc",
"x86/linux/tools/perf/bench/extr_numa.c___bench_numa.bc",
"x86/SoftEtherVPN/src/See/extr_memory_t.h_SW_LONG_AT.bc"
]
}
10 changes: 5 additions & 5 deletions include/rellic/AST/ASTPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ASTPass {
std::atomic_bool stop{false};

protected:
Provenance& provenance;
DecompilationContext& dec_ctx;
clang::ASTUnit& ast_unit;
clang::ASTContext& ast_ctx;
ASTBuilder ast;
Expand All @@ -32,8 +32,8 @@ class ASTPass {
virtual void StopImpl() {}

public:
ASTPass(Provenance& provenance, clang::ASTUnit& ast_unit)
: provenance(provenance),
ASTPass(DecompilationContext& dec_ctx, clang::ASTUnit& ast_unit)
: dec_ctx(dec_ctx),
ast_unit(ast_unit),
ast_ctx(ast_unit.getASTContext()),
ast(ast_unit) {}
Expand Down Expand Up @@ -89,8 +89,8 @@ class CompositeASTPass : public ASTPass {
}

public:
CompositeASTPass(Provenance& provenance, clang::ASTUnit& ast_unit)
: ASTPass(provenance, ast_unit) {}
CompositeASTPass(DecompilationContext& dec_ctx, clang::ASTUnit& ast_unit)
: ASTPass(dec_ctx, ast_unit) {}
std::vector<std::unique_ptr<ASTPass>>& GetPasses() { return passes; }
};
} // namespace rellic
10 changes: 1 addition & 9 deletions include/rellic/AST/CondBasedRefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "rellic/AST/ASTPass.h"
#include "rellic/AST/IRToASTVisitor.h"
#include "rellic/AST/TransformVisitor.h"
#include "rellic/AST/Z3ConvVisitor.h"

namespace rellic {

Expand All @@ -35,18 +34,11 @@ namespace rellic {
*/
class CondBasedRefine : public TransformVisitor<CondBasedRefine> {
private:
std::unique_ptr<z3::context> z3_ctx;
std::unique_ptr<rellic::Z3ConvVisitor> z3_gen;

z3::tactic z3_solver;

z3::expr GetZ3Cond(clang::IfStmt *ifstmt);

protected:
void RunImpl() override;

public:
CondBasedRefine(Provenance &provenance, clang::ASTUnit &unit);
CondBasedRefine(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitCompoundStmt(clang::CompoundStmt *compound);
};
Expand Down
2 changes: 1 addition & 1 deletion include/rellic/AST/DeadStmtElim.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class DeadStmtElim : public TransformVisitor<DeadStmtElim> {
void RunImpl() override;

public:
DeadStmtElim(Provenance &provenance, clang::ASTUnit &unit);
DeadStmtElim(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitIfStmt(clang::IfStmt *ifstmt);
bool VisitCompoundStmt(clang::CompoundStmt *compound);
Expand Down
2 changes: 1 addition & 1 deletion include/rellic/AST/ExprCombine.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ExprCombine : public TransformVisitor<ExprCombine> {
void RunImpl() override;

public:
ExprCombine(Provenance &provenance, clang::ASTUnit &unit);
ExprCombine(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitCStyleCastExpr(clang::CStyleCastExpr *cast);
bool VisitUnaryOperator(clang::UnaryOperator *op);
Expand Down
48 changes: 22 additions & 26 deletions include/rellic/AST/GenerateAST.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <llvm/IR/PassManager.h>
#include <z3++.h>

#include <limits>
#include <map>
#include <unordered_set>

Expand All @@ -25,28 +26,14 @@ class GenerateAST : public llvm::AnalysisInfoMixin<GenerateAST> {
friend llvm::AnalysisInfoMixin<GenerateAST>;
static llvm::AnalysisKey Key;

// Need to use `map` with these instead of `unordered_map`, because
// `std::pair` doesn't have a default hash implementation
using BBEdge = std::pair<llvm::BasicBlock *, llvm::BasicBlock *>;
using BrEdge = std::pair<llvm::BranchInst *, bool>;
using SwEdge = std::pair<llvm::SwitchInst *, llvm::ConstantInt *>;
constexpr static unsigned poison_idx = std::numeric_limits<unsigned>::max();
frabert marked this conversation as resolved.
Show resolved Hide resolved
z3::expr ToExpr(unsigned idx);

clang::ASTUnit &unit;
clang::ASTContext *ast_ctx;
rellic::IRToASTVisitor ast_gen;
rellic::ASTBuilder ast;
z3::context *z_ctx;

Provenance &provenance;

z3::expr_vector z_exprs;
std::unordered_map<unsigned, BrEdge> z_br_edges_inv;
std::map<BrEdge, unsigned> z_br_edges;

std::unordered_map<unsigned, SwEdge> z_sw_edges_inv;
std::map<SwEdge, unsigned> z_sw_edges;

std::map<BBEdge, unsigned> z_edges;
std::unordered_map<llvm::BasicBlock *, unsigned> reaching_conds;
DecompilationContext &dec_ctx;
bool reaching_conds_changed{true};
std::unordered_map<llvm::BasicBlock *, clang::IfStmt *> block_stmts;
std::unordered_map<llvm::Region *, clang::CompoundStmt *> region_stmts;
Expand All @@ -57,16 +44,25 @@ class GenerateAST : public llvm::AnalysisInfoMixin<GenerateAST> {

std::vector<llvm::BasicBlock *> rpo_walk;

z3::expr GetOrCreateEdgeForBranch(llvm::BranchInst *inst, bool cond);
z3::expr GetOrCreateEdgeForSwitch(llvm::SwitchInst *inst,
// GetOrCreateEdgeForBranch(branch, true) will return the index of an
// expression that is true when branch is taken.
// Viceversa, GetOrCreateEdgeForBranch(branch, false) is an expression that
// will be true when branch is not taken
unsigned GetOrCreateEdgeForBranch(llvm::BranchInst *inst, bool cond);

// Returns the index of an expression containing a numerical variable that
// represents the condition of a switch.
unsigned GetOrCreateVarForSwitch(llvm::SwitchInst *inst);
// Returns the index of an expression that is true when a particular case of a
// switch is taken. If c is nullptr, the expression for the default case will
// be returned.
unsigned GetOrCreateEdgeForSwitch(llvm::SwitchInst *inst,
llvm::ConstantInt *c);

z3::expr GetOrCreateEdgeCond(llvm::BasicBlock *from, llvm::BasicBlock *to);
z3::expr GetReachingCond(llvm::BasicBlock *block);
unsigned GetOrCreateEdgeCond(llvm::BasicBlock *from, llvm::BasicBlock *to);
unsigned GetReachingCond(llvm::BasicBlock *block);
void CreateReachingCond(llvm::BasicBlock *block);

clang::Expr *ConvertExpr(z3::expr expr);

std::vector<clang::Stmt *> CreateBasicBlockStmts(llvm::BasicBlock *block);
std::vector<clang::Stmt *> CreateRegionStmts(llvm::Region *region);

Expand All @@ -82,12 +78,12 @@ class GenerateAST : public llvm::AnalysisInfoMixin<GenerateAST> {

public:
using Result = llvm::PreservedAnalyses;
GenerateAST(Provenance &provenance, clang::ASTUnit &unit);
GenerateAST(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

Result run(llvm::Function &F, llvm::FunctionAnalysisManager &FAM);
Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM);

static void run(llvm::Module &M, Provenance &provenance,
static void run(llvm::Module &M, DecompilationContext &dec_ctx,
clang::ASTUnit &unit);
};

Expand Down
5 changes: 3 additions & 2 deletions include/rellic/AST/IRToASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ class IRToASTVisitor {

ASTBuilder ast;

Provenance &provenance;
DecompilationContext &dec_ctx;

void VisitArgument(llvm::Argument &arg);

public:
IRToASTVisitor(clang::ASTUnit &unit, Provenance &provenance);
IRToASTVisitor(clang::ASTUnit &unit, DecompilationContext &dec_ctx);

clang::Expr *CreateOperandExpr(llvm::Use &val);
clang::Expr *CreateConstantExpr(llvm::Constant *constant);
clang::Expr *ConvertExpr(z3::expr expr);

void VisitGlobalVar(llvm::GlobalVariable &var);
void VisitFunctionDecl(llvm::Function &func);
Expand Down
4 changes: 2 additions & 2 deletions include/rellic/AST/InferenceRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ class InferenceRule : public clang::ast_matchers::MatchFinder::MatchCallback {
return cond;
}

virtual clang::Stmt *GetOrCreateSubstitution(Provenance &provenance,
virtual clang::Stmt *GetOrCreateSubstitution(DecompilationContext &dec_ctx,
clang::ASTUnit &unit,
clang::Stmt *stmt) = 0;
};

clang::Stmt *ApplyFirstMatchingRule(
Provenance &provenance, clang::ASTUnit &unit, clang::Stmt *stmt,
DecompilationContext &dec_ctx, clang::ASTUnit &unit, clang::Stmt *stmt,
std::vector<std::unique_ptr<InferenceRule>> &rules);

} // namespace rellic
2 changes: 1 addition & 1 deletion include/rellic/AST/LocalDeclRenamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class LocalDeclRenamer : public TransformVisitor<LocalDeclRenamer> {
void RunImpl() override;

public:
LocalDeclRenamer(Provenance &provenance, clang::ASTUnit &unit,
LocalDeclRenamer(DecompilationContext &dec_ctx, clang::ASTUnit &unit,
IRToNameMap &names);

bool shouldTraversePostOrder() override;
Expand Down
2 changes: 1 addition & 1 deletion include/rellic/AST/LoopRefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class LoopRefine : public TransformVisitor<LoopRefine> {
void RunImpl() override;

public:
LoopRefine(Provenance &provenance, clang::ASTUnit &unit);
LoopRefine(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitWhileStmt(clang::WhileStmt *loop);
};
Expand Down
37 changes: 37 additions & 0 deletions include/rellic/AST/MaterializeConds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021-present, Trail of Bits, Inc.
* All rights reserved.
*
* This source code is licensed in accordance with the terms specified in
* the LICENSE file found in the root directory of this source tree.
*/

#pragma once

#include <clang/AST/ASTContext.h>

#include "rellic/AST/IRToASTVisitor.h"
#include "rellic/AST/TransformVisitor.h"

namespace rellic {

/*
* This pass substitutes the marker expression in loops and `if` statements for
* their translation from Z3 formulas
*/
class MaterializeConds : public TransformVisitor<MaterializeConds> {
private:
IRToASTVisitor ast_gen;

protected:
void RunImpl() override;

public:
MaterializeConds(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitIfStmt(clang::IfStmt *stmt);
bool VisitWhileStmt(clang::WhileStmt *loop);
bool VisitDoStmt(clang::DoStmt *loop);
};

} // namespace rellic
2 changes: 1 addition & 1 deletion include/rellic/AST/NestedCondProp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class NestedCondProp : public ASTPass {
void RunImpl() override;

public:
NestedCondProp(Provenance &provenance, clang::ASTUnit &unit);
NestedCondProp(DecompilationContext& dec_ctx, clang::ASTUnit& unit);
};

} // namespace rellic
3 changes: 2 additions & 1 deletion include/rellic/AST/NestedScopeCombine.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class NestedScopeCombine : public TransformVisitor<NestedScopeCombine> {
void RunImpl() override;

public:
NestedScopeCombine(Provenance &provenance, clang::ASTUnit &unit);
NestedScopeCombine(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitIfStmt(clang::IfStmt *ifstmt);
bool VisitWhileStmt(clang::WhileStmt *stmt);
bool VisitCompoundStmt(clang::CompoundStmt *compound);
};

Expand Down
33 changes: 0 additions & 33 deletions include/rellic/AST/NormalizeCond.h

This file was deleted.

8 changes: 1 addition & 7 deletions include/rellic/AST/ReachBasedRefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#pragma once

#include "rellic/AST/TransformVisitor.h"
#include "rellic/AST/Z3ConvVisitor.h"

namespace rellic {

Expand Down Expand Up @@ -38,16 +37,11 @@ namespace rellic {
*/
class ReachBasedRefine : public TransformVisitor<ReachBasedRefine> {
private:
std::unique_ptr<z3::context> z3_ctx;
std::unique_ptr<rellic::Z3ConvVisitor> z3_gen;

z3::expr GetZ3Cond(clang::IfStmt *ifstmt);

protected:
void RunImpl() override;

public:
ReachBasedRefine(Provenance &provenance, clang::ASTUnit &unit);
ReachBasedRefine(DecompilationContext &dec_ctx, clang::ASTUnit &unit);

bool VisitCompoundStmt(clang::CompoundStmt *compound);
};
Expand Down
2 changes: 1 addition & 1 deletion include/rellic/AST/StructFieldRenamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class StructFieldRenamer
void RunImpl() override;

public:
StructFieldRenamer(Provenance &provenance, clang::ASTUnit &unit,
StructFieldRenamer(DecompilationContext &dec_ctx, clang::ASTUnit &unit,
IRTypeToDITypeMap &types);

bool VisitRecordDecl(clang::RecordDecl *decl);
Expand Down
8 changes: 4 additions & 4 deletions include/rellic/AST/TransformVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class TransformVisitor : public ASTPass,
StmtSubMap substitutions;

void CopyProvenance(clang::Stmt *from, clang::Stmt *to) {
::rellic::CopyProvenance(from, to, provenance.stmt_provenance);
::rellic::CopyProvenance(from, to, dec_ctx.stmt_provenance);
}

void CopyProvenance(clang::Expr *from, clang::Expr *to) {
::rellic::CopyProvenance(from, to, provenance.use_provenance);
::rellic::CopyProvenance(from, to, dec_ctx.use_provenance);
}

bool ReplaceChildren(clang::Stmt *stmt, StmtSubMap &repl_map) {
Expand All @@ -55,8 +55,8 @@ class TransformVisitor : public ASTPass,
void RunImpl() override { substitutions.clear(); }

public:
TransformVisitor(Provenance &provenance, clang::ASTUnit &unit)
: ASTPass(provenance, unit) {}
TransformVisitor(DecompilationContext &dec_ctx, clang::ASTUnit &unit)
: ASTPass(dec_ctx, unit) {}

virtual bool shouldTraversePostOrder() { return true; }

Expand Down
Loading