libTriton version 1.0 build 1588
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 /* We symbolize the return of call */
40 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
41 }
42
43 switch (instruction->getOpcode()) {
44
45 case llvm::Instruction::AShr: {
46 auto LHS = this->do_convert(instruction->getOperand(0));
47 auto RHS = this->do_convert(instruction->getOperand(1));
48 return this->actx->bvashr(LHS, RHS);
49 }
50
51 case llvm::Instruction::Add: {
52 auto LHS = this->do_convert(instruction->getOperand(0));
53 auto RHS = this->do_convert(instruction->getOperand(1));
54 return this->actx->bvadd(LHS, RHS);
55 }
56
57 case llvm::Instruction::And: {
58 auto LHS = this->do_convert(instruction->getOperand(0));
59 auto RHS = this->do_convert(instruction->getOperand(1));
60 /* LLVM does not distinct a logical AND of the bitwise AND */
61 if (LHS->isLogical() && RHS->isLogical()) {
62 return this->actx->ite(this->actx->land(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
63 }
64 return this->actx->bvand(LHS, RHS);
65 }
66
67 case llvm::Instruction::ICmp: {
69 auto LHS = this->do_convert(instruction->getOperand(0));
70 auto RHS = this->do_convert(instruction->getOperand(1));
71 if (icmp != nullptr) {
72 switch (icmp->getPredicate()) {
73 case llvm::ICmpInst::ICMP_EQ: return this->actx->equal(LHS, RHS);
74 case llvm::ICmpInst::ICMP_NE: return this->actx->distinct(LHS, RHS);
75 case llvm::ICmpInst::ICMP_UGE: return this->actx->bvuge(LHS, RHS);
76 case llvm::ICmpInst::ICMP_UGT: return this->actx->bvugt(LHS, RHS);
77 case llvm::ICmpInst::ICMP_ULE: return this->actx->bvule(LHS, RHS);
78 case llvm::ICmpInst::ICMP_ULT: return this->actx->bvult(LHS, RHS);
79 case llvm::ICmpInst::ICMP_SGE: return this->actx->bvsge(LHS, RHS);
80 case llvm::ICmpInst::ICMP_SGT: return this->actx->bvsgt(LHS, RHS);
81 case llvm::ICmpInst::ICMP_SLE: return this->actx->bvsle(LHS, RHS);
82 case llvm::ICmpInst::ICMP_SLT: return this->actx->bvslt(LHS, RHS);
83 default:
84 break;
85 }
86 return node;
87 }
88 throw triton::exceptions::AstLifting("LLVMToTriton::do_convert(): ICmpInst not supported");
89 }
90
91 case llvm::Instruction::LShr: {
92 auto LHS = this->do_convert(instruction->getOperand(0));
93 auto RHS = this->do_convert(instruction->getOperand(1));
94 return this->actx->bvlshr(LHS, RHS);
95 }
96
97 case llvm::Instruction::Mul: {
98 auto LHS = this->do_convert(instruction->getOperand(0));
99 auto RHS = this->do_convert(instruction->getOperand(1));
100 return this->actx->bvmul(LHS, RHS);
101 }
102
103 case llvm::Instruction::Or: {
104 auto LHS = this->do_convert(instruction->getOperand(0));
105 auto RHS = this->do_convert(instruction->getOperand(1));
106 /* LLVM does not distinct a logical OR of the bitwise OR */
107 if (LHS->isLogical() && RHS->isLogical()) {
108 return this->actx->ite(this->actx->lor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
109 }
110 return this->actx->bvor(LHS, RHS);
111 }
112
113 case llvm::Instruction::Ret:
114 return this->do_convert(instruction->getOperand(0));
115
116 case llvm::Instruction::SDiv: {
117 auto LHS = this->do_convert(instruction->getOperand(0));
118 auto RHS = this->do_convert(instruction->getOperand(1));
119 return this->actx->bvsdiv(LHS, RHS);
120 }
121
122 case llvm::Instruction::SExt: {
123 /* Final size */
124 auto size = instruction->getType()->getIntegerBitWidth();
125 auto node = this->do_convert(instruction->getOperand(0));
126 /* Size of the child */
127 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
128 return this->actx->sx(size - csze, node);
129 }
130
131 case llvm::Instruction::SRem: {
132 auto LHS = this->do_convert(instruction->getOperand(0));
133 auto RHS = this->do_convert(instruction->getOperand(1));
134 return this->actx->bvsrem(LHS, RHS);
135 }
136
137 case llvm::Instruction::Select: {
138 auto nif = this->do_convert(instruction->getOperand(0));
139 auto nthen = this->do_convert(instruction->getOperand(1));
140 auto nelse = this->do_convert(instruction->getOperand(2));
141
142 /*
143 * In some cases, LLVM simplifies the icmp by a constant
144 * which is lifted to a bvtrue on our side. In this case,
145 * we have to translate it to a logical node.
146 */
147 if (nif->isLogical() == false) {
148 nif = this->actx->equal(nif, this->actx->bvtrue());
149 }
150
151 return this->actx->ite(nif, nthen, nelse);
152 }
153
154 case llvm::Instruction::Shl: {
155 auto LHS = this->do_convert(instruction->getOperand(0));
156 auto RHS = this->do_convert(instruction->getOperand(1));
157 return this->actx->bvshl(LHS, RHS);
158 }
159
160 case llvm::Instruction::Sub: {
161 auto LHS = this->do_convert(instruction->getOperand(0));
162 auto RHS = this->do_convert(instruction->getOperand(1));
163 return this->actx->bvsub(LHS, RHS);
164 }
165
166 case llvm::Instruction::Trunc: {
167 auto size = instruction->getType()->getIntegerBitWidth();
168 auto node = this->do_convert(instruction->getOperand(0));
169 return this->actx->extract(size - 1, 0, node);
170 }
171
172 case llvm::Instruction::UDiv: {
173 auto LHS = this->do_convert(instruction->getOperand(0));
174 auto RHS = this->do_convert(instruction->getOperand(1));
175 return this->actx->bvudiv(LHS, RHS);
176 }
177
178 case llvm::Instruction::URem: {
179 auto LHS = this->do_convert(instruction->getOperand(0));
180 auto RHS = this->do_convert(instruction->getOperand(1));
181 return this->actx->bvurem(LHS, RHS);
182 }
183
184 case llvm::Instruction::Xor: {
185 auto LHS = this->do_convert(instruction->getOperand(0));
186 auto RHS = this->do_convert(instruction->getOperand(1));
187 /* LLVM does not distinct a logical XOR of the bitwise XOR */
188 if (LHS->isLogical() && RHS->isLogical()) {
189 return this->actx->ite(this->actx->lxor(LHS, RHS), this->actx->bvtrue(), this->actx->bvfalse());
190 }
191 return this->actx->bvxor(LHS, RHS);
192 }
193
194 case llvm::Instruction::ZExt: {
195 /* Final size */
196 auto size = instruction->getType()->getIntegerBitWidth();
197 auto node = this->do_convert(instruction->getOperand(0));
198 /* Size of the child */
199 auto csze = instruction->getOperand(0)->getType()->getIntegerBitWidth();
200 return this->actx->zx(size - csze, node);
201 }
202
203 case llvm::Instruction::Load: {
204 /* We symbolize LOAD memory access */
205 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
206 }
207
208 case llvm::Instruction::PHI: {
209 /* We symbolize PHI node */
210 return this->var(instruction->getName().str(), instruction->getType()->getScalarSizeInBits());
211 }
212
213 default:
214 throw triton::exceptions::AstLifting("LLVMToTriton::do_convert(): LLVM instruction not supported");
215 }
216 }
217 else if (constant != nullptr) {
218 return this->actx->bv(constant->getLimitedValue(), constant->getBitWidth());
219 }
220 else if (argument != nullptr) {
221 return this->var(argument->getName().data(), argument->getType()->getScalarSizeInBits());
222 }
223
224 throw triton::exceptions::AstLifting("LLVMToTriton::do_convert(): LLVM instruction not supported");
225 }
226
227
228 SharedAbstractNode LLVMToTriton::var(const std::string &name, triton::uint32 varSize) {
229 /* Return the symbolic variable if already exists */
230 auto it = this->symvars.find(name);
231 if (it != this->symvars.end())
232 return it->second;
233
234 /* Otherwise, create a new one */
236 if (this->ctx == nullptr)
237 node = this->actx->getVariableNode(name);
238 else
239 node = this->actx->variable(this->ctx->newSymbolicVariable(varSize, name));
240
241 symvars[name] = node;
242 return node;
243 }
244
245
246 SharedAbstractNode LLVMToTriton::convert(llvm::Module* llvmModule, const char* fname) {
247 /* Check if the given llvm::module contains the __triton function */
248 llvm::Function* function = llvmModule->getFunction(fname);
249 if (function == nullptr) {
250 throw triton::exceptions::AstLifting("LLVMToTriton::convert(): llvm::Module doesn't contain the given function name");
251 }
252
253 /* Get the entry block of the function */
254 llvm::BasicBlock& entryBlock = function->getEntryBlock();
255
256 /* Get the return of the function */
257 llvm::Instruction* returnInstruction = entryBlock.getTerminator();
258
259 /* Let's convert everything */
260 return this->do_convert(returnInstruction);
261 }
262
263
264 SharedAbstractNode LLVMToTriton::convert(llvm::Value* instruction) {
265 return this->do_convert(instruction);
266 }
267
268 }; /* ast namespace */
269}; /* 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:778
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).
Definition: exceptions.hpp:413
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
Definition: tritonTypes.hpp:39
The Triton namespace.