libTriton version 1.0 build 1590
Loading...
Searching...
No Matches
llvmToTriton.cpp
Go to the documentation of this file.
1
2/*
3** Copyright (C) - Triton
4**
5** This program is under the terms of the Apache License 2.0.
6*/
7
10
11
12namespace triton {
13 namespace ast {
14
16 : actx(ctx.getAstContext()), ctx(&ctx) {
17 }
18
19
21 : actx(actx), ctx(nullptr) {
22 }
23
24
25 triton::ast::SharedAbstractNode LLVMToTriton::do_convert(llvm::Value* value) {
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);
31
32 if (instruction != nullptr) {
33
34 /* Check if the instruction is a call */
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)));
38 }
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());
42 for (triton::uint32 i = 0; i < oprnd->getBitvectorSize(); ++i) {
43 node = this->actx->bvadd(node, this->actx->zx(oprnd->getBitvectorSize() - 1, this->actx->extract(i, i, oprnd)));
44 }
45 return node;
46 }
47 /* We symbolize the return of call */
48 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
49 }
50
51 switch (instruction->getOpcode()) {
52
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);
57 }
58
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);
63 }
64
65 case llvm::Instruction::And: {
66 auto LHS = this->do_convert(instruction->getOperand(0));
67 auto RHS = this->do_convert(instruction->getOperand(1));
68 /* LLVM does not distinct a logical AND of the bitwise AND */
69 if (LHS->isLogical() && RHS->isLogical()) {
70 return this->actx->ite(this->actx->land(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
71 }
72 return this->actx->bvand(LHS, RHS);
73 }
74
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);
91 default:
92 break;
93 }
94 return node;
95 }
96 throw triton::exceptions::AstLifting("LLVMToTriton::do_convert(): ICmpInst not supported");
97 }
98
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);
103 }
104
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);
109 }
110
111 case llvm::Instruction::Or: {
112 auto LHS = this->do_convert(instruction->getOperand(0));
113 auto RHS = this->do_convert(instruction->getOperand(1));
114 /* LLVM does not distinct a logical OR of the bitwise OR */
115 if (LHS->isLogical() && RHS->isLogical()) {
116 return this->actx->ite(this->actx->lor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
117 }
118 return this->actx->bvor(LHS, RHS);
119 }
120
121 case llvm::Instruction::Ret:
122 return this->do_convert(instruction->getOperand(0));
123
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);
128 }
129
130 case llvm::Instruction::SExt: {
131 /* Final size */
132 auto size = instruction->getType()->getIntegerBitWidth();
133 auto node = this->do_convert(instruction->getOperand(0));
134
135 /* Handle the case where node is logical */
136 if (node->isLogical()) {
137 node = this->actx->ite(node, this->actx->bvtrue(), this->actx->bvfalse());
138 }
139
140 /* Size of the child */
141 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
142 return this->actx->sx(size - csze, node);
143 }
144
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);
149 }
150
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));
155
156 /*
157 * In some cases, LLVM simplifies the icmp by a constant
158 * which is lifted to a bvtrue on our side. In this case,
159 * we have to translate it to a logical node.
160 */
161 if (nif->isLogical() == false) {
162 nif = this->actx->equal(nif, this->actx->bvtrue());
163 }
164
165 return this->actx->ite(nif, nthen, nelse);
166 }
167
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);
172 }
173
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);
178 }
179
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);
184 }
185
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);
190 }
191
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);
196 }
197
198 case llvm::Instruction::Xor: {
199 auto LHS = this->do_convert(instruction->getOperand(0));
200 auto RHS = this->do_convert(instruction->getOperand(1));
201 /* LLVM does not distinct a logical XOR of the bitwise XOR */
202 if (LHS->isLogical() && RHS->isLogical()) {
203 return this->actx->ite(this->actx->lxor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
204 }
205 return this->actx->bvxor(LHS, RHS);
206 }
207
208 case llvm::Instruction::ZExt: {
209 /* Final size */
210 auto size = instruction->getType()->getIntegerBitWidth();
211 auto node = this->do_convert(instruction->getOperand(0));
212
213 /* Handle the case where node is logical */
214 if (node->isLogical()) {
215 node = this->actx->ite(node, this->actx->bvtrue(), this->actx->bvfalse());
216 }
217
218 /* Size of the child */
219 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
220 return this->actx->zx(size - csze, node);
221 }
222
223 case llvm::Instruction::Load: {
224 /* We symbolize LOAD memory access */
225 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
226 }
227
228 case llvm::Instruction::PHI: {
229 /* We symbolize PHI node */
230 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
231 }
232
233 default:
234 throw triton::exceptions::AstLifting("LLVMToTriton::do_convert(): LLVM instruction not supported");
235 }
236 }
237 else if (constant != nullptr) {
238 return this->actx->bv(constant->getLimitedValue(), constant->getBitWidth());
239 }
240 else if (argument != nullptr) {
241 return this->var(argument->getName().data(), argument->getType()->getScalarSizeInBits());
242 }
243
244 throw triton::exceptions::AstLifting("LLVMToTriton::do_convert(): LLVM instruction not supported");
245 }
246
247
248 SharedAbstractNode LLVMToTriton::var(const std::string &name, triton::uint32 varSize) {
249 /* Return the symbolic variable if already exists */
250 auto it = this->symvars.find(name);
251 if (it != this->symvars.end())
252 return it->second;
253
254 /* Otherwise, create a new one */
256 if (this->ctx == nullptr)
257 node = this->actx->getVariableNode(name);
258 else
259 node = this->actx->variable(this->ctx->newSymbolicVariable(varSize, name));
260
261 symvars[name] = node;
262 return node;
263 }
264
265
266 SharedAbstractNode LLVMToTriton::convert(llvm::Module* llvmModule, const char* fname) {
267 /* Check if the given llvm::module contains the __triton function */
268 llvm::Function* function = llvmModule->getFunction(fname);
269 if (function == nullptr) {
270 throw triton::exceptions::AstLifting("LLVMToTriton::convert(): llvm::Module doesn't contain the given function name");
271 }
272
273 /* Get the entry block of the function */
274 llvm::BasicBlock& entryBlock = function->getEntryBlock();
275
276 /* Get the return of the function */
277 llvm::Instruction* returnInstruction = entryBlock.getTerminator();
278
279 /* Let's convert everything */
280 return this->do_convert(returnInstruction);
281 }
282
283
284 SharedAbstractNode LLVMToTriton::convert(llvm::Value* instruction) {
285 return this->do_convert(instruction);
286 }
287
288 }; /* ast namespace */
289}; /* triton namespace */
This is the main Triton Context class.
Definition context.hpp:45
TRITON_EXPORT triton::engines::symbolic::SharedSymbolicVariable newSymbolicVariable(triton::uint32 varSize, const std::string &alias="")
[symbolic api] - Returns a new symbolic variable.
Definition context.cpp:783
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.
Definition ast.hpp:59
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
Definition ast.hpp:65
std::uint32_t uint32
unisgned 32-bits
The Triton namespace.