16 : actx(ctx.getAstContext()), ctx(&ctx) {
21 : actx(actx), ctx(nullptr) {
26 llvm::Argument* argument = llvm::dyn_cast_or_null<llvm::Argument>(value);
27 llvm::CallInst* call = llvm::dyn_cast_or_null<llvm::CallInst>(value);
28 llvm::ConstantInt* constant = llvm::dyn_cast_or_null<llvm::ConstantInt>(value);
29 llvm::ICmpInst* icmp = llvm::dyn_cast_or_null<llvm::ICmpInst>(value);
30 llvm::Instruction* instruction = llvm::dyn_cast_or_null<llvm::Instruction>(value);
32 if (instruction !=
nullptr) {
35 if (call !=
nullptr) {
36 if (call->getCalledFunction()->getName().find(
"llvm.bswap.i") != std::string::npos) {
37 return this->actx->bswap(this->do_convert(call->getOperand(0)));
39 else if (call->getCalledFunction()->getName().find(
"llvm.ctpop.i") != std::string::npos) {
40 auto oprnd = this->do_convert(call->getOperand(0));
41 auto node = this->actx->bv(0, oprnd->getBitvectorSize());
43 node = this->actx->bvadd(node, this->actx->zx(oprnd->getBitvectorSize() - 1, this->actx->extract(i, i, oprnd)));
48 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
51 switch (instruction->getOpcode()) {
53 case llvm::Instruction::AShr: {
54 auto LHS = this->do_convert(instruction->getOperand(0));
55 auto RHS = this->do_convert(instruction->getOperand(1));
56 return this->actx->bvashr(LHS, RHS);
59 case llvm::Instruction::Add: {
60 auto LHS = this->do_convert(instruction->getOperand(0));
61 auto RHS = this->do_convert(instruction->getOperand(1));
62 return this->actx->bvadd(LHS, RHS);
65 case llvm::Instruction::And: {
66 auto LHS = this->do_convert(instruction->getOperand(0));
67 auto RHS = this->do_convert(instruction->getOperand(1));
69 if (LHS->isLogical() && RHS->isLogical()) {
70 return this->actx->ite(this->actx->land(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
72 return this->actx->bvand(LHS, RHS);
75 case llvm::Instruction::ICmp: {
77 auto LHS = this->do_convert(instruction->getOperand(0));
78 auto RHS = this->do_convert(instruction->getOperand(1));
79 if (icmp !=
nullptr) {
80 switch (icmp->getPredicate()) {
81 case llvm::ICmpInst::ICMP_EQ:
return this->actx->equal(LHS, RHS);
82 case llvm::ICmpInst::ICMP_NE:
return this->actx->distinct(LHS, RHS);
83 case llvm::ICmpInst::ICMP_UGE:
return this->actx->bvuge(LHS, RHS);
84 case llvm::ICmpInst::ICMP_UGT:
return this->actx->bvugt(LHS, RHS);
85 case llvm::ICmpInst::ICMP_ULE:
return this->actx->bvule(LHS, RHS);
86 case llvm::ICmpInst::ICMP_ULT:
return this->actx->bvult(LHS, RHS);
87 case llvm::ICmpInst::ICMP_SGE:
return this->actx->bvsge(LHS, RHS);
88 case llvm::ICmpInst::ICMP_SGT:
return this->actx->bvsgt(LHS, RHS);
89 case llvm::ICmpInst::ICMP_SLE:
return this->actx->bvsle(LHS, RHS);
90 case llvm::ICmpInst::ICMP_SLT:
return this->actx->bvslt(LHS, RHS);
99 case llvm::Instruction::LShr: {
100 auto LHS = this->do_convert(instruction->getOperand(0));
101 auto RHS = this->do_convert(instruction->getOperand(1));
102 return this->actx->bvlshr(LHS, RHS);
105 case llvm::Instruction::Mul: {
106 auto LHS = this->do_convert(instruction->getOperand(0));
107 auto RHS = this->do_convert(instruction->getOperand(1));
108 return this->actx->bvmul(LHS, RHS);
111 case llvm::Instruction::Or: {
112 auto LHS = this->do_convert(instruction->getOperand(0));
113 auto RHS = this->do_convert(instruction->getOperand(1));
115 if (LHS->isLogical() && RHS->isLogical()) {
116 return this->actx->ite(this->actx->lor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
118 return this->actx->bvor(LHS, RHS);
121 case llvm::Instruction::Ret:
122 return this->do_convert(instruction->getOperand(0));
124 case llvm::Instruction::SDiv: {
125 auto LHS = this->do_convert(instruction->getOperand(0));
126 auto RHS = this->do_convert(instruction->getOperand(1));
127 return this->actx->bvsdiv(LHS, RHS);
130 case llvm::Instruction::SExt: {
132 auto size = instruction->getType()->getIntegerBitWidth();
133 auto node = this->do_convert(instruction->getOperand(0));
136 if (node->isLogical()) {
137 node = this->actx->ite(node, this->actx->bvtrue(), this->actx->bvfalse());
141 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
142 return this->actx->sx(size - csze, node);
145 case llvm::Instruction::SRem: {
146 auto LHS = this->do_convert(instruction->getOperand(0));
147 auto RHS = this->do_convert(instruction->getOperand(1));
148 return this->actx->bvsrem(LHS, RHS);
151 case llvm::Instruction::Select: {
152 auto nif = this->do_convert(instruction->getOperand(0));
153 auto nthen = this->do_convert(instruction->getOperand(1));
154 auto nelse = this->do_convert(instruction->getOperand(2));
161 if (nif->isLogical() ==
false) {
162 nif = this->actx->equal(nif, this->actx->bvtrue());
165 return this->actx->ite(nif, nthen, nelse);
168 case llvm::Instruction::Shl: {
169 auto LHS = this->do_convert(instruction->getOperand(0));
170 auto RHS = this->do_convert(instruction->getOperand(1));
171 return this->actx->bvshl(LHS, RHS);
174 case llvm::Instruction::Sub: {
175 auto LHS = this->do_convert(instruction->getOperand(0));
176 auto RHS = this->do_convert(instruction->getOperand(1));
177 return this->actx->bvsub(LHS, RHS);
180 case llvm::Instruction::Trunc: {
181 auto size = instruction->getType()->getIntegerBitWidth();
182 auto node = this->do_convert(instruction->getOperand(0));
183 return this->actx->extract(size - 1, 0, node);
186 case llvm::Instruction::UDiv: {
187 auto LHS = this->do_convert(instruction->getOperand(0));
188 auto RHS = this->do_convert(instruction->getOperand(1));
189 return this->actx->bvudiv(LHS, RHS);
192 case llvm::Instruction::URem: {
193 auto LHS = this->do_convert(instruction->getOperand(0));
194 auto RHS = this->do_convert(instruction->getOperand(1));
195 return this->actx->bvurem(LHS, RHS);
198 case llvm::Instruction::Xor: {
199 auto LHS = this->do_convert(instruction->getOperand(0));
200 auto RHS = this->do_convert(instruction->getOperand(1));
202 if (LHS->isLogical() && RHS->isLogical()) {
203 return this->actx->ite(this->actx->lxor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
205 return this->actx->bvxor(LHS, RHS);
208 case llvm::Instruction::ZExt: {
210 auto size = instruction->getType()->getIntegerBitWidth();
211 auto node = this->do_convert(instruction->getOperand(0));
214 if (node->isLogical()) {
215 node = this->actx->ite(node, this->actx->bvtrue(), this->actx->bvfalse());
219 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
220 return this->actx->zx(size - csze, node);
223 case llvm::Instruction::Load: {
225 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
228 case llvm::Instruction::PHI: {
230 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
237 else if (constant !=
nullptr) {
238 return this->actx->bv(constant->getLimitedValue(), constant->getBitWidth());
240 else if (argument !=
nullptr) {
241 return this->var(argument->getName().data(), argument->getType()->getScalarSizeInBits());
250 auto it = this->symvars.find(name);
251 if (it != this->symvars.end())
256 if (this->ctx ==
nullptr)
257 node = this->actx->getVariableNode(name);
261 symvars[name] = node;
268 llvm::Function* function = llvmModule->getFunction(fname);
269 if (function ==
nullptr) {
274 llvm::BasicBlock& entryBlock = function->getEntryBlock();
277 llvm::Instruction* returnInstruction = entryBlock.getTerminator();
280 return this->do_convert(returnInstruction);
285 return this->do_convert(instruction);
This is the main Triton Context class.
TRITON_EXPORT triton::engines::symbolic::SharedSymbolicVariable newSymbolicVariable(triton::uint32 varSize, const std::string &alias="")
[symbolic api] - Returns a new symbolic variable.
TRITON_EXPORT triton::ast::SharedAbstractNode convert(llvm::Module *llvmModule, const char *fname="__triton")
Converts a given function from an LLVM module to a Triton AST.
TRITON_EXPORT LLVMToTriton(triton::Context &ctx)
Constructor.
The exception class used by all AST lifting (e.g z3 <-> triton).
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
std::uint32_t uint32
unisgned 32-bits