180814287SRaphael Isemann //===-- IRInterpreter.cpp -------------------------------------------------===//
23bfdaa2aSSean Callanan //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63bfdaa2aSSean Callanan //
73bfdaa2aSSean Callanan //===----------------------------------------------------------------------===//
83bfdaa2aSSean Callanan 
9579e70c9SSean Callanan #include "lldb/Expression/IRInterpreter.h"
1090ff7911SEwan Crawford #include "lldb/Core/Module.h"
11579e70c9SSean Callanan #include "lldb/Core/ModuleSpec.h"
1290ff7911SEwan Crawford #include "lldb/Core/ValueObject.h"
13579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h"
147071c5fdSTed Woodward #include "lldb/Expression/IRExecutionUnit.h"
15fefe43cdSSean Callanan #include "lldb/Expression/IRMemoryMap.h"
16bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h"
17666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
1801c3243fSZachary Turner #include "lldb/Utility/Endian.h"
196f9e6901SZachary Turner #include "lldb/Utility/Log.h"
20d821c997SPavel Labath #include "lldb/Utility/Scalar.h"
2197206d57SZachary Turner #include "lldb/Utility/Status.h"
22bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
233bfdaa2aSSean Callanan 
2490ff7911SEwan Crawford #include "lldb/Target/ABI.h"
2590ff7911SEwan Crawford #include "lldb/Target/ExecutionContext.h"
2690ff7911SEwan Crawford #include "lldb/Target/Target.h"
2790ff7911SEwan Crawford #include "lldb/Target/Thread.h"
2890ff7911SEwan Crawford #include "lldb/Target/ThreadPlan.h"
2990ff7911SEwan Crawford #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
3090ff7911SEwan Crawford 
311e157587SChandler Carruth #include "llvm/IR/Constants.h"
32fefe43cdSSean Callanan #include "llvm/IR/DataLayout.h"
331e157587SChandler Carruth #include "llvm/IR/Function.h"
341e157587SChandler Carruth #include "llvm/IR/Instructions.h"
35576a4374SSean Callanan #include "llvm/IR/Intrinsics.h"
3690ff7911SEwan Crawford #include "llvm/IR/LLVMContext.h"
371e157587SChandler Carruth #include "llvm/IR/Module.h"
38d05b8992SEduard Burtescu #include "llvm/IR/Operator.h"
393bfdaa2aSSean Callanan #include "llvm/Support/raw_ostream.h"
403bfdaa2aSSean Callanan 
413bfdaa2aSSean Callanan #include <map>
423bfdaa2aSSean Callanan 
433bfdaa2aSSean Callanan using namespace llvm;
443bfdaa2aSSean Callanan 
45b9c1b51eSKate Stone static std::string PrintValue(const Value *value, bool truncate = false) {
463bfdaa2aSSean Callanan   std::string s;
473bfdaa2aSSean Callanan   raw_string_ostream rso(s);
483bfdaa2aSSean Callanan   value->print(rso);
493bfdaa2aSSean Callanan   rso.flush();
503bfdaa2aSSean Callanan   if (truncate)
513bfdaa2aSSean Callanan     s.resize(s.length() - 1);
523bfdaa2aSSean Callanan 
533bfdaa2aSSean Callanan   size_t offset;
543bfdaa2aSSean Callanan   while ((offset = s.find('\n')) != s.npos)
553bfdaa2aSSean Callanan     s.erase(offset, 1);
563bfdaa2aSSean Callanan   while (s[0] == ' ' || s[0] == '\t')
573bfdaa2aSSean Callanan     s.erase(0, 1);
583bfdaa2aSSean Callanan 
593bfdaa2aSSean Callanan   return s;
603bfdaa2aSSean Callanan }
613bfdaa2aSSean Callanan 
62b9c1b51eSKate Stone static std::string PrintType(const Type *type, bool truncate = false) {
633bfdaa2aSSean Callanan   std::string s;
643bfdaa2aSSean Callanan   raw_string_ostream rso(s);
653bfdaa2aSSean Callanan   type->print(rso);
663bfdaa2aSSean Callanan   rso.flush();
673bfdaa2aSSean Callanan   if (truncate)
683bfdaa2aSSean Callanan     s.resize(s.length() - 1);
693bfdaa2aSSean Callanan   return s;
703bfdaa2aSSean Callanan }
713bfdaa2aSSean Callanan 
72b9c1b51eSKate Stone static bool CanIgnoreCall(const CallInst *call) {
73576a4374SSean Callanan   const llvm::Function *called_function = call->getCalledFunction();
74576a4374SSean Callanan 
75576a4374SSean Callanan   if (!called_function)
76576a4374SSean Callanan     return false;
77576a4374SSean Callanan 
78b9c1b51eSKate Stone   if (called_function->isIntrinsic()) {
79b9c1b51eSKate Stone     switch (called_function->getIntrinsicID()) {
80576a4374SSean Callanan     default:
81576a4374SSean Callanan       break;
82576a4374SSean Callanan     case llvm::Intrinsic::dbg_declare:
83576a4374SSean Callanan     case llvm::Intrinsic::dbg_value:
84576a4374SSean Callanan       return true;
85576a4374SSean Callanan     }
86576a4374SSean Callanan   }
87576a4374SSean Callanan 
88576a4374SSean Callanan   return false;
89576a4374SSean Callanan }
90576a4374SSean Callanan 
91b9c1b51eSKate Stone class InterpreterStackFrame {
923bfdaa2aSSean Callanan public:
9308052afaSSean Callanan   typedef std::map<const Value *, lldb::addr_t> ValueMap;
9408052afaSSean Callanan 
953bfdaa2aSSean Callanan   ValueMap m_values;
968468dbecSMicah Villmow   DataLayout &m_target_data;
977071c5fdSTed Woodward   lldb_private::IRExecutionUnit &m_execution_unit;
983bfdaa2aSSean Callanan   const BasicBlock *m_bb;
993fe71581SMarianne Mailhot-Sarrasin   const BasicBlock *m_prev_bb;
1003bfdaa2aSSean Callanan   BasicBlock::const_iterator m_ii;
1013bfdaa2aSSean Callanan   BasicBlock::const_iterator m_ie;
1023bfdaa2aSSean Callanan 
1031582ee68SSean Callanan   lldb::addr_t m_frame_process_address;
1041582ee68SSean Callanan   size_t m_frame_size;
1051582ee68SSean Callanan   lldb::addr_t m_stack_pointer;
1061582ee68SSean Callanan 
1073bfdaa2aSSean Callanan   lldb::ByteOrder m_byte_order;
1083bfdaa2aSSean Callanan   size_t m_addr_byte_size;
1093bfdaa2aSSean Callanan 
1108468dbecSMicah Villmow   InterpreterStackFrame(DataLayout &target_data,
1117071c5fdSTed Woodward                         lldb_private::IRExecutionUnit &execution_unit,
112df56540aSSean Callanan                         lldb::addr_t stack_frame_bottom,
113b9c1b51eSKate Stone                         lldb::addr_t stack_frame_top)
114b9c1b51eSKate Stone       : m_target_data(target_data), m_execution_unit(execution_unit),
115b9c1b51eSKate Stone         m_bb(nullptr), m_prev_bb(nullptr) {
116b9c1b51eSKate Stone     m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle
117b9c1b51eSKate Stone                                                  : lldb::eByteOrderBig);
11895769bf4SSean Callanan     m_addr_byte_size = (target_data.getPointerSize(0));
1191582ee68SSean Callanan 
120df56540aSSean Callanan     m_frame_process_address = stack_frame_bottom;
121df56540aSSean Callanan     m_frame_size = stack_frame_top - stack_frame_bottom;
122df56540aSSean Callanan     m_stack_pointer = stack_frame_top;
1231582ee68SSean Callanan   }
1241582ee68SSean Callanan 
125b9c1b51eSKate Stone   ~InterpreterStackFrame() {}
1263bfdaa2aSSean Callanan 
127b9c1b51eSKate Stone   void Jump(const BasicBlock *bb) {
1283fe71581SMarianne Mailhot-Sarrasin     m_prev_bb = m_bb;
1293bfdaa2aSSean Callanan     m_bb = bb;
1303bfdaa2aSSean Callanan     m_ii = m_bb->begin();
1313bfdaa2aSSean Callanan     m_ie = m_bb->end();
1323bfdaa2aSSean Callanan   }
1333bfdaa2aSSean Callanan 
134b9c1b51eSKate Stone   std::string SummarizeValue(const Value *value) {
1353bfdaa2aSSean Callanan     lldb_private::StreamString ss;
1363bfdaa2aSSean Callanan 
1373bfdaa2aSSean Callanan     ss.Printf("%s", PrintValue(value).c_str());
1383bfdaa2aSSean Callanan 
1393bfdaa2aSSean Callanan     ValueMap::iterator i = m_values.find(value);
1403bfdaa2aSSean Callanan 
141b9c1b51eSKate Stone     if (i != m_values.end()) {
14208052afaSSean Callanan       lldb::addr_t addr = i->second;
1433bfdaa2aSSean Callanan 
14408052afaSSean Callanan       ss.Printf(" 0x%llx", (unsigned long long)addr);
1453bfdaa2aSSean Callanan     }
1463bfdaa2aSSean Callanan 
147adcd0268SBenjamin Kramer     return std::string(ss.GetString());
1483bfdaa2aSSean Callanan   }
1493bfdaa2aSSean Callanan 
150*b725142cSPavel Labath   bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value,
151b9c1b51eSKate Stone                          Type *type) {
1523bfdaa2aSSean Callanan     size_t type_size = m_target_data.getTypeStoreSize(type);
1533bfdaa2aSSean Callanan 
154ae6ca2fcSFrederic Riss     if (type_size > 8)
1553bfdaa2aSSean Callanan       return false;
1563bfdaa2aSSean Callanan 
157ae6ca2fcSFrederic Riss     if (type_size != 1)
158ae6ca2fcSFrederic Riss       type_size = PowerOf2Ceil(type_size);
159ae6ca2fcSFrederic Riss 
160*b725142cSPavel Labath     scalar = value.zextOrTrunc(type_size * 8);
1613bfdaa2aSSean Callanan     return true;
1623bfdaa2aSSean Callanan   }
1633bfdaa2aSSean Callanan 
164b9c1b51eSKate Stone   bool EvaluateValue(lldb_private::Scalar &scalar, const Value *value,
165b9c1b51eSKate Stone                      Module &module) {
1663bfdaa2aSSean Callanan     const Constant *constant = dyn_cast<Constant>(value);
1673bfdaa2aSSean Callanan 
168b9c1b51eSKate Stone     if (constant) {
169415422ceSSean Callanan       APInt value_apint;
170415422ceSSean Callanan 
171415422ceSSean Callanan       if (!ResolveConstantValue(value_apint, constant))
172415422ceSSean Callanan         return false;
173415422ceSSean Callanan 
174*b725142cSPavel Labath       return AssignToMatchType(scalar, value_apint, value->getType());
175c3f0d9f3SDavide Italiano     }
176c3f0d9f3SDavide Italiano 
17708052afaSSean Callanan     lldb::addr_t process_address = ResolveValue(value, module);
1783bfdaa2aSSean Callanan     size_t value_size = m_target_data.getTypeStoreSize(value->getType());
1793bfdaa2aSSean Callanan 
18008052afaSSean Callanan     lldb_private::DataExtractor value_extractor;
18197206d57SZachary Turner     lldb_private::Status extract_error;
18208052afaSSean Callanan 
183b9c1b51eSKate Stone     m_execution_unit.GetMemoryData(value_extractor, process_address,
184b9c1b51eSKate Stone                                    value_size, extract_error);
18508052afaSSean Callanan 
18608052afaSSean Callanan     if (!extract_error.Success())
18708052afaSSean Callanan       return false;
18808052afaSSean Callanan 
189c7bece56SGreg Clayton     lldb::offset_t offset = 0;
190ae6ca2fcSFrederic Riss     if (value_size <= 8) {
19108052afaSSean Callanan       uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
192*b725142cSPavel Labath       return AssignToMatchType(scalar, llvm::APInt(64, u64value),
193*b725142cSPavel Labath                                value->getType());
1943bfdaa2aSSean Callanan     }
1953bfdaa2aSSean Callanan 
1963bfdaa2aSSean Callanan     return false;
1973bfdaa2aSSean Callanan   }
1983bfdaa2aSSean Callanan 
199*b725142cSPavel Labath   bool AssignValue(const Value *value, lldb_private::Scalar scalar,
200b9c1b51eSKate Stone                    Module &module) {
20108052afaSSean Callanan     lldb::addr_t process_address = ResolveValue(value, module);
20208052afaSSean Callanan 
20308052afaSSean Callanan     if (process_address == LLDB_INVALID_ADDRESS)
20408052afaSSean Callanan       return false;
2053bfdaa2aSSean Callanan 
2063bfdaa2aSSean Callanan     lldb_private::Scalar cast_scalar;
2073bfdaa2aSSean Callanan 
208*b725142cSPavel Labath     scalar.MakeUnsigned();
209*b725142cSPavel Labath     if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
210*b725142cSPavel Labath                            value->getType()))
2113bfdaa2aSSean Callanan       return false;
2123bfdaa2aSSean Callanan 
21308052afaSSean Callanan     size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
2143bfdaa2aSSean Callanan 
21508052afaSSean Callanan     lldb_private::DataBufferHeap buf(value_byte_size, 0);
2163bfdaa2aSSean Callanan 
21797206d57SZachary Turner     lldb_private::Status get_data_error;
21808052afaSSean Callanan 
219b9c1b51eSKate Stone     if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),
220b9c1b51eSKate Stone                                      m_byte_order, get_data_error))
2213bfdaa2aSSean Callanan       return false;
2223bfdaa2aSSean Callanan 
22397206d57SZachary Turner     lldb_private::Status write_error;
2243bfdaa2aSSean Callanan 
225b9c1b51eSKate Stone     m_execution_unit.WriteMemory(process_address, buf.GetBytes(),
226b9c1b51eSKate Stone                                  buf.GetByteSize(), write_error);
2275c9737a5SGreg Clayton 
22808052afaSSean Callanan     return write_error.Success();
2293bfdaa2aSSean Callanan   }
2303bfdaa2aSSean Callanan 
231b9c1b51eSKate Stone   bool ResolveConstantValue(APInt &value, const Constant *constant) {
232b9c1b51eSKate Stone     switch (constant->getValueID()) {
2331582ee68SSean Callanan     default:
2341582ee68SSean Callanan       break;
2357071c5fdSTed Woodward     case Value::FunctionVal:
236b9c1b51eSKate Stone       if (const Function *constant_func = dyn_cast<Function>(constant)) {
2377071c5fdSTed Woodward         lldb_private::ConstString name(constant_func->getName());
238f2128b28SJim Ingham         bool missing_weak = false;
239f2128b28SJim Ingham         lldb::addr_t addr = m_execution_unit.FindSymbol(name, missing_weak);
240f2128b28SJim Ingham         if (addr == LLDB_INVALID_ADDRESS || missing_weak)
2417071c5fdSTed Woodward           return false;
2427071c5fdSTed Woodward         value = APInt(m_target_data.getPointerSizeInBits(), addr);
2437071c5fdSTed Woodward         return true;
2447071c5fdSTed Woodward       }
2457071c5fdSTed Woodward       break;
2461582ee68SSean Callanan     case Value::ConstantIntVal:
247b9c1b51eSKate Stone       if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) {
24894a9a39eSSean Callanan         value = constant_int->getValue();
24994a9a39eSSean Callanan         return true;
2503bfdaa2aSSean Callanan       }
2511582ee68SSean Callanan       break;
2521582ee68SSean Callanan     case Value::ConstantFPVal:
253b9c1b51eSKate Stone       if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) {
25494a9a39eSSean Callanan         value = constant_fp->getValueAPF().bitcastToAPInt();
25594a9a39eSSean Callanan         return true;
2563bfdaa2aSSean Callanan       }
2571582ee68SSean Callanan       break;
2581582ee68SSean Callanan     case Value::ConstantExprVal:
259b9c1b51eSKate Stone       if (const ConstantExpr *constant_expr =
260b9c1b51eSKate Stone               dyn_cast<ConstantExpr>(constant)) {
261b9c1b51eSKate Stone         switch (constant_expr->getOpcode()) {
26280c48c10SSean Callanan         default:
26380c48c10SSean Callanan           return false;
26480c48c10SSean Callanan         case Instruction::IntToPtr:
2652abffe05SSean Callanan         case Instruction::PtrToInt:
26680c48c10SSean Callanan         case Instruction::BitCast:
26794a9a39eSSean Callanan           return ResolveConstantValue(value, constant_expr->getOperand(0));
268b9c1b51eSKate Stone         case Instruction::GetElementPtr: {
26994a9a39eSSean Callanan           ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
27094a9a39eSSean Callanan           ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
27194a9a39eSSean Callanan 
27294a9a39eSSean Callanan           Constant *base = dyn_cast<Constant>(*op_cursor);
27394a9a39eSSean Callanan 
27494a9a39eSSean Callanan           if (!base)
27594a9a39eSSean Callanan             return false;
27694a9a39eSSean Callanan 
27794a9a39eSSean Callanan           if (!ResolveConstantValue(value, base))
27894a9a39eSSean Callanan             return false;
27994a9a39eSSean Callanan 
28094a9a39eSSean Callanan           op_cursor++;
28194a9a39eSSean Callanan 
28294a9a39eSSean Callanan           if (op_cursor == op_end)
28394a9a39eSSean Callanan             return true; // no offset to apply!
28494a9a39eSSean Callanan 
28594a9a39eSSean Callanan           SmallVector<Value *, 8> indices(op_cursor, op_end);
28694a9a39eSSean Callanan 
287b9c1b51eSKate Stone           Type *src_elem_ty =
288b9c1b51eSKate Stone               cast<GEPOperator>(constant_expr)->getSourceElementType();
289b9c1b51eSKate Stone           uint64_t offset =
290b9c1b51eSKate Stone               m_target_data.getIndexedOffsetInType(src_elem_ty, indices);
29194a9a39eSSean Callanan 
29294a9a39eSSean Callanan           const bool is_signed = true;
29394a9a39eSSean Callanan           value += APInt(value.getBitWidth(), offset, is_signed);
29494a9a39eSSean Callanan 
29594a9a39eSSean Callanan           return true;
29694a9a39eSSean Callanan         }
29780c48c10SSean Callanan         }
29880c48c10SSean Callanan       }
2991582ee68SSean Callanan       break;
3001582ee68SSean Callanan     case Value::ConstantPointerNullVal:
301b9c1b51eSKate Stone       if (isa<ConstantPointerNull>(constant)) {
3021582ee68SSean Callanan         value = APInt(m_target_data.getPointerSizeInBits(), 0);
3031582ee68SSean Callanan         return true;
3041582ee68SSean Callanan       }
3051582ee68SSean Callanan       break;
3061582ee68SSean Callanan     }
3073bfdaa2aSSean Callanan     return false;
3083bfdaa2aSSean Callanan   }
3093bfdaa2aSSean Callanan 
310b9c1b51eSKate Stone   bool MakeArgument(const Argument *value, uint64_t address) {
3111582ee68SSean Callanan     lldb::addr_t data_address = Malloc(value->getType());
3121582ee68SSean Callanan 
3131582ee68SSean Callanan     if (data_address == LLDB_INVALID_ADDRESS)
3141582ee68SSean Callanan       return false;
3151582ee68SSean Callanan 
31697206d57SZachary Turner     lldb_private::Status write_error;
3171582ee68SSean Callanan 
3187071c5fdSTed Woodward     m_execution_unit.WritePointerToMemory(data_address, address, write_error);
3191582ee68SSean Callanan 
320b9c1b51eSKate Stone     if (!write_error.Success()) {
32197206d57SZachary Turner       lldb_private::Status free_error;
3227071c5fdSTed Woodward       m_execution_unit.Free(data_address, free_error);
3231582ee68SSean Callanan       return false;
3241582ee68SSean Callanan     }
3251582ee68SSean Callanan 
3261582ee68SSean Callanan     m_values[value] = data_address;
3271582ee68SSean Callanan 
328b9c1b51eSKate Stone     lldb_private::Log *log(
329b9c1b51eSKate Stone         lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
3301582ee68SSean Callanan 
331b9c1b51eSKate Stone     if (log) {
33263e5fb76SJonas Devlieghere       LLDB_LOGF(log, "Made an allocation for argument %s",
333b9c1b51eSKate Stone                 PrintValue(value).c_str());
33463e5fb76SJonas Devlieghere       LLDB_LOGF(log, "  Data region    : %llx", (unsigned long long)address);
33563e5fb76SJonas Devlieghere       LLDB_LOGF(log, "  Ref region     : %llx",
33663e5fb76SJonas Devlieghere                 (unsigned long long)data_address);
3371582ee68SSean Callanan     }
3381582ee68SSean Callanan 
3391582ee68SSean Callanan     return true;
3401582ee68SSean Callanan   }
3411582ee68SSean Callanan 
342b9c1b51eSKate Stone   bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) {
34394a9a39eSSean Callanan     APInt resolved_value;
34494a9a39eSSean Callanan 
34594a9a39eSSean Callanan     if (!ResolveConstantValue(resolved_value, constant))
34694a9a39eSSean Callanan       return false;
34794a9a39eSSean Callanan 
34894a9a39eSSean Callanan     size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
3499521ad2aSUlrich Weigand     lldb_private::DataBufferHeap buf(constant_size, 0);
35008052afaSSean Callanan 
35197206d57SZachary Turner     lldb_private::Status get_data_error;
35246fc0066SSean Callanan 
353b9c1b51eSKate Stone     lldb_private::Scalar resolved_scalar(
354b9c1b51eSKate Stone         resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8));
355b9c1b51eSKate Stone     if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),
356b9c1b51eSKate Stone                                          m_byte_order, get_data_error))
3579521ad2aSUlrich Weigand       return false;
35846fc0066SSean Callanan 
35997206d57SZachary Turner     lldb_private::Status write_error;
36008052afaSSean Callanan 
361b9c1b51eSKate Stone     m_execution_unit.WriteMemory(process_address, buf.GetBytes(),
362b9c1b51eSKate Stone                                  buf.GetByteSize(), write_error);
36308052afaSSean Callanan 
36408052afaSSean Callanan     return write_error.Success();
36594a9a39eSSean Callanan   }
36694a9a39eSSean Callanan 
367b9c1b51eSKate Stone   lldb::addr_t Malloc(size_t size, uint8_t byte_alignment) {
3681582ee68SSean Callanan     lldb::addr_t ret = m_stack_pointer;
36908052afaSSean Callanan 
3701582ee68SSean Callanan     ret -= size;
3711582ee68SSean Callanan     ret -= (ret % byte_alignment);
37208052afaSSean Callanan 
3731582ee68SSean Callanan     if (ret < m_frame_process_address)
37408052afaSSean Callanan       return LLDB_INVALID_ADDRESS;
3751582ee68SSean Callanan 
3761582ee68SSean Callanan     m_stack_pointer = ret;
3771582ee68SSean Callanan     return ret;
37808052afaSSean Callanan   }
37908052afaSSean Callanan 
380b9c1b51eSKate Stone   lldb::addr_t Malloc(llvm::Type *type) {
38197206d57SZachary Turner     lldb_private::Status alloc_error;
38208052afaSSean Callanan 
383b9c1b51eSKate Stone     return Malloc(m_target_data.getTypeAllocSize(type),
384b9c1b51eSKate Stone                   m_target_data.getPrefTypeAlignment(type));
38508052afaSSean Callanan   }
38608052afaSSean Callanan 
387b9c1b51eSKate Stone   std::string PrintData(lldb::addr_t addr, llvm::Type *type) {
38808052afaSSean Callanan     size_t length = m_target_data.getTypeStoreSize(type);
38908052afaSSean Callanan 
39008052afaSSean Callanan     lldb_private::DataBufferHeap buf(length, 0);
39108052afaSSean Callanan 
39297206d57SZachary Turner     lldb_private::Status read_error;
39308052afaSSean Callanan 
3947071c5fdSTed Woodward     m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error);
39508052afaSSean Callanan 
39608052afaSSean Callanan     if (!read_error.Success())
39708052afaSSean Callanan       return std::string("<couldn't read data>");
39808052afaSSean Callanan 
39908052afaSSean Callanan     lldb_private::StreamString ss;
40008052afaSSean Callanan 
401b9c1b51eSKate Stone     for (size_t i = 0; i < length; i++) {
40208052afaSSean Callanan       if ((!(i & 0xf)) && i)
40308052afaSSean Callanan         ss.Printf("%02hhx - ", buf.GetBytes()[i]);
40408052afaSSean Callanan       else
40508052afaSSean Callanan         ss.Printf("%02hhx ", buf.GetBytes()[i]);
40608052afaSSean Callanan     }
40708052afaSSean Callanan 
408adcd0268SBenjamin Kramer     return std::string(ss.GetString());
40908052afaSSean Callanan   }
41008052afaSSean Callanan 
411b9c1b51eSKate Stone   lldb::addr_t ResolveValue(const Value *value, Module &module) {
4123bfdaa2aSSean Callanan     ValueMap::iterator i = m_values.find(value);
4133bfdaa2aSSean Callanan 
4143bfdaa2aSSean Callanan     if (i != m_values.end())
4153bfdaa2aSSean Callanan       return i->second;
4163bfdaa2aSSean Callanan 
4171582ee68SSean Callanan     // Fall back and allocate space [allocation type Alloca]
4181582ee68SSean Callanan 
4191582ee68SSean Callanan     lldb::addr_t data_address = Malloc(value->getType());
4201582ee68SSean Callanan 
421b9c1b51eSKate Stone     if (const Constant *constant = dyn_cast<Constant>(value)) {
422b9c1b51eSKate Stone       if (!ResolveConstant(data_address, constant)) {
42397206d57SZachary Turner         lldb_private::Status free_error;
4247071c5fdSTed Woodward         m_execution_unit.Free(data_address, free_error);
4251582ee68SSean Callanan         return LLDB_INVALID_ADDRESS;
4261582ee68SSean Callanan       }
4271582ee68SSean Callanan     }
4281582ee68SSean Callanan 
4291582ee68SSean Callanan     m_values[value] = data_address;
4301582ee68SSean Callanan     return data_address;
4313bfdaa2aSSean Callanan   }
4323bfdaa2aSSean Callanan };
4333bfdaa2aSSean Callanan 
434b9c1b51eSKate Stone static const char *unsupported_opcode_error =
435b9c1b51eSKate Stone     "Interpreter doesn't handle one of the expression's opcodes";
436b9c1b51eSKate Stone static const char *unsupported_operand_error =
437b9c1b51eSKate Stone     "Interpreter doesn't handle one of the expression's operands";
438b9c1b51eSKate Stone static const char *interpreter_internal_error =
439b9c1b51eSKate Stone     "Interpreter encountered an internal error";
440b9c1b51eSKate Stone static const char *bad_value_error =
441b9c1b51eSKate Stone     "Interpreter couldn't resolve a value during execution";
442b9c1b51eSKate Stone static const char *memory_allocation_error =
443b9c1b51eSKate Stone     "Interpreter couldn't allocate memory";
444175a0d04SSean Callanan static const char *memory_write_error = "Interpreter couldn't write to memory";
445175a0d04SSean Callanan static const char *memory_read_error = "Interpreter couldn't read from memory";
446175a0d04SSean Callanan static const char *infinite_loop_error = "Interpreter ran for too many cycles";
447b9c1b51eSKate Stone static const char *too_many_functions_error =
448b9c1b51eSKate Stone     "Interpreter doesn't handle modules with multiple function bodies.";
449175a0d04SSean Callanan 
450b9c1b51eSKate Stone static bool CanResolveConstant(llvm::Constant *constant) {
451b9c1b51eSKate Stone   switch (constant->getValueID()) {
4528c62daf2SSean Callanan   default:
4538c62daf2SSean Callanan     return false;
4548c62daf2SSean Callanan   case Value::ConstantIntVal:
4558c62daf2SSean Callanan   case Value::ConstantFPVal:
4567071c5fdSTed Woodward   case Value::FunctionVal:
4578c62daf2SSean Callanan     return true;
4588c62daf2SSean Callanan   case Value::ConstantExprVal:
459b9c1b51eSKate Stone     if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
460b9c1b51eSKate Stone       switch (constant_expr->getOpcode()) {
4618c62daf2SSean Callanan       default:
4628c62daf2SSean Callanan         return false;
4638c62daf2SSean Callanan       case Instruction::IntToPtr:
4648c62daf2SSean Callanan       case Instruction::PtrToInt:
4658c62daf2SSean Callanan       case Instruction::BitCast:
4668c62daf2SSean Callanan         return CanResolveConstant(constant_expr->getOperand(0));
467b9c1b51eSKate Stone       case Instruction::GetElementPtr: {
4688c62daf2SSean Callanan         ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
4698c62daf2SSean Callanan         Constant *base = dyn_cast<Constant>(*op_cursor);
4708c62daf2SSean Callanan         if (!base)
4718c62daf2SSean Callanan           return false;
4728c62daf2SSean Callanan 
4738c62daf2SSean Callanan         return CanResolveConstant(base);
4748c62daf2SSean Callanan       }
4758c62daf2SSean Callanan       }
4768c62daf2SSean Callanan     } else {
4778c62daf2SSean Callanan       return false;
4788c62daf2SSean Callanan     }
4798c62daf2SSean Callanan   case Value::ConstantPointerNullVal:
4808c62daf2SSean Callanan     return true;
4818c62daf2SSean Callanan   }
4828c62daf2SSean Callanan }
4838c62daf2SSean Callanan 
484b9c1b51eSKate Stone bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
48597206d57SZachary Turner                                  lldb_private::Status &error,
486b9c1b51eSKate Stone                                  const bool support_function_calls) {
487b9c1b51eSKate Stone   lldb_private::Log *log(
488b9c1b51eSKate Stone       lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
4893bfdaa2aSSean Callanan 
49085fc8761SSean Callanan   bool saw_function_with_body = false;
491af4adb07SRaphael Isemann   for (Function &f : module) {
492af4adb07SRaphael Isemann     if (f.begin() != f.end()) {
493b9c1b51eSKate Stone       if (saw_function_with_body) {
49463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "More than one function in the module has a body");
4953f998107SAdrian McCarthy         error.SetErrorToGenericError();
4963f998107SAdrian McCarthy         error.SetErrorString(too_many_functions_error);
49785fc8761SSean Callanan         return false;
4983f998107SAdrian McCarthy       }
49985fc8761SSean Callanan       saw_function_with_body = true;
50085fc8761SSean Callanan     }
50185fc8761SSean Callanan   }
50285fc8761SSean Callanan 
503af4adb07SRaphael Isemann   for (BasicBlock &bb : function) {
504af4adb07SRaphael Isemann     for (Instruction &ii : bb) {
505af4adb07SRaphael Isemann       switch (ii.getOpcode()) {
506b9c1b51eSKate Stone       default: {
507af4adb07SRaphael Isemann         LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&ii).c_str());
50844342735SSean Callanan         error.SetErrorToGenericError();
50944342735SSean Callanan         error.SetErrorString(unsupported_opcode_error);
5103bfdaa2aSSean Callanan         return false;
5113bfdaa2aSSean Callanan       }
5123bfdaa2aSSean Callanan       case Instruction::Add:
5133bfdaa2aSSean Callanan       case Instruction::Alloca:
5143bfdaa2aSSean Callanan       case Instruction::BitCast:
5153bfdaa2aSSean Callanan       case Instruction::Br:
5163fe71581SMarianne Mailhot-Sarrasin       case Instruction::PHI:
517576a4374SSean Callanan         break;
518b9c1b51eSKate Stone       case Instruction::Call: {
519af4adb07SRaphael Isemann         CallInst *call_inst = dyn_cast<CallInst>(&ii);
520576a4374SSean Callanan 
521b9c1b51eSKate Stone         if (!call_inst) {
522576a4374SSean Callanan           error.SetErrorToGenericError();
523576a4374SSean Callanan           error.SetErrorString(interpreter_internal_error);
524576a4374SSean Callanan           return false;
525576a4374SSean Callanan         }
526576a4374SSean Callanan 
527b9c1b51eSKate Stone         if (!CanIgnoreCall(call_inst) && !support_function_calls) {
52863e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported instruction: %s",
529af4adb07SRaphael Isemann                     PrintValue(&ii).c_str());
530576a4374SSean Callanan           error.SetErrorToGenericError();
531576a4374SSean Callanan           error.SetErrorString(unsupported_opcode_error);
532576a4374SSean Callanan           return false;
533576a4374SSean Callanan         }
534b9c1b51eSKate Stone       } break;
5353bfdaa2aSSean Callanan       case Instruction::GetElementPtr:
5363bfdaa2aSSean Callanan         break;
537b9c1b51eSKate Stone       case Instruction::ICmp: {
538af4adb07SRaphael Isemann         ICmpInst *icmp_inst = dyn_cast<ICmpInst>(&ii);
5393bfdaa2aSSean Callanan 
540b9c1b51eSKate Stone         if (!icmp_inst) {
54144342735SSean Callanan           error.SetErrorToGenericError();
54244342735SSean Callanan           error.SetErrorString(interpreter_internal_error);
5433bfdaa2aSSean Callanan           return false;
544175a0d04SSean Callanan         }
5453bfdaa2aSSean Callanan 
546b9c1b51eSKate Stone         switch (icmp_inst->getPredicate()) {
547b9c1b51eSKate Stone         default: {
54863e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported ICmp predicate: %s",
549af4adb07SRaphael Isemann                     PrintValue(&ii).c_str());
550175a0d04SSean Callanan 
55144342735SSean Callanan           error.SetErrorToGenericError();
55244342735SSean Callanan           error.SetErrorString(unsupported_opcode_error);
5533bfdaa2aSSean Callanan           return false;
5543bfdaa2aSSean Callanan         }
5553bfdaa2aSSean Callanan         case CmpInst::ICMP_EQ:
5563bfdaa2aSSean Callanan         case CmpInst::ICMP_NE:
5573bfdaa2aSSean Callanan         case CmpInst::ICMP_UGT:
5583bfdaa2aSSean Callanan         case CmpInst::ICMP_UGE:
5593bfdaa2aSSean Callanan         case CmpInst::ICMP_ULT:
5603bfdaa2aSSean Callanan         case CmpInst::ICMP_ULE:
5613bfdaa2aSSean Callanan         case CmpInst::ICMP_SGT:
5623bfdaa2aSSean Callanan         case CmpInst::ICMP_SGE:
5633bfdaa2aSSean Callanan         case CmpInst::ICMP_SLT:
5643bfdaa2aSSean Callanan         case CmpInst::ICMP_SLE:
5653bfdaa2aSSean Callanan           break;
5663bfdaa2aSSean Callanan         }
567b9c1b51eSKate Stone       } break;
568087f437bSSean Callanan       case Instruction::And:
569087f437bSSean Callanan       case Instruction::AShr:
57080c48c10SSean Callanan       case Instruction::IntToPtr:
5712abffe05SSean Callanan       case Instruction::PtrToInt:
5723bfdaa2aSSean Callanan       case Instruction::Load:
573087f437bSSean Callanan       case Instruction::LShr:
5743bfdaa2aSSean Callanan       case Instruction::Mul:
575087f437bSSean Callanan       case Instruction::Or:
5763bfdaa2aSSean Callanan       case Instruction::Ret:
5773bfdaa2aSSean Callanan       case Instruction::SDiv:
578415422ceSSean Callanan       case Instruction::SExt:
579087f437bSSean Callanan       case Instruction::Shl:
580f466a6edSSean Callanan       case Instruction::SRem:
5813bfdaa2aSSean Callanan       case Instruction::Store:
5823bfdaa2aSSean Callanan       case Instruction::Sub:
5838c46bacaSSean Callanan       case Instruction::Trunc:
5843bfdaa2aSSean Callanan       case Instruction::UDiv:
585f466a6edSSean Callanan       case Instruction::URem:
586087f437bSSean Callanan       case Instruction::Xor:
5871ef77434SSean Callanan       case Instruction::ZExt:
5883bfdaa2aSSean Callanan         break;
5893bfdaa2aSSean Callanan       }
5903fa3e65dSSean Callanan 
591af4adb07SRaphael Isemann       for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
592af4adb07SRaphael Isemann         Value *operand = ii.getOperand(oi);
5933fa3e65dSSean Callanan         Type *operand_type = operand->getType();
5943fa3e65dSSean Callanan 
595d405d279SDavide Italiano         switch (operand_type->getTypeID()) {
596d405d279SDavide Italiano         default:
597d405d279SDavide Italiano           break;
5982dea3f12SChristopher Tetreault         case Type::FixedVectorTyID:
5992dea3f12SChristopher Tetreault         case Type::ScalableVectorTyID: {
60063e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported operand type: %s",
601b9c1b51eSKate Stone                     PrintType(operand_type).c_str());
6023fa3e65dSSean Callanan           error.SetErrorString(unsupported_operand_error);
6033fa3e65dSSean Callanan           return false;
604d405d279SDavide Italiano         }
605d405d279SDavide Italiano         }
6068c62daf2SSean Callanan 
6075f6789efSDavide Italiano         // The IR interpreter currently doesn't know about
6085f6789efSDavide Italiano         // 128-bit integers. As they're not that frequent,
6095f6789efSDavide Italiano         // we can just fall back to the JIT rather than
6105f6789efSDavide Italiano         // choking.
6115f6789efSDavide Italiano         if (operand_type->getPrimitiveSizeInBits() > 64) {
61263e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported operand type: %s",
6135f6789efSDavide Italiano                     PrintType(operand_type).c_str());
6145f6789efSDavide Italiano           error.SetErrorString(unsupported_operand_error);
6155f6789efSDavide Italiano           return false;
6165f6789efSDavide Italiano         }
6175f6789efSDavide Italiano 
618d405d279SDavide Italiano         if (Constant *constant = llvm::dyn_cast<Constant>(operand)) {
619b9c1b51eSKate Stone           if (!CanResolveConstant(constant)) {
62063e5fb76SJonas Devlieghere             LLDB_LOGF(log, "Unsupported constant: %s",
621b9c1b51eSKate Stone                       PrintValue(constant).c_str());
6228c62daf2SSean Callanan             error.SetErrorString(unsupported_operand_error);
6238c62daf2SSean Callanan             return false;
6248c62daf2SSean Callanan           }
6258c62daf2SSean Callanan         }
6263fa3e65dSSean Callanan       }
6273fa3e65dSSean Callanan     }
6283fa3e65dSSean Callanan   }
6293bfdaa2aSSean Callanan 
6303f998107SAdrian McCarthy   return true;
6313f998107SAdrian McCarthy }
63214cb2aaaSSean Callanan 
633b9c1b51eSKate Stone bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
6341582ee68SSean Callanan                               llvm::ArrayRef<lldb::addr_t> args,
6357071c5fdSTed Woodward                               lldb_private::IRExecutionUnit &execution_unit,
63697206d57SZachary Turner                               lldb_private::Status &error,
637df56540aSSean Callanan                               lldb::addr_t stack_frame_bottom,
63890ff7911SEwan Crawford                               lldb::addr_t stack_frame_top,
639b9c1b51eSKate Stone                               lldb_private::ExecutionContext &exe_ctx) {
640b9c1b51eSKate Stone   lldb_private::Log *log(
641b9c1b51eSKate Stone       lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
64214cb2aaaSSean Callanan 
643b9c1b51eSKate Stone   if (log) {
6441582ee68SSean Callanan     std::string s;
6451582ee68SSean Callanan     raw_string_ostream oss(s);
6461582ee68SSean Callanan 
647248a1305SKonrad Kleine     module.print(oss, nullptr);
6481582ee68SSean Callanan 
6491582ee68SSean Callanan     oss.flush();
6501582ee68SSean Callanan 
65163e5fb76SJonas Devlieghere     LLDB_LOGF(log, "Module as passed in to IRInterpreter::Interpret: \n\"%s\"",
652b9c1b51eSKate Stone               s.c_str());
6531582ee68SSean Callanan   }
6541582ee68SSean Callanan 
65514cb2aaaSSean Callanan   DataLayout data_layout(&module);
65614cb2aaaSSean Callanan 
657b9c1b51eSKate Stone   InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom,
658b9c1b51eSKate Stone                               stack_frame_top);
65914cb2aaaSSean Callanan 
660b9c1b51eSKate Stone   if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS) {
6611582ee68SSean Callanan     error.SetErrorString("Couldn't allocate stack frame");
6621582ee68SSean Callanan   }
6631582ee68SSean Callanan 
6641582ee68SSean Callanan   int arg_index = 0;
6651582ee68SSean Callanan 
666b9c1b51eSKate Stone   for (llvm::Function::arg_iterator ai = function.arg_begin(),
667b9c1b51eSKate Stone                                     ae = function.arg_end();
668b9c1b51eSKate Stone        ai != ae; ++ai, ++arg_index) {
669b9c1b51eSKate Stone     if (args.size() <= static_cast<size_t>(arg_index)) {
6701582ee68SSean Callanan       error.SetErrorString("Not enough arguments passed in to function");
6711582ee68SSean Callanan       return false;
6721582ee68SSean Callanan     }
6731582ee68SSean Callanan 
6741582ee68SSean Callanan     lldb::addr_t ptr = args[arg_index];
6751582ee68SSean Callanan 
67633e43ca6SDuncan P. N. Exon Smith     frame.MakeArgument(&*ai, ptr);
6771582ee68SSean Callanan   }
6781582ee68SSean Callanan 
67914cb2aaaSSean Callanan   uint32_t num_insts = 0;
68014cb2aaaSSean Callanan 
68133e43ca6SDuncan P. N. Exon Smith   frame.Jump(&function.front());
68214cb2aaaSSean Callanan 
683b9c1b51eSKate Stone   while (frame.m_ii != frame.m_ie && (++num_insts < 4096)) {
68433e43ca6SDuncan P. N. Exon Smith     const Instruction *inst = &*frame.m_ii;
68514cb2aaaSSean Callanan 
68663e5fb76SJonas Devlieghere     LLDB_LOGF(log, "Interpreting %s", PrintValue(inst).c_str());
68714cb2aaaSSean Callanan 
688b9c1b51eSKate Stone     switch (inst->getOpcode()) {
68914cb2aaaSSean Callanan     default:
69014cb2aaaSSean Callanan       break;
691576a4374SSean Callanan 
69214cb2aaaSSean Callanan     case Instruction::Add:
69314cb2aaaSSean Callanan     case Instruction::Sub:
69414cb2aaaSSean Callanan     case Instruction::Mul:
69514cb2aaaSSean Callanan     case Instruction::SDiv:
69614cb2aaaSSean Callanan     case Instruction::UDiv:
69714cb2aaaSSean Callanan     case Instruction::SRem:
69814cb2aaaSSean Callanan     case Instruction::URem:
69914cb2aaaSSean Callanan     case Instruction::Shl:
70014cb2aaaSSean Callanan     case Instruction::LShr:
70114cb2aaaSSean Callanan     case Instruction::AShr:
70214cb2aaaSSean Callanan     case Instruction::And:
70314cb2aaaSSean Callanan     case Instruction::Or:
704b9c1b51eSKate Stone     case Instruction::Xor: {
70514cb2aaaSSean Callanan       const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
70614cb2aaaSSean Callanan 
707b9c1b51eSKate Stone       if (!bin_op) {
70863e5fb76SJonas Devlieghere         LLDB_LOGF(
70963e5fb76SJonas Devlieghere             log,
710b9c1b51eSKate Stone             "getOpcode() returns %s, but instruction is not a BinaryOperator",
711b9c1b51eSKate Stone             inst->getOpcodeName());
71214cb2aaaSSean Callanan         error.SetErrorToGenericError();
71314cb2aaaSSean Callanan         error.SetErrorString(interpreter_internal_error);
71414cb2aaaSSean Callanan         return false;
71514cb2aaaSSean Callanan       }
71614cb2aaaSSean Callanan 
71714cb2aaaSSean Callanan       Value *lhs = inst->getOperand(0);
71814cb2aaaSSean Callanan       Value *rhs = inst->getOperand(1);
71914cb2aaaSSean Callanan 
72014cb2aaaSSean Callanan       lldb_private::Scalar L;
72114cb2aaaSSean Callanan       lldb_private::Scalar R;
72214cb2aaaSSean Callanan 
723b9c1b51eSKate Stone       if (!frame.EvaluateValue(L, lhs, module)) {
72463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
72514cb2aaaSSean Callanan         error.SetErrorToGenericError();
72614cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
72714cb2aaaSSean Callanan         return false;
72814cb2aaaSSean Callanan       }
72914cb2aaaSSean Callanan 
730b9c1b51eSKate Stone       if (!frame.EvaluateValue(R, rhs, module)) {
73163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
73214cb2aaaSSean Callanan         error.SetErrorToGenericError();
73314cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
73414cb2aaaSSean Callanan         return false;
73514cb2aaaSSean Callanan       }
73614cb2aaaSSean Callanan 
73714cb2aaaSSean Callanan       lldb_private::Scalar result;
73814cb2aaaSSean Callanan 
739b9c1b51eSKate Stone       switch (inst->getOpcode()) {
74014cb2aaaSSean Callanan       default:
74114cb2aaaSSean Callanan         break;
74214cb2aaaSSean Callanan       case Instruction::Add:
74314cb2aaaSSean Callanan         result = L + R;
74414cb2aaaSSean Callanan         break;
74514cb2aaaSSean Callanan       case Instruction::Mul:
74614cb2aaaSSean Callanan         result = L * R;
74714cb2aaaSSean Callanan         break;
74814cb2aaaSSean Callanan       case Instruction::Sub:
74914cb2aaaSSean Callanan         result = L - R;
75014cb2aaaSSean Callanan         break;
75114cb2aaaSSean Callanan       case Instruction::SDiv:
7520b342b6dSSean Callanan         L.MakeSigned();
7530b342b6dSSean Callanan         R.MakeSigned();
75414cb2aaaSSean Callanan         result = L / R;
75514cb2aaaSSean Callanan         break;
75614cb2aaaSSean Callanan       case Instruction::UDiv:
7579521ad2aSUlrich Weigand         L.MakeUnsigned();
7589521ad2aSUlrich Weigand         R.MakeUnsigned();
7599521ad2aSUlrich Weigand         result = L / R;
76014cb2aaaSSean Callanan         break;
76114cb2aaaSSean Callanan       case Instruction::SRem:
7620b342b6dSSean Callanan         L.MakeSigned();
7630b342b6dSSean Callanan         R.MakeSigned();
76414cb2aaaSSean Callanan         result = L % R;
76514cb2aaaSSean Callanan         break;
76614cb2aaaSSean Callanan       case Instruction::URem:
7679521ad2aSUlrich Weigand         L.MakeUnsigned();
7689521ad2aSUlrich Weigand         R.MakeUnsigned();
7699521ad2aSUlrich Weigand         result = L % R;
77014cb2aaaSSean Callanan         break;
77114cb2aaaSSean Callanan       case Instruction::Shl:
77214cb2aaaSSean Callanan         result = L << R;
77314cb2aaaSSean Callanan         break;
77414cb2aaaSSean Callanan       case Instruction::AShr:
77514cb2aaaSSean Callanan         result = L >> R;
77614cb2aaaSSean Callanan         break;
77714cb2aaaSSean Callanan       case Instruction::LShr:
77814cb2aaaSSean Callanan         result = L;
77914cb2aaaSSean Callanan         result.ShiftRightLogical(R);
78014cb2aaaSSean Callanan         break;
78114cb2aaaSSean Callanan       case Instruction::And:
78214cb2aaaSSean Callanan         result = L & R;
78314cb2aaaSSean Callanan         break;
78414cb2aaaSSean Callanan       case Instruction::Or:
78514cb2aaaSSean Callanan         result = L | R;
78614cb2aaaSSean Callanan         break;
78714cb2aaaSSean Callanan       case Instruction::Xor:
78814cb2aaaSSean Callanan         result = L ^ R;
78914cb2aaaSSean Callanan         break;
79014cb2aaaSSean Callanan       }
79114cb2aaaSSean Callanan 
79214cb2aaaSSean Callanan       frame.AssignValue(inst, result, module);
79314cb2aaaSSean Callanan 
794b9c1b51eSKate Stone       if (log) {
79563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
79663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  L : %s", frame.SummarizeValue(lhs).c_str());
79763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : %s", frame.SummarizeValue(rhs).c_str());
79863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  = : %s", frame.SummarizeValue(inst).c_str());
79914cb2aaaSSean Callanan       }
800b9c1b51eSKate Stone     } break;
801b9c1b51eSKate Stone     case Instruction::Alloca: {
802f18370feSRaphael Isemann       const AllocaInst *alloca_inst = cast<AllocaInst>(inst);
80314cb2aaaSSean Callanan 
804b9c1b51eSKate Stone       if (alloca_inst->isArrayAllocation()) {
80563e5fb76SJonas Devlieghere         LLDB_LOGF(log,
806b9c1b51eSKate Stone                   "AllocaInsts are not handled if isArrayAllocation() is true");
80714cb2aaaSSean Callanan         error.SetErrorToGenericError();
80814cb2aaaSSean Callanan         error.SetErrorString(unsupported_opcode_error);
80914cb2aaaSSean Callanan         return false;
81014cb2aaaSSean Callanan       }
81114cb2aaaSSean Callanan 
81214cb2aaaSSean Callanan       // The semantics of Alloca are:
813b9c1b51eSKate Stone       //   Create a region R of virtual memory of type T, backed by a data
814b9c1b51eSKate Stone       //   buffer
815b9c1b51eSKate Stone       //   Create a region P of virtual memory of type T*, backed by a data
816b9c1b51eSKate Stone       //   buffer
81714cb2aaaSSean Callanan       //   Write the virtual address of R into P
81814cb2aaaSSean Callanan 
81914cb2aaaSSean Callanan       Type *T = alloca_inst->getAllocatedType();
82014cb2aaaSSean Callanan       Type *Tptr = alloca_inst->getType();
82114cb2aaaSSean Callanan 
82214cb2aaaSSean Callanan       lldb::addr_t R = frame.Malloc(T);
82314cb2aaaSSean Callanan 
824b9c1b51eSKate Stone       if (R == LLDB_INVALID_ADDRESS) {
82563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst");
82614cb2aaaSSean Callanan         error.SetErrorToGenericError();
82714cb2aaaSSean Callanan         error.SetErrorString(memory_allocation_error);
82814cb2aaaSSean Callanan         return false;
82914cb2aaaSSean Callanan       }
83014cb2aaaSSean Callanan 
83114cb2aaaSSean Callanan       lldb::addr_t P = frame.Malloc(Tptr);
83214cb2aaaSSean Callanan 
833b9c1b51eSKate Stone       if (P == LLDB_INVALID_ADDRESS) {
83463e5fb76SJonas Devlieghere         LLDB_LOGF(log,
83563e5fb76SJonas Devlieghere                   "Couldn't allocate the result pointer for an AllocaInst");
83614cb2aaaSSean Callanan         error.SetErrorToGenericError();
83714cb2aaaSSean Callanan         error.SetErrorString(memory_allocation_error);
83814cb2aaaSSean Callanan         return false;
83914cb2aaaSSean Callanan       }
84014cb2aaaSSean Callanan 
84197206d57SZachary Turner       lldb_private::Status write_error;
84214cb2aaaSSean Callanan 
8437071c5fdSTed Woodward       execution_unit.WritePointerToMemory(P, R, write_error);
84414cb2aaaSSean Callanan 
845b9c1b51eSKate Stone       if (!write_error.Success()) {
84663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't write the result pointer for an AllocaInst");
84714cb2aaaSSean Callanan         error.SetErrorToGenericError();
84814cb2aaaSSean Callanan         error.SetErrorString(memory_write_error);
84997206d57SZachary Turner         lldb_private::Status free_error;
8507071c5fdSTed Woodward         execution_unit.Free(P, free_error);
8517071c5fdSTed Woodward         execution_unit.Free(R, free_error);
85214cb2aaaSSean Callanan         return false;
85314cb2aaaSSean Callanan       }
85414cb2aaaSSean Callanan 
85514cb2aaaSSean Callanan       frame.m_values[alloca_inst] = P;
85614cb2aaaSSean Callanan 
857b9c1b51eSKate Stone       if (log) {
85863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted an AllocaInst");
85963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
86063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
86114cb2aaaSSean Callanan       }
862b9c1b51eSKate Stone     } break;
86314cb2aaaSSean Callanan     case Instruction::BitCast:
864b9c1b51eSKate Stone     case Instruction::ZExt: {
865f18370feSRaphael Isemann       const CastInst *cast_inst = cast<CastInst>(inst);
86614cb2aaaSSean Callanan 
86714cb2aaaSSean Callanan       Value *source = cast_inst->getOperand(0);
86814cb2aaaSSean Callanan 
86914cb2aaaSSean Callanan       lldb_private::Scalar S;
87014cb2aaaSSean Callanan 
871b9c1b51eSKate Stone       if (!frame.EvaluateValue(S, source, module)) {
87263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
87314cb2aaaSSean Callanan         error.SetErrorToGenericError();
87414cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
87514cb2aaaSSean Callanan         return false;
87614cb2aaaSSean Callanan       }
87714cb2aaaSSean Callanan 
87814cb2aaaSSean Callanan       frame.AssignValue(inst, S, module);
879b9c1b51eSKate Stone     } break;
880b9c1b51eSKate Stone     case Instruction::SExt: {
881f18370feSRaphael Isemann       const CastInst *cast_inst = cast<CastInst>(inst);
882415422ceSSean Callanan 
883415422ceSSean Callanan       Value *source = cast_inst->getOperand(0);
884415422ceSSean Callanan 
885415422ceSSean Callanan       lldb_private::Scalar S;
886415422ceSSean Callanan 
887b9c1b51eSKate Stone       if (!frame.EvaluateValue(S, source, module)) {
88863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
889415422ceSSean Callanan         error.SetErrorToGenericError();
890415422ceSSean Callanan         error.SetErrorString(bad_value_error);
891415422ceSSean Callanan         return false;
892415422ceSSean Callanan       }
893415422ceSSean Callanan 
894415422ceSSean Callanan       S.MakeSigned();
895415422ceSSean Callanan 
896415422ceSSean Callanan       lldb_private::Scalar S_signextend(S.SLongLong());
897415422ceSSean Callanan 
898415422ceSSean Callanan       frame.AssignValue(inst, S_signextend, module);
899b9c1b51eSKate Stone     } break;
900b9c1b51eSKate Stone     case Instruction::Br: {
901f18370feSRaphael Isemann       const BranchInst *br_inst = cast<BranchInst>(inst);
90214cb2aaaSSean Callanan 
903b9c1b51eSKate Stone       if (br_inst->isConditional()) {
90414cb2aaaSSean Callanan         Value *condition = br_inst->getCondition();
90514cb2aaaSSean Callanan 
90614cb2aaaSSean Callanan         lldb_private::Scalar C;
90714cb2aaaSSean Callanan 
908b9c1b51eSKate Stone         if (!frame.EvaluateValue(C, condition, module)) {
90963e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str());
91014cb2aaaSSean Callanan           error.SetErrorToGenericError();
91114cb2aaaSSean Callanan           error.SetErrorString(bad_value_error);
91214cb2aaaSSean Callanan           return false;
91314cb2aaaSSean Callanan         }
91414cb2aaaSSean Callanan 
9159521ad2aSUlrich Weigand         if (!C.IsZero())
91614cb2aaaSSean Callanan           frame.Jump(br_inst->getSuccessor(0));
91714cb2aaaSSean Callanan         else
91814cb2aaaSSean Callanan           frame.Jump(br_inst->getSuccessor(1));
91914cb2aaaSSean Callanan 
920b9c1b51eSKate Stone         if (log) {
92163e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Interpreted a BrInst with a condition");
92263e5fb76SJonas Devlieghere           LLDB_LOGF(log, "  cond : %s",
92363e5fb76SJonas Devlieghere                     frame.SummarizeValue(condition).c_str());
92414cb2aaaSSean Callanan         }
925b9c1b51eSKate Stone       } else {
92614cb2aaaSSean Callanan         frame.Jump(br_inst->getSuccessor(0));
92714cb2aaaSSean Callanan 
928b9c1b51eSKate Stone         if (log) {
92963e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Interpreted a BrInst with no condition");
93014cb2aaaSSean Callanan         }
93114cb2aaaSSean Callanan       }
93214cb2aaaSSean Callanan     }
93314cb2aaaSSean Callanan       continue;
934b9c1b51eSKate Stone     case Instruction::PHI: {
935f18370feSRaphael Isemann       const PHINode *phi_inst = cast<PHINode>(inst);
936b9c1b51eSKate Stone       if (!frame.m_prev_bb) {
93763e5fb76SJonas Devlieghere         LLDB_LOGF(log,
93863e5fb76SJonas Devlieghere                   "Encountered PHI node without having jumped from another "
939b9c1b51eSKate Stone                   "basic block");
9403fe71581SMarianne Mailhot-Sarrasin         error.SetErrorToGenericError();
9413fe71581SMarianne Mailhot-Sarrasin         error.SetErrorString(interpreter_internal_error);
9423fe71581SMarianne Mailhot-Sarrasin         return false;
9433fe71581SMarianne Mailhot-Sarrasin       }
9443fe71581SMarianne Mailhot-Sarrasin 
9453fe71581SMarianne Mailhot-Sarrasin       Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb);
9463fe71581SMarianne Mailhot-Sarrasin       lldb_private::Scalar result;
947b9c1b51eSKate Stone       if (!frame.EvaluateValue(result, value, module)) {
94863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str());
9493fe71581SMarianne Mailhot-Sarrasin         error.SetErrorToGenericError();
9503fe71581SMarianne Mailhot-Sarrasin         error.SetErrorString(bad_value_error);
9513fe71581SMarianne Mailhot-Sarrasin         return false;
9523fe71581SMarianne Mailhot-Sarrasin       }
9533fe71581SMarianne Mailhot-Sarrasin       frame.AssignValue(inst, result, module);
9543fe71581SMarianne Mailhot-Sarrasin 
955b9c1b51eSKate Stone       if (log) {
95663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
95763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Incoming value : %s",
958b9c1b51eSKate Stone                   frame.SummarizeValue(value).c_str());
9593fe71581SMarianne Mailhot-Sarrasin       }
960b9c1b51eSKate Stone     } break;
961b9c1b51eSKate Stone     case Instruction::GetElementPtr: {
962f18370feSRaphael Isemann       const GetElementPtrInst *gep_inst = cast<GetElementPtrInst>(inst);
96314cb2aaaSSean Callanan 
96414cb2aaaSSean Callanan       const Value *pointer_operand = gep_inst->getPointerOperand();
965d05b8992SEduard Burtescu       Type *src_elem_ty = gep_inst->getSourceElementType();
96614cb2aaaSSean Callanan 
96714cb2aaaSSean Callanan       lldb_private::Scalar P;
96814cb2aaaSSean Callanan 
969b9c1b51eSKate Stone       if (!frame.EvaluateValue(P, pointer_operand, module)) {
97063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s",
971b9c1b51eSKate Stone                   PrintValue(pointer_operand).c_str());
97214cb2aaaSSean Callanan         error.SetErrorToGenericError();
97314cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
97414cb2aaaSSean Callanan         return false;
97514cb2aaaSSean Callanan       }
97614cb2aaaSSean Callanan 
97714cb2aaaSSean Callanan       typedef SmallVector<Value *, 8> IndexVector;
97814cb2aaaSSean Callanan       typedef IndexVector::iterator IndexIterator;
97914cb2aaaSSean Callanan 
98014cb2aaaSSean Callanan       SmallVector<Value *, 8> indices(gep_inst->idx_begin(),
98114cb2aaaSSean Callanan                                       gep_inst->idx_end());
98214cb2aaaSSean Callanan 
98314cb2aaaSSean Callanan       SmallVector<Value *, 8> const_indices;
98414cb2aaaSSean Callanan 
985b9c1b51eSKate Stone       for (IndexIterator ii = indices.begin(), ie = indices.end(); ii != ie;
986b9c1b51eSKate Stone            ++ii) {
98714cb2aaaSSean Callanan         ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);
98814cb2aaaSSean Callanan 
989b9c1b51eSKate Stone         if (!constant_index) {
99014cb2aaaSSean Callanan           lldb_private::Scalar I;
99114cb2aaaSSean Callanan 
992b9c1b51eSKate Stone           if (!frame.EvaluateValue(I, *ii, module)) {
99363e5fb76SJonas Devlieghere             LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str());
99414cb2aaaSSean Callanan             error.SetErrorToGenericError();
99514cb2aaaSSean Callanan             error.SetErrorString(bad_value_error);
99614cb2aaaSSean Callanan             return false;
99714cb2aaaSSean Callanan           }
99814cb2aaaSSean Callanan 
99963e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Evaluated constant index %s as %llu",
100063e5fb76SJonas Devlieghere                     PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
100114cb2aaaSSean Callanan 
1002b9c1b51eSKate Stone           constant_index = cast<ConstantInt>(ConstantInt::get(
1003b9c1b51eSKate Stone               (*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
100414cb2aaaSSean Callanan         }
100514cb2aaaSSean Callanan 
100614cb2aaaSSean Callanan         const_indices.push_back(constant_index);
100714cb2aaaSSean Callanan       }
100814cb2aaaSSean Callanan 
1009b9c1b51eSKate Stone       uint64_t offset =
1010b9c1b51eSKate Stone           data_layout.getIndexedOffsetInType(src_elem_ty, const_indices);
101114cb2aaaSSean Callanan 
101214cb2aaaSSean Callanan       lldb_private::Scalar Poffset = P + offset;
101314cb2aaaSSean Callanan 
101414cb2aaaSSean Callanan       frame.AssignValue(inst, Poffset, module);
101514cb2aaaSSean Callanan 
1016b9c1b51eSKate Stone       if (log) {
101763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a GetElementPtrInst");
101863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P       : %s",
1019b9c1b51eSKate Stone                   frame.SummarizeValue(pointer_operand).c_str());
102063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Poffset : %s", frame.SummarizeValue(inst).c_str());
102114cb2aaaSSean Callanan       }
1022b9c1b51eSKate Stone     } break;
1023b9c1b51eSKate Stone     case Instruction::ICmp: {
1024f18370feSRaphael Isemann       const ICmpInst *icmp_inst = cast<ICmpInst>(inst);
102514cb2aaaSSean Callanan 
102614cb2aaaSSean Callanan       CmpInst::Predicate predicate = icmp_inst->getPredicate();
102714cb2aaaSSean Callanan 
102814cb2aaaSSean Callanan       Value *lhs = inst->getOperand(0);
102914cb2aaaSSean Callanan       Value *rhs = inst->getOperand(1);
103014cb2aaaSSean Callanan 
103114cb2aaaSSean Callanan       lldb_private::Scalar L;
103214cb2aaaSSean Callanan       lldb_private::Scalar R;
103314cb2aaaSSean Callanan 
1034b9c1b51eSKate Stone       if (!frame.EvaluateValue(L, lhs, module)) {
103563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
103614cb2aaaSSean Callanan         error.SetErrorToGenericError();
103714cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
103814cb2aaaSSean Callanan         return false;
103914cb2aaaSSean Callanan       }
104014cb2aaaSSean Callanan 
1041b9c1b51eSKate Stone       if (!frame.EvaluateValue(R, rhs, module)) {
104263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
104314cb2aaaSSean Callanan         error.SetErrorToGenericError();
104414cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
104514cb2aaaSSean Callanan         return false;
104614cb2aaaSSean Callanan       }
104714cb2aaaSSean Callanan 
104814cb2aaaSSean Callanan       lldb_private::Scalar result;
104914cb2aaaSSean Callanan 
1050b9c1b51eSKate Stone       switch (predicate) {
105114cb2aaaSSean Callanan       default:
105214cb2aaaSSean Callanan         return false;
105314cb2aaaSSean Callanan       case CmpInst::ICMP_EQ:
105414cb2aaaSSean Callanan         result = (L == R);
105514cb2aaaSSean Callanan         break;
105614cb2aaaSSean Callanan       case CmpInst::ICMP_NE:
105714cb2aaaSSean Callanan         result = (L != R);
105814cb2aaaSSean Callanan         break;
105914cb2aaaSSean Callanan       case CmpInst::ICMP_UGT:
10609521ad2aSUlrich Weigand         L.MakeUnsigned();
10619521ad2aSUlrich Weigand         R.MakeUnsigned();
10629521ad2aSUlrich Weigand         result = (L > R);
106314cb2aaaSSean Callanan         break;
106414cb2aaaSSean Callanan       case CmpInst::ICMP_UGE:
10659521ad2aSUlrich Weigand         L.MakeUnsigned();
10669521ad2aSUlrich Weigand         R.MakeUnsigned();
10679521ad2aSUlrich Weigand         result = (L >= R);
106814cb2aaaSSean Callanan         break;
106914cb2aaaSSean Callanan       case CmpInst::ICMP_ULT:
10709521ad2aSUlrich Weigand         L.MakeUnsigned();
10719521ad2aSUlrich Weigand         R.MakeUnsigned();
10729521ad2aSUlrich Weigand         result = (L < R);
107314cb2aaaSSean Callanan         break;
107414cb2aaaSSean Callanan       case CmpInst::ICMP_ULE:
10759521ad2aSUlrich Weigand         L.MakeUnsigned();
10769521ad2aSUlrich Weigand         R.MakeUnsigned();
10779521ad2aSUlrich Weigand         result = (L <= R);
107814cb2aaaSSean Callanan         break;
107914cb2aaaSSean Callanan       case CmpInst::ICMP_SGT:
10800b342b6dSSean Callanan         L.MakeSigned();
10810b342b6dSSean Callanan         R.MakeSigned();
108214cb2aaaSSean Callanan         result = (L > R);
108314cb2aaaSSean Callanan         break;
108414cb2aaaSSean Callanan       case CmpInst::ICMP_SGE:
10850b342b6dSSean Callanan         L.MakeSigned();
10860b342b6dSSean Callanan         R.MakeSigned();
108714cb2aaaSSean Callanan         result = (L >= R);
108814cb2aaaSSean Callanan         break;
108914cb2aaaSSean Callanan       case CmpInst::ICMP_SLT:
10900b342b6dSSean Callanan         L.MakeSigned();
10910b342b6dSSean Callanan         R.MakeSigned();
109214cb2aaaSSean Callanan         result = (L < R);
109314cb2aaaSSean Callanan         break;
109414cb2aaaSSean Callanan       case CmpInst::ICMP_SLE:
10950b342b6dSSean Callanan         L.MakeSigned();
10960b342b6dSSean Callanan         R.MakeSigned();
109714cb2aaaSSean Callanan         result = (L <= R);
109814cb2aaaSSean Callanan         break;
109914cb2aaaSSean Callanan       }
110014cb2aaaSSean Callanan 
110114cb2aaaSSean Callanan       frame.AssignValue(inst, result, module);
110214cb2aaaSSean Callanan 
1103b9c1b51eSKate Stone       if (log) {
110463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted an ICmpInst");
110563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  L : %s", frame.SummarizeValue(lhs).c_str());
110663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : %s", frame.SummarizeValue(rhs).c_str());
110763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  = : %s", frame.SummarizeValue(inst).c_str());
110814cb2aaaSSean Callanan       }
1109b9c1b51eSKate Stone     } break;
1110b9c1b51eSKate Stone     case Instruction::IntToPtr: {
1111f18370feSRaphael Isemann       const IntToPtrInst *int_to_ptr_inst = cast<IntToPtrInst>(inst);
111214cb2aaaSSean Callanan 
111314cb2aaaSSean Callanan       Value *src_operand = int_to_ptr_inst->getOperand(0);
111414cb2aaaSSean Callanan 
111514cb2aaaSSean Callanan       lldb_private::Scalar I;
111614cb2aaaSSean Callanan 
1117b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, src_operand, module)) {
111863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
111914cb2aaaSSean Callanan         error.SetErrorToGenericError();
112014cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
112114cb2aaaSSean Callanan         return false;
112214cb2aaaSSean Callanan       }
112314cb2aaaSSean Callanan 
112414cb2aaaSSean Callanan       frame.AssignValue(inst, I, module);
112514cb2aaaSSean Callanan 
1126b9c1b51eSKate Stone       if (log) {
112763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted an IntToPtr");
112863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
112963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
113014cb2aaaSSean Callanan       }
1131b9c1b51eSKate Stone     } break;
1132b9c1b51eSKate Stone     case Instruction::PtrToInt: {
1133f18370feSRaphael Isemann       const PtrToIntInst *ptr_to_int_inst = cast<PtrToIntInst>(inst);
113414cb2aaaSSean Callanan 
113514cb2aaaSSean Callanan       Value *src_operand = ptr_to_int_inst->getOperand(0);
113614cb2aaaSSean Callanan 
113714cb2aaaSSean Callanan       lldb_private::Scalar I;
113814cb2aaaSSean Callanan 
1139b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, src_operand, module)) {
114063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
114114cb2aaaSSean Callanan         error.SetErrorToGenericError();
114214cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
114314cb2aaaSSean Callanan         return false;
114414cb2aaaSSean Callanan       }
114514cb2aaaSSean Callanan 
114614cb2aaaSSean Callanan       frame.AssignValue(inst, I, module);
114714cb2aaaSSean Callanan 
1148b9c1b51eSKate Stone       if (log) {
114963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a PtrToInt");
115063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
115163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
115214cb2aaaSSean Callanan       }
1153b9c1b51eSKate Stone     } break;
1154b9c1b51eSKate Stone     case Instruction::Trunc: {
1155f18370feSRaphael Isemann       const TruncInst *trunc_inst = cast<TruncInst>(inst);
11568c46bacaSSean Callanan 
11578c46bacaSSean Callanan       Value *src_operand = trunc_inst->getOperand(0);
11588c46bacaSSean Callanan 
11598c46bacaSSean Callanan       lldb_private::Scalar I;
11608c46bacaSSean Callanan 
1161b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, src_operand, module)) {
116263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
11638c46bacaSSean Callanan         error.SetErrorToGenericError();
11648c46bacaSSean Callanan         error.SetErrorString(bad_value_error);
11658c46bacaSSean Callanan         return false;
11668c46bacaSSean Callanan       }
11678c46bacaSSean Callanan 
11688c46bacaSSean Callanan       frame.AssignValue(inst, I, module);
11698c46bacaSSean Callanan 
1170b9c1b51eSKate Stone       if (log) {
117163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a Trunc");
117263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
117363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
11748c46bacaSSean Callanan       }
1175b9c1b51eSKate Stone     } break;
1176b9c1b51eSKate Stone     case Instruction::Load: {
1177f18370feSRaphael Isemann       const LoadInst *load_inst = cast<LoadInst>(inst);
117814cb2aaaSSean Callanan 
117914cb2aaaSSean Callanan       // The semantics of Load are:
118014cb2aaaSSean Callanan       //   Create a region D that will contain the loaded data
118114cb2aaaSSean Callanan       //   Resolve the region P containing a pointer
118214cb2aaaSSean Callanan       //   Dereference P to get the region R that the data should be loaded from
118314cb2aaaSSean Callanan       //   Transfer a unit of type type(D) from R to D
118414cb2aaaSSean Callanan 
118514cb2aaaSSean Callanan       const Value *pointer_operand = load_inst->getPointerOperand();
118614cb2aaaSSean Callanan 
118714cb2aaaSSean Callanan       Type *pointer_ty = pointer_operand->getType();
118814cb2aaaSSean Callanan       PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
1189b9c1b51eSKate Stone       if (!pointer_ptr_ty) {
119063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "getPointerOperand()->getType() is not a PointerType");
119114cb2aaaSSean Callanan         error.SetErrorToGenericError();
119214cb2aaaSSean Callanan         error.SetErrorString(interpreter_internal_error);
119314cb2aaaSSean Callanan         return false;
119414cb2aaaSSean Callanan       }
119514cb2aaaSSean Callanan       Type *target_ty = pointer_ptr_ty->getElementType();
119614cb2aaaSSean Callanan 
119714cb2aaaSSean Callanan       lldb::addr_t D = frame.ResolveValue(load_inst, module);
119814cb2aaaSSean Callanan       lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
119914cb2aaaSSean Callanan 
1200b9c1b51eSKate Stone       if (D == LLDB_INVALID_ADDRESS) {
120163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything");
120214cb2aaaSSean Callanan         error.SetErrorToGenericError();
120314cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
120414cb2aaaSSean Callanan         return false;
120514cb2aaaSSean Callanan       }
120614cb2aaaSSean Callanan 
1207b9c1b51eSKate Stone       if (P == LLDB_INVALID_ADDRESS) {
120863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "LoadInst's pointer doesn't resolve to anything");
120914cb2aaaSSean Callanan         error.SetErrorToGenericError();
121014cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
121114cb2aaaSSean Callanan         return false;
121214cb2aaaSSean Callanan       }
121314cb2aaaSSean Callanan 
121414cb2aaaSSean Callanan       lldb::addr_t R;
121597206d57SZachary Turner       lldb_private::Status read_error;
12167071c5fdSTed Woodward       execution_unit.ReadPointerFromMemory(&R, P, read_error);
121714cb2aaaSSean Callanan 
1218b9c1b51eSKate Stone       if (!read_error.Success()) {
121963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
122014cb2aaaSSean Callanan         error.SetErrorToGenericError();
122114cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
122214cb2aaaSSean Callanan         return false;
122314cb2aaaSSean Callanan       }
122414cb2aaaSSean Callanan 
122514cb2aaaSSean Callanan       size_t target_size = data_layout.getTypeStoreSize(target_ty);
122614cb2aaaSSean Callanan       lldb_private::DataBufferHeap buffer(target_size, 0);
122714cb2aaaSSean Callanan 
122814cb2aaaSSean Callanan       read_error.Clear();
1229b9c1b51eSKate Stone       execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(),
1230b9c1b51eSKate Stone                                 read_error);
1231b9c1b51eSKate Stone       if (!read_error.Success()) {
123263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read from a region on behalf of a LoadInst");
123314cb2aaaSSean Callanan         error.SetErrorToGenericError();
123414cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
123514cb2aaaSSean Callanan         return false;
123614cb2aaaSSean Callanan       }
123714cb2aaaSSean Callanan 
123897206d57SZachary Turner       lldb_private::Status write_error;
1239b9c1b51eSKate Stone       execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(),
1240b9c1b51eSKate Stone                                  write_error);
1241b9c1b51eSKate Stone       if (!write_error.Success()) {
124263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst");
124314cb2aaaSSean Callanan         error.SetErrorToGenericError();
124414cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
124514cb2aaaSSean Callanan         return false;
124614cb2aaaSSean Callanan       }
124714cb2aaaSSean Callanan 
1248b9c1b51eSKate Stone       if (log) {
124963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a LoadInst");
125063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
125163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
125263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  D : 0x%" PRIx64, D);
125314cb2aaaSSean Callanan       }
1254b9c1b51eSKate Stone     } break;
1255b9c1b51eSKate Stone     case Instruction::Ret: {
125614cb2aaaSSean Callanan       return true;
125714cb2aaaSSean Callanan     }
1258b9c1b51eSKate Stone     case Instruction::Store: {
1259f18370feSRaphael Isemann       const StoreInst *store_inst = cast<StoreInst>(inst);
126014cb2aaaSSean Callanan 
126114cb2aaaSSean Callanan       // The semantics of Store are:
126214cb2aaaSSean Callanan       //   Resolve the region D containing the data to be stored
126314cb2aaaSSean Callanan       //   Resolve the region P containing a pointer
126414cb2aaaSSean Callanan       //   Dereference P to get the region R that the data should be stored in
126514cb2aaaSSean Callanan       //   Transfer a unit of type type(D) from D to R
126614cb2aaaSSean Callanan 
126714cb2aaaSSean Callanan       const Value *value_operand = store_inst->getValueOperand();
126814cb2aaaSSean Callanan       const Value *pointer_operand = store_inst->getPointerOperand();
126914cb2aaaSSean Callanan 
127014cb2aaaSSean Callanan       Type *pointer_ty = pointer_operand->getType();
127114cb2aaaSSean Callanan       PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
127214cb2aaaSSean Callanan       if (!pointer_ptr_ty)
127314cb2aaaSSean Callanan         return false;
127414cb2aaaSSean Callanan       Type *target_ty = pointer_ptr_ty->getElementType();
127514cb2aaaSSean Callanan 
127614cb2aaaSSean Callanan       lldb::addr_t D = frame.ResolveValue(value_operand, module);
127714cb2aaaSSean Callanan       lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
127814cb2aaaSSean Callanan 
1279b9c1b51eSKate Stone       if (D == LLDB_INVALID_ADDRESS) {
128063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything");
128114cb2aaaSSean Callanan         error.SetErrorToGenericError();
128214cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
128314cb2aaaSSean Callanan         return false;
128414cb2aaaSSean Callanan       }
128514cb2aaaSSean Callanan 
1286b9c1b51eSKate Stone       if (P == LLDB_INVALID_ADDRESS) {
128763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "StoreInst's pointer doesn't resolve to anything");
128814cb2aaaSSean Callanan         error.SetErrorToGenericError();
128914cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
129014cb2aaaSSean Callanan         return false;
129114cb2aaaSSean Callanan       }
129214cb2aaaSSean Callanan 
129314cb2aaaSSean Callanan       lldb::addr_t R;
129497206d57SZachary Turner       lldb_private::Status read_error;
12957071c5fdSTed Woodward       execution_unit.ReadPointerFromMemory(&R, P, read_error);
129614cb2aaaSSean Callanan 
1297b9c1b51eSKate Stone       if (!read_error.Success()) {
129863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
129914cb2aaaSSean Callanan         error.SetErrorToGenericError();
130014cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
130114cb2aaaSSean Callanan         return false;
130214cb2aaaSSean Callanan       }
130314cb2aaaSSean Callanan 
130414cb2aaaSSean Callanan       size_t target_size = data_layout.getTypeStoreSize(target_ty);
130514cb2aaaSSean Callanan       lldb_private::DataBufferHeap buffer(target_size, 0);
130614cb2aaaSSean Callanan 
130714cb2aaaSSean Callanan       read_error.Clear();
1308b9c1b51eSKate Stone       execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(),
1309b9c1b51eSKate Stone                                 read_error);
1310b9c1b51eSKate Stone       if (!read_error.Success()) {
131163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read from a region on behalf of a StoreInst");
131214cb2aaaSSean Callanan         error.SetErrorToGenericError();
131314cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
131414cb2aaaSSean Callanan         return false;
131514cb2aaaSSean Callanan       }
131614cb2aaaSSean Callanan 
131797206d57SZachary Turner       lldb_private::Status write_error;
1318b9c1b51eSKate Stone       execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(),
1319b9c1b51eSKate Stone                                  write_error);
1320b9c1b51eSKate Stone       if (!write_error.Success()) {
132163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't write to a region on behalf of a StoreInst");
132214cb2aaaSSean Callanan         error.SetErrorToGenericError();
132349630e7fSSean Callanan         error.SetErrorString(memory_write_error);
132414cb2aaaSSean Callanan         return false;
132514cb2aaaSSean Callanan       }
132614cb2aaaSSean Callanan 
1327b9c1b51eSKate Stone       if (log) {
132863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a StoreInst");
132963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  D : 0x%" PRIx64, D);
133063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
133163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
133214cb2aaaSSean Callanan       }
1333b9c1b51eSKate Stone     } break;
1334b9c1b51eSKate Stone     case Instruction::Call: {
1335f18370feSRaphael Isemann       const CallInst *call_inst = cast<CallInst>(inst);
133690ff7911SEwan Crawford 
133790ff7911SEwan Crawford       if (CanIgnoreCall(call_inst))
133890ff7911SEwan Crawford         break;
133990ff7911SEwan Crawford 
134090ff7911SEwan Crawford       // Get the return type
134190ff7911SEwan Crawford       llvm::Type *returnType = call_inst->getType();
1342b9c1b51eSKate Stone       if (returnType == nullptr) {
134390ff7911SEwan Crawford         error.SetErrorToGenericError();
134490ff7911SEwan Crawford         error.SetErrorString("unable to access return type");
134590ff7911SEwan Crawford         return false;
134690ff7911SEwan Crawford       }
134790ff7911SEwan Crawford 
134890ff7911SEwan Crawford       // Work with void, integer and pointer return types
1349b9c1b51eSKate Stone       if (!returnType->isVoidTy() && !returnType->isIntegerTy() &&
1350b9c1b51eSKate Stone           !returnType->isPointerTy()) {
135190ff7911SEwan Crawford         error.SetErrorToGenericError();
135290ff7911SEwan Crawford         error.SetErrorString("return type is not supported");
135390ff7911SEwan Crawford         return false;
135490ff7911SEwan Crawford       }
135590ff7911SEwan Crawford 
135690ff7911SEwan Crawford       // Check we can actually get a thread
1357b9c1b51eSKate Stone       if (exe_ctx.GetThreadPtr() == nullptr) {
135890ff7911SEwan Crawford         error.SetErrorToGenericError();
135990ff7911SEwan Crawford         error.SetErrorStringWithFormat("unable to acquire thread");
136090ff7911SEwan Crawford         return false;
136190ff7911SEwan Crawford       }
136290ff7911SEwan Crawford 
136390ff7911SEwan Crawford       // Make sure we have a valid process
1364b9c1b51eSKate Stone       if (!exe_ctx.GetProcessPtr()) {
136590ff7911SEwan Crawford         error.SetErrorToGenericError();
136690ff7911SEwan Crawford         error.SetErrorStringWithFormat("unable to get the process");
136790ff7911SEwan Crawford         return false;
136890ff7911SEwan Crawford       }
136990ff7911SEwan Crawford 
137090ff7911SEwan Crawford       // Find the address of the callee function
137190ff7911SEwan Crawford       lldb_private::Scalar I;
1372a58b62b4SCraig Topper       const llvm::Value *val = call_inst->getCalledOperand();
137390ff7911SEwan Crawford 
1374b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, val, module)) {
137590ff7911SEwan Crawford         error.SetErrorToGenericError();
137690ff7911SEwan Crawford         error.SetErrorString("unable to get address of function");
137790ff7911SEwan Crawford         return false;
137890ff7911SEwan Crawford       }
137990ff7911SEwan Crawford       lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS));
138090ff7911SEwan Crawford 
1381579e70c9SSean Callanan       lldb_private::DiagnosticManager diagnostics;
138290ff7911SEwan Crawford       lldb_private::EvaluateExpressionOptions options;
138390ff7911SEwan Crawford 
138490ff7911SEwan Crawford       // We generally receive a function pointer which we must dereference
138590ff7911SEwan Crawford       llvm::Type *prototype = val->getType();
1386b9c1b51eSKate Stone       if (!prototype->isPointerTy()) {
138790ff7911SEwan Crawford         error.SetErrorToGenericError();
138890ff7911SEwan Crawford         error.SetErrorString("call need function pointer");
138990ff7911SEwan Crawford         return false;
139090ff7911SEwan Crawford       }
139190ff7911SEwan Crawford 
139290ff7911SEwan Crawford       // Dereference the function pointer
139390ff7911SEwan Crawford       prototype = prototype->getPointerElementType();
1394b9c1b51eSKate Stone       if (!(prototype->isFunctionTy() || prototype->isFunctionVarArg())) {
139590ff7911SEwan Crawford         error.SetErrorToGenericError();
139690ff7911SEwan Crawford         error.SetErrorString("call need function pointer");
139790ff7911SEwan Crawford         return false;
139890ff7911SEwan Crawford       }
139990ff7911SEwan Crawford 
140090ff7911SEwan Crawford       // Find number of arguments
140190ff7911SEwan Crawford       const int numArgs = call_inst->getNumArgOperands();
140290ff7911SEwan Crawford 
140390ff7911SEwan Crawford       // We work with a fixed array of 16 arguments which is our upper limit
140490ff7911SEwan Crawford       static lldb_private::ABI::CallArgument rawArgs[16];
1405b9c1b51eSKate Stone       if (numArgs >= 16) {
140690ff7911SEwan Crawford         error.SetErrorToGenericError();
140790ff7911SEwan Crawford         error.SetErrorStringWithFormat("function takes too many arguments");
140890ff7911SEwan Crawford         return false;
140990ff7911SEwan Crawford       }
141090ff7911SEwan Crawford 
141105097246SAdrian Prantl       // Push all function arguments to the argument list that will be passed
141205097246SAdrian Prantl       // to the call function thread plan
1413b9c1b51eSKate Stone       for (int i = 0; i < numArgs; i++) {
141490ff7911SEwan Crawford         // Get details of this argument
141590ff7911SEwan Crawford         llvm::Value *arg_op = call_inst->getArgOperand(i);
141690ff7911SEwan Crawford         llvm::Type *arg_ty = arg_op->getType();
141790ff7911SEwan Crawford 
141890ff7911SEwan Crawford         // Ensure that this argument is an supported type
1419b9c1b51eSKate Stone         if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) {
142090ff7911SEwan Crawford           error.SetErrorToGenericError();
142190ff7911SEwan Crawford           error.SetErrorStringWithFormat("argument %d must be integer type", i);
142290ff7911SEwan Crawford           return false;
142390ff7911SEwan Crawford         }
142490ff7911SEwan Crawford 
142590ff7911SEwan Crawford         // Extract the arguments value
142690ff7911SEwan Crawford         lldb_private::Scalar tmp_op = 0;
1427b9c1b51eSKate Stone         if (!frame.EvaluateValue(tmp_op, arg_op, module)) {
142890ff7911SEwan Crawford           error.SetErrorToGenericError();
142990ff7911SEwan Crawford           error.SetErrorStringWithFormat("unable to evaluate argument %d", i);
143090ff7911SEwan Crawford           return false;
143190ff7911SEwan Crawford         }
143290ff7911SEwan Crawford 
143390ff7911SEwan Crawford         // Check if this is a string literal or constant string pointer
1434b9c1b51eSKate Stone         if (arg_ty->isPointerTy()) {
143590ff7911SEwan Crawford           lldb::addr_t addr = tmp_op.ULongLong();
143690ff7911SEwan Crawford           size_t dataSize = 0;
143790ff7911SEwan Crawford 
1438a322f36cSDavid Blaikie           bool Success = execution_unit.GetAllocSize(addr, dataSize);
1439a322f36cSDavid Blaikie           (void)Success;
1440a322f36cSDavid Blaikie           assert(Success &&
1441a322f36cSDavid Blaikie                  "unable to locate host data for transfer to device");
144290ff7911SEwan Crawford           // Create the required buffer
144390ff7911SEwan Crawford           rawArgs[i].size = dataSize;
1444d5b44036SJonas Devlieghere           rawArgs[i].data_up.reset(new uint8_t[dataSize + 1]);
144590ff7911SEwan Crawford 
144690ff7911SEwan Crawford           // Read string from host memory
1447d5b44036SJonas Devlieghere           execution_unit.ReadMemory(rawArgs[i].data_up.get(), addr, dataSize,
1448b9c1b51eSKate Stone                                     error);
1449a322f36cSDavid Blaikie           assert(!error.Fail() &&
1450a322f36cSDavid Blaikie                  "we have failed to read the string from memory");
1451a322f36cSDavid Blaikie 
145290ff7911SEwan Crawford           // Add null terminator
1453d5b44036SJonas Devlieghere           rawArgs[i].data_up[dataSize] = '\0';
145490ff7911SEwan Crawford           rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer;
1455b9c1b51eSKate Stone         } else /* if ( arg_ty->isPointerTy() ) */
145690ff7911SEwan Crawford         {
145790ff7911SEwan Crawford           rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue;
145890ff7911SEwan Crawford           // Get argument size in bytes
145990ff7911SEwan Crawford           rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8;
146090ff7911SEwan Crawford           // Push value into argument list for thread plan
146190ff7911SEwan Crawford           rawArgs[i].value = tmp_op.ULongLong();
146290ff7911SEwan Crawford         }
146390ff7911SEwan Crawford       }
146490ff7911SEwan Crawford 
146590ff7911SEwan Crawford       // Pack the arguments into an llvm::array
146690ff7911SEwan Crawford       llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs);
146790ff7911SEwan Crawford 
146890ff7911SEwan Crawford       // Setup a thread plan to call the target function
1469b9c1b51eSKate Stone       lldb::ThreadPlanSP call_plan_sp(
1470b9c1b51eSKate Stone           new lldb_private::ThreadPlanCallFunctionUsingABI(
1471b9c1b51eSKate Stone               exe_ctx.GetThreadRef(), funcAddr, *prototype, *returnType, args,
1472b9c1b51eSKate Stone               options));
147390ff7911SEwan Crawford 
147490ff7911SEwan Crawford       // Check if the plan is valid
1475579e70c9SSean Callanan       lldb_private::StreamString ss;
1476b9c1b51eSKate Stone       if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) {
147790ff7911SEwan Crawford         error.SetErrorToGenericError();
1478b9c1b51eSKate Stone         error.SetErrorStringWithFormat(
1479b9c1b51eSKate Stone             "unable to make ThreadPlanCallFunctionUsingABI for 0x%llx",
1480579e70c9SSean Callanan             I.ULongLong());
148190ff7911SEwan Crawford         return false;
148290ff7911SEwan Crawford       }
148390ff7911SEwan Crawford 
148490ff7911SEwan Crawford       exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
148590ff7911SEwan Crawford 
148690ff7911SEwan Crawford       // Execute the actual function call thread plan
1487b9c1b51eSKate Stone       lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan(
1488b9c1b51eSKate Stone           exe_ctx, call_plan_sp, options, diagnostics);
148990ff7911SEwan Crawford 
149090ff7911SEwan Crawford       // Check that the thread plan completed successfully
1491b9c1b51eSKate Stone       if (res != lldb::ExpressionResults::eExpressionCompleted) {
149290ff7911SEwan Crawford         error.SetErrorToGenericError();
149390ff7911SEwan Crawford         error.SetErrorStringWithFormat("ThreadPlanCallFunctionUsingABI failed");
149490ff7911SEwan Crawford         return false;
149590ff7911SEwan Crawford       }
149690ff7911SEwan Crawford 
149790ff7911SEwan Crawford       exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
149890ff7911SEwan Crawford 
149990ff7911SEwan Crawford       // Void return type
1500b9c1b51eSKate Stone       if (returnType->isVoidTy()) {
150190ff7911SEwan Crawford         // Cant assign to void types, so we leave the frame untouched
1502b9c1b51eSKate Stone       } else
150390ff7911SEwan Crawford           // Integer or pointer return type
1504b9c1b51eSKate Stone           if (returnType->isIntegerTy() || returnType->isPointerTy()) {
150590ff7911SEwan Crawford         // Get the encapsulated return value
150690ff7911SEwan Crawford         lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject();
150790ff7911SEwan Crawford 
150890ff7911SEwan Crawford         lldb_private::Scalar returnVal = -1;
150990ff7911SEwan Crawford         lldb_private::ValueObject *vobj = retVal.get();
151090ff7911SEwan Crawford 
151190ff7911SEwan Crawford         // Check if the return value is valid
1512363f05b8SPavel Labath         if (vobj == nullptr || !retVal) {
151390ff7911SEwan Crawford           error.SetErrorToGenericError();
151490ff7911SEwan Crawford           error.SetErrorStringWithFormat("unable to get the return value");
151590ff7911SEwan Crawford           return false;
151690ff7911SEwan Crawford         }
151790ff7911SEwan Crawford 
151890ff7911SEwan Crawford         // Extract the return value as a integer
151990ff7911SEwan Crawford         lldb_private::Value &value = vobj->GetValue();
152090ff7911SEwan Crawford         returnVal = value.GetScalar();
152190ff7911SEwan Crawford 
152290ff7911SEwan Crawford         // Push the return value as the result
152390ff7911SEwan Crawford         frame.AssignValue(inst, returnVal, module);
152490ff7911SEwan Crawford       }
1525b9c1b51eSKate Stone     } break;
152614cb2aaaSSean Callanan     }
152714cb2aaaSSean Callanan 
152814cb2aaaSSean Callanan     ++frame.m_ii;
152914cb2aaaSSean Callanan   }
153014cb2aaaSSean Callanan 
1531b9c1b51eSKate Stone   if (num_insts >= 4096) {
153214cb2aaaSSean Callanan     error.SetErrorToGenericError();
153314cb2aaaSSean Callanan     error.SetErrorString(infinite_loop_error);
153414cb2aaaSSean Callanan     return false;
153514cb2aaaSSean Callanan   }
153614cb2aaaSSean Callanan 
153714cb2aaaSSean Callanan   return false;
153814cb2aaaSSean Callanan }
1539