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"
19c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
206f9e6901SZachary Turner #include "lldb/Utility/Log.h"
21d821c997SPavel Labath #include "lldb/Utility/Scalar.h"
2297206d57SZachary Turner #include "lldb/Utility/Status.h"
23bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
243bfdaa2aSSean Callanan 
2590ff7911SEwan Crawford #include "lldb/Target/ABI.h"
2690ff7911SEwan Crawford #include "lldb/Target/ExecutionContext.h"
2790ff7911SEwan Crawford #include "lldb/Target/Target.h"
2890ff7911SEwan Crawford #include "lldb/Target/Thread.h"
2990ff7911SEwan Crawford #include "lldb/Target/ThreadPlan.h"
3090ff7911SEwan Crawford #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
3190ff7911SEwan Crawford 
321e157587SChandler Carruth #include "llvm/IR/Constants.h"
33fefe43cdSSean Callanan #include "llvm/IR/DataLayout.h"
341e157587SChandler Carruth #include "llvm/IR/Function.h"
351e157587SChandler Carruth #include "llvm/IR/Instructions.h"
36576a4374SSean Callanan #include "llvm/IR/Intrinsics.h"
3790ff7911SEwan Crawford #include "llvm/IR/LLVMContext.h"
381e157587SChandler Carruth #include "llvm/IR/Module.h"
39d05b8992SEduard Burtescu #include "llvm/IR/Operator.h"
403bfdaa2aSSean Callanan #include "llvm/Support/raw_ostream.h"
413bfdaa2aSSean Callanan 
423bfdaa2aSSean Callanan #include <map>
433bfdaa2aSSean Callanan 
443bfdaa2aSSean Callanan using namespace llvm;
45a007a6d8SPavel Labath using lldb_private::LLDBLog;
463bfdaa2aSSean Callanan 
PrintValue(const Value * value,bool truncate=false)47b9c1b51eSKate Stone static std::string PrintValue(const Value *value, bool truncate = false) {
483bfdaa2aSSean Callanan   std::string s;
493bfdaa2aSSean Callanan   raw_string_ostream rso(s);
503bfdaa2aSSean Callanan   value->print(rso);
513bfdaa2aSSean Callanan   rso.flush();
523bfdaa2aSSean Callanan   if (truncate)
533bfdaa2aSSean Callanan     s.resize(s.length() - 1);
543bfdaa2aSSean Callanan 
553bfdaa2aSSean Callanan   size_t offset;
563bfdaa2aSSean Callanan   while ((offset = s.find('\n')) != s.npos)
573bfdaa2aSSean Callanan     s.erase(offset, 1);
583bfdaa2aSSean Callanan   while (s[0] == ' ' || s[0] == '\t')
593bfdaa2aSSean Callanan     s.erase(0, 1);
603bfdaa2aSSean Callanan 
613bfdaa2aSSean Callanan   return s;
623bfdaa2aSSean Callanan }
633bfdaa2aSSean Callanan 
PrintType(const Type * type,bool truncate=false)64b9c1b51eSKate Stone static std::string PrintType(const Type *type, bool truncate = false) {
653bfdaa2aSSean Callanan   std::string s;
663bfdaa2aSSean Callanan   raw_string_ostream rso(s);
673bfdaa2aSSean Callanan   type->print(rso);
683bfdaa2aSSean Callanan   rso.flush();
693bfdaa2aSSean Callanan   if (truncate)
703bfdaa2aSSean Callanan     s.resize(s.length() - 1);
713bfdaa2aSSean Callanan   return s;
723bfdaa2aSSean Callanan }
733bfdaa2aSSean Callanan 
CanIgnoreCall(const CallInst * call)74b9c1b51eSKate Stone static bool CanIgnoreCall(const CallInst *call) {
75576a4374SSean Callanan   const llvm::Function *called_function = call->getCalledFunction();
76576a4374SSean Callanan 
77576a4374SSean Callanan   if (!called_function)
78576a4374SSean Callanan     return false;
79576a4374SSean Callanan 
80b9c1b51eSKate Stone   if (called_function->isIntrinsic()) {
81b9c1b51eSKate Stone     switch (called_function->getIntrinsicID()) {
82576a4374SSean Callanan     default:
83576a4374SSean Callanan       break;
84576a4374SSean Callanan     case llvm::Intrinsic::dbg_declare:
85576a4374SSean Callanan     case llvm::Intrinsic::dbg_value:
86576a4374SSean Callanan       return true;
87576a4374SSean Callanan     }
88576a4374SSean Callanan   }
89576a4374SSean Callanan 
90576a4374SSean Callanan   return false;
91576a4374SSean Callanan }
92576a4374SSean Callanan 
93b9c1b51eSKate Stone class InterpreterStackFrame {
943bfdaa2aSSean Callanan public:
9508052afaSSean Callanan   typedef std::map<const Value *, lldb::addr_t> ValueMap;
9608052afaSSean Callanan 
973bfdaa2aSSean Callanan   ValueMap m_values;
988468dbecSMicah Villmow   DataLayout &m_target_data;
997071c5fdSTed Woodward   lldb_private::IRExecutionUnit &m_execution_unit;
100*28c878aeSShafik Yaghmour   const BasicBlock *m_bb = nullptr;
101*28c878aeSShafik Yaghmour   const BasicBlock *m_prev_bb = nullptr;
1023bfdaa2aSSean Callanan   BasicBlock::const_iterator m_ii;
1033bfdaa2aSSean Callanan   BasicBlock::const_iterator m_ie;
1043bfdaa2aSSean Callanan 
1051582ee68SSean Callanan   lldb::addr_t m_frame_process_address;
1061582ee68SSean Callanan   size_t m_frame_size;
1071582ee68SSean Callanan   lldb::addr_t m_stack_pointer;
1081582ee68SSean Callanan 
1093bfdaa2aSSean Callanan   lldb::ByteOrder m_byte_order;
1103bfdaa2aSSean Callanan   size_t m_addr_byte_size;
1113bfdaa2aSSean Callanan 
InterpreterStackFrame(DataLayout & target_data,lldb_private::IRExecutionUnit & execution_unit,lldb::addr_t stack_frame_bottom,lldb::addr_t stack_frame_top)1128468dbecSMicah Villmow   InterpreterStackFrame(DataLayout &target_data,
1137071c5fdSTed Woodward                         lldb_private::IRExecutionUnit &execution_unit,
114df56540aSSean Callanan                         lldb::addr_t stack_frame_bottom,
115b9c1b51eSKate Stone                         lldb::addr_t stack_frame_top)
116*28c878aeSShafik Yaghmour       : m_target_data(target_data), m_execution_unit(execution_unit) {
117b9c1b51eSKate Stone     m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle
118b9c1b51eSKate Stone                                                  : lldb::eByteOrderBig);
11995769bf4SSean Callanan     m_addr_byte_size = (target_data.getPointerSize(0));
1201582ee68SSean Callanan 
121df56540aSSean Callanan     m_frame_process_address = stack_frame_bottom;
122df56540aSSean Callanan     m_frame_size = stack_frame_top - stack_frame_bottom;
123df56540aSSean Callanan     m_stack_pointer = stack_frame_top;
1241582ee68SSean Callanan   }
1251582ee68SSean Callanan 
126fd2433e1SJonas Devlieghere   ~InterpreterStackFrame() = default;
1273bfdaa2aSSean Callanan 
Jump(const BasicBlock * bb)128b9c1b51eSKate Stone   void Jump(const BasicBlock *bb) {
1293fe71581SMarianne Mailhot-Sarrasin     m_prev_bb = m_bb;
1303bfdaa2aSSean Callanan     m_bb = bb;
1313bfdaa2aSSean Callanan     m_ii = m_bb->begin();
1323bfdaa2aSSean Callanan     m_ie = m_bb->end();
1333bfdaa2aSSean Callanan   }
1343bfdaa2aSSean Callanan 
SummarizeValue(const Value * value)135b9c1b51eSKate Stone   std::string SummarizeValue(const Value *value) {
1363bfdaa2aSSean Callanan     lldb_private::StreamString ss;
1373bfdaa2aSSean Callanan 
1383bfdaa2aSSean Callanan     ss.Printf("%s", PrintValue(value).c_str());
1393bfdaa2aSSean Callanan 
1403bfdaa2aSSean Callanan     ValueMap::iterator i = m_values.find(value);
1413bfdaa2aSSean Callanan 
142b9c1b51eSKate Stone     if (i != m_values.end()) {
14308052afaSSean Callanan       lldb::addr_t addr = i->second;
1443bfdaa2aSSean Callanan 
14508052afaSSean Callanan       ss.Printf(" 0x%llx", (unsigned long long)addr);
1463bfdaa2aSSean Callanan     }
1473bfdaa2aSSean Callanan 
148adcd0268SBenjamin Kramer     return std::string(ss.GetString());
1493bfdaa2aSSean Callanan   }
1503bfdaa2aSSean Callanan 
AssignToMatchType(lldb_private::Scalar & scalar,llvm::APInt value,Type * type)151b725142cSPavel Labath   bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value,
152b9c1b51eSKate Stone                          Type *type) {
1533bfdaa2aSSean Callanan     size_t type_size = m_target_data.getTypeStoreSize(type);
1543bfdaa2aSSean Callanan 
155ae6ca2fcSFrederic Riss     if (type_size > 8)
1563bfdaa2aSSean Callanan       return false;
1573bfdaa2aSSean Callanan 
158ae6ca2fcSFrederic Riss     if (type_size != 1)
159ae6ca2fcSFrederic Riss       type_size = PowerOf2Ceil(type_size);
160ae6ca2fcSFrederic Riss 
161b725142cSPavel Labath     scalar = value.zextOrTrunc(type_size * 8);
1623bfdaa2aSSean Callanan     return true;
1633bfdaa2aSSean Callanan   }
1643bfdaa2aSSean Callanan 
EvaluateValue(lldb_private::Scalar & scalar,const Value * value,Module & module)165b9c1b51eSKate Stone   bool EvaluateValue(lldb_private::Scalar &scalar, const Value *value,
166b9c1b51eSKate Stone                      Module &module) {
1673bfdaa2aSSean Callanan     const Constant *constant = dyn_cast<Constant>(value);
1683bfdaa2aSSean Callanan 
169b9c1b51eSKate Stone     if (constant) {
170415422ceSSean Callanan       APInt value_apint;
171415422ceSSean Callanan 
172415422ceSSean Callanan       if (!ResolveConstantValue(value_apint, constant))
173415422ceSSean Callanan         return false;
174415422ceSSean Callanan 
175b725142cSPavel Labath       return AssignToMatchType(scalar, value_apint, value->getType());
176c3f0d9f3SDavide Italiano     }
177c3f0d9f3SDavide Italiano 
17808052afaSSean Callanan     lldb::addr_t process_address = ResolveValue(value, module);
1793bfdaa2aSSean Callanan     size_t value_size = m_target_data.getTypeStoreSize(value->getType());
1803bfdaa2aSSean Callanan 
18108052afaSSean Callanan     lldb_private::DataExtractor value_extractor;
18297206d57SZachary Turner     lldb_private::Status extract_error;
18308052afaSSean Callanan 
184b9c1b51eSKate Stone     m_execution_unit.GetMemoryData(value_extractor, process_address,
185b9c1b51eSKate Stone                                    value_size, extract_error);
18608052afaSSean Callanan 
18708052afaSSean Callanan     if (!extract_error.Success())
18808052afaSSean Callanan       return false;
18908052afaSSean Callanan 
190c7bece56SGreg Clayton     lldb::offset_t offset = 0;
191ae6ca2fcSFrederic Riss     if (value_size <= 8) {
19208052afaSSean Callanan       uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
193b725142cSPavel Labath       return AssignToMatchType(scalar, llvm::APInt(64, u64value),
194b725142cSPavel Labath                                value->getType());
1953bfdaa2aSSean Callanan     }
1963bfdaa2aSSean Callanan 
1973bfdaa2aSSean Callanan     return false;
1983bfdaa2aSSean Callanan   }
1993bfdaa2aSSean Callanan 
AssignValue(const Value * value,lldb_private::Scalar scalar,Module & module)200b725142cSPavel Labath   bool AssignValue(const Value *value, lldb_private::Scalar scalar,
201b9c1b51eSKate Stone                    Module &module) {
20208052afaSSean Callanan     lldb::addr_t process_address = ResolveValue(value, module);
20308052afaSSean Callanan 
20408052afaSSean Callanan     if (process_address == LLDB_INVALID_ADDRESS)
20508052afaSSean Callanan       return false;
2063bfdaa2aSSean Callanan 
2073bfdaa2aSSean Callanan     lldb_private::Scalar cast_scalar;
2083bfdaa2aSSean Callanan 
209b725142cSPavel Labath     scalar.MakeUnsigned();
210b725142cSPavel Labath     if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
211b725142cSPavel Labath                            value->getType()))
2123bfdaa2aSSean Callanan       return false;
2133bfdaa2aSSean Callanan 
21408052afaSSean Callanan     size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
2153bfdaa2aSSean Callanan 
21608052afaSSean Callanan     lldb_private::DataBufferHeap buf(value_byte_size, 0);
2173bfdaa2aSSean Callanan 
21897206d57SZachary Turner     lldb_private::Status get_data_error;
21908052afaSSean Callanan 
220b9c1b51eSKate Stone     if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),
221b9c1b51eSKate Stone                                      m_byte_order, get_data_error))
2223bfdaa2aSSean Callanan       return false;
2233bfdaa2aSSean Callanan 
22497206d57SZachary Turner     lldb_private::Status write_error;
2253bfdaa2aSSean Callanan 
226b9c1b51eSKate Stone     m_execution_unit.WriteMemory(process_address, buf.GetBytes(),
227b9c1b51eSKate Stone                                  buf.GetByteSize(), write_error);
2285c9737a5SGreg Clayton 
22908052afaSSean Callanan     return write_error.Success();
2303bfdaa2aSSean Callanan   }
2313bfdaa2aSSean Callanan 
ResolveConstantValue(APInt & value,const Constant * constant)232b9c1b51eSKate Stone   bool ResolveConstantValue(APInt &value, const Constant *constant) {
233b9c1b51eSKate Stone     switch (constant->getValueID()) {
2341582ee68SSean Callanan     default:
2351582ee68SSean Callanan       break;
2367071c5fdSTed Woodward     case Value::FunctionVal:
237b9c1b51eSKate Stone       if (const Function *constant_func = dyn_cast<Function>(constant)) {
2387071c5fdSTed Woodward         lldb_private::ConstString name(constant_func->getName());
239f2128b28SJim Ingham         bool missing_weak = false;
240f2128b28SJim Ingham         lldb::addr_t addr = m_execution_unit.FindSymbol(name, missing_weak);
241f2128b28SJim Ingham         if (addr == LLDB_INVALID_ADDRESS || missing_weak)
2427071c5fdSTed Woodward           return false;
2437071c5fdSTed Woodward         value = APInt(m_target_data.getPointerSizeInBits(), addr);
2447071c5fdSTed Woodward         return true;
2457071c5fdSTed Woodward       }
2467071c5fdSTed Woodward       break;
2471582ee68SSean Callanan     case Value::ConstantIntVal:
248b9c1b51eSKate Stone       if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) {
24994a9a39eSSean Callanan         value = constant_int->getValue();
25094a9a39eSSean Callanan         return true;
2513bfdaa2aSSean Callanan       }
2521582ee68SSean Callanan       break;
2531582ee68SSean Callanan     case Value::ConstantFPVal:
254b9c1b51eSKate Stone       if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) {
25594a9a39eSSean Callanan         value = constant_fp->getValueAPF().bitcastToAPInt();
25694a9a39eSSean Callanan         return true;
2573bfdaa2aSSean Callanan       }
2581582ee68SSean Callanan       break;
2591582ee68SSean Callanan     case Value::ConstantExprVal:
260b9c1b51eSKate Stone       if (const ConstantExpr *constant_expr =
261b9c1b51eSKate Stone               dyn_cast<ConstantExpr>(constant)) {
262b9c1b51eSKate Stone         switch (constant_expr->getOpcode()) {
26380c48c10SSean Callanan         default:
26480c48c10SSean Callanan           return false;
26580c48c10SSean Callanan         case Instruction::IntToPtr:
2662abffe05SSean Callanan         case Instruction::PtrToInt:
26780c48c10SSean Callanan         case Instruction::BitCast:
26894a9a39eSSean Callanan           return ResolveConstantValue(value, constant_expr->getOperand(0));
269b9c1b51eSKate Stone         case Instruction::GetElementPtr: {
27094a9a39eSSean Callanan           ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
27194a9a39eSSean Callanan           ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
27294a9a39eSSean Callanan 
27394a9a39eSSean Callanan           Constant *base = dyn_cast<Constant>(*op_cursor);
27494a9a39eSSean Callanan 
27594a9a39eSSean Callanan           if (!base)
27694a9a39eSSean Callanan             return false;
27794a9a39eSSean Callanan 
27894a9a39eSSean Callanan           if (!ResolveConstantValue(value, base))
27994a9a39eSSean Callanan             return false;
28094a9a39eSSean Callanan 
28194a9a39eSSean Callanan           op_cursor++;
28294a9a39eSSean Callanan 
28394a9a39eSSean Callanan           if (op_cursor == op_end)
28494a9a39eSSean Callanan             return true; // no offset to apply!
28594a9a39eSSean Callanan 
28694a9a39eSSean Callanan           SmallVector<Value *, 8> indices(op_cursor, op_end);
287b9c1b51eSKate Stone           Type *src_elem_ty =
288b9c1b51eSKate Stone               cast<GEPOperator>(constant_expr)->getSourceElementType();
289afb446e8SAndy Yankovsky 
290afb446e8SAndy Yankovsky           // DataLayout::getIndexedOffsetInType assumes the indices are
291afb446e8SAndy Yankovsky           // instances of ConstantInt.
292b9c1b51eSKate Stone           uint64_t offset =
293b9c1b51eSKate Stone               m_target_data.getIndexedOffsetInType(src_elem_ty, indices);
29494a9a39eSSean Callanan 
29594a9a39eSSean Callanan           const bool is_signed = true;
29694a9a39eSSean Callanan           value += APInt(value.getBitWidth(), offset, is_signed);
29794a9a39eSSean Callanan 
29894a9a39eSSean Callanan           return true;
29994a9a39eSSean Callanan         }
30080c48c10SSean Callanan         }
30180c48c10SSean Callanan       }
3021582ee68SSean Callanan       break;
3031582ee68SSean Callanan     case Value::ConstantPointerNullVal:
304b9c1b51eSKate Stone       if (isa<ConstantPointerNull>(constant)) {
3051582ee68SSean Callanan         value = APInt(m_target_data.getPointerSizeInBits(), 0);
3061582ee68SSean Callanan         return true;
3071582ee68SSean Callanan       }
3081582ee68SSean Callanan       break;
3091582ee68SSean Callanan     }
3103bfdaa2aSSean Callanan     return false;
3113bfdaa2aSSean Callanan   }
3123bfdaa2aSSean Callanan 
MakeArgument(const Argument * value,uint64_t address)313b9c1b51eSKate Stone   bool MakeArgument(const Argument *value, uint64_t address) {
3141582ee68SSean Callanan     lldb::addr_t data_address = Malloc(value->getType());
3151582ee68SSean Callanan 
3161582ee68SSean Callanan     if (data_address == LLDB_INVALID_ADDRESS)
3171582ee68SSean Callanan       return false;
3181582ee68SSean Callanan 
31997206d57SZachary Turner     lldb_private::Status write_error;
3201582ee68SSean Callanan 
3217071c5fdSTed Woodward     m_execution_unit.WritePointerToMemory(data_address, address, write_error);
3221582ee68SSean Callanan 
323b9c1b51eSKate Stone     if (!write_error.Success()) {
32497206d57SZachary Turner       lldb_private::Status free_error;
3257071c5fdSTed Woodward       m_execution_unit.Free(data_address, free_error);
3261582ee68SSean Callanan       return false;
3271582ee68SSean Callanan     }
3281582ee68SSean Callanan 
3291582ee68SSean Callanan     m_values[value] = data_address;
3301582ee68SSean Callanan 
331a007a6d8SPavel Labath     lldb_private::Log *log(GetLog(LLDBLog::Expressions));
3321582ee68SSean Callanan 
333b9c1b51eSKate Stone     if (log) {
33463e5fb76SJonas Devlieghere       LLDB_LOGF(log, "Made an allocation for argument %s",
335b9c1b51eSKate Stone                 PrintValue(value).c_str());
33663e5fb76SJonas Devlieghere       LLDB_LOGF(log, "  Data region    : %llx", (unsigned long long)address);
33763e5fb76SJonas Devlieghere       LLDB_LOGF(log, "  Ref region     : %llx",
33863e5fb76SJonas Devlieghere                 (unsigned long long)data_address);
3391582ee68SSean Callanan     }
3401582ee68SSean Callanan 
3411582ee68SSean Callanan     return true;
3421582ee68SSean Callanan   }
3431582ee68SSean Callanan 
ResolveConstant(lldb::addr_t process_address,const Constant * constant)344b9c1b51eSKate Stone   bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) {
34594a9a39eSSean Callanan     APInt resolved_value;
34694a9a39eSSean Callanan 
34794a9a39eSSean Callanan     if (!ResolveConstantValue(resolved_value, constant))
34894a9a39eSSean Callanan       return false;
34994a9a39eSSean Callanan 
35094a9a39eSSean Callanan     size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
3519521ad2aSUlrich Weigand     lldb_private::DataBufferHeap buf(constant_size, 0);
35208052afaSSean Callanan 
35397206d57SZachary Turner     lldb_private::Status get_data_error;
35446fc0066SSean Callanan 
355b9c1b51eSKate Stone     lldb_private::Scalar resolved_scalar(
356b9c1b51eSKate Stone         resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8));
357b9c1b51eSKate Stone     if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),
358b9c1b51eSKate Stone                                          m_byte_order, get_data_error))
3599521ad2aSUlrich Weigand       return false;
36046fc0066SSean Callanan 
36197206d57SZachary Turner     lldb_private::Status write_error;
36208052afaSSean Callanan 
363b9c1b51eSKate Stone     m_execution_unit.WriteMemory(process_address, buf.GetBytes(),
364b9c1b51eSKate Stone                                  buf.GetByteSize(), write_error);
36508052afaSSean Callanan 
36608052afaSSean Callanan     return write_error.Success();
36794a9a39eSSean Callanan   }
36894a9a39eSSean Callanan 
Malloc(size_t size,uint8_t byte_alignment)369b9c1b51eSKate Stone   lldb::addr_t Malloc(size_t size, uint8_t byte_alignment) {
3701582ee68SSean Callanan     lldb::addr_t ret = m_stack_pointer;
37108052afaSSean Callanan 
3721582ee68SSean Callanan     ret -= size;
3731582ee68SSean Callanan     ret -= (ret % byte_alignment);
37408052afaSSean Callanan 
3751582ee68SSean Callanan     if (ret < m_frame_process_address)
37608052afaSSean Callanan       return LLDB_INVALID_ADDRESS;
3771582ee68SSean Callanan 
3781582ee68SSean Callanan     m_stack_pointer = ret;
3791582ee68SSean Callanan     return ret;
38008052afaSSean Callanan   }
38108052afaSSean Callanan 
Malloc(llvm::Type * type)382b9c1b51eSKate Stone   lldb::addr_t Malloc(llvm::Type *type) {
38397206d57SZachary Turner     lldb_private::Status alloc_error;
38408052afaSSean Callanan 
385b9c1b51eSKate Stone     return Malloc(m_target_data.getTypeAllocSize(type),
386b9c1b51eSKate Stone                   m_target_data.getPrefTypeAlignment(type));
38708052afaSSean Callanan   }
38808052afaSSean Callanan 
PrintData(lldb::addr_t addr,llvm::Type * type)389b9c1b51eSKate Stone   std::string PrintData(lldb::addr_t addr, llvm::Type *type) {
39008052afaSSean Callanan     size_t length = m_target_data.getTypeStoreSize(type);
39108052afaSSean Callanan 
39208052afaSSean Callanan     lldb_private::DataBufferHeap buf(length, 0);
39308052afaSSean Callanan 
39497206d57SZachary Turner     lldb_private::Status read_error;
39508052afaSSean Callanan 
3967071c5fdSTed Woodward     m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error);
39708052afaSSean Callanan 
39808052afaSSean Callanan     if (!read_error.Success())
39908052afaSSean Callanan       return std::string("<couldn't read data>");
40008052afaSSean Callanan 
40108052afaSSean Callanan     lldb_private::StreamString ss;
40208052afaSSean Callanan 
403b9c1b51eSKate Stone     for (size_t i = 0; i < length; i++) {
40408052afaSSean Callanan       if ((!(i & 0xf)) && i)
40508052afaSSean Callanan         ss.Printf("%02hhx - ", buf.GetBytes()[i]);
40608052afaSSean Callanan       else
40708052afaSSean Callanan         ss.Printf("%02hhx ", buf.GetBytes()[i]);
40808052afaSSean Callanan     }
40908052afaSSean Callanan 
410adcd0268SBenjamin Kramer     return std::string(ss.GetString());
41108052afaSSean Callanan   }
41208052afaSSean Callanan 
ResolveValue(const Value * value,Module & module)413b9c1b51eSKate Stone   lldb::addr_t ResolveValue(const Value *value, Module &module) {
4143bfdaa2aSSean Callanan     ValueMap::iterator i = m_values.find(value);
4153bfdaa2aSSean Callanan 
4163bfdaa2aSSean Callanan     if (i != m_values.end())
4173bfdaa2aSSean Callanan       return i->second;
4183bfdaa2aSSean Callanan 
4191582ee68SSean Callanan     // Fall back and allocate space [allocation type Alloca]
4201582ee68SSean Callanan 
4211582ee68SSean Callanan     lldb::addr_t data_address = Malloc(value->getType());
4221582ee68SSean Callanan 
423b9c1b51eSKate Stone     if (const Constant *constant = dyn_cast<Constant>(value)) {
424b9c1b51eSKate Stone       if (!ResolveConstant(data_address, constant)) {
42597206d57SZachary Turner         lldb_private::Status free_error;
4267071c5fdSTed Woodward         m_execution_unit.Free(data_address, free_error);
4271582ee68SSean Callanan         return LLDB_INVALID_ADDRESS;
4281582ee68SSean Callanan       }
4291582ee68SSean Callanan     }
4301582ee68SSean Callanan 
4311582ee68SSean Callanan     m_values[value] = data_address;
4321582ee68SSean Callanan     return data_address;
4333bfdaa2aSSean Callanan   }
4343bfdaa2aSSean Callanan };
4353bfdaa2aSSean Callanan 
436b9c1b51eSKate Stone static const char *unsupported_opcode_error =
437b9c1b51eSKate Stone     "Interpreter doesn't handle one of the expression's opcodes";
438b9c1b51eSKate Stone static const char *unsupported_operand_error =
439b9c1b51eSKate Stone     "Interpreter doesn't handle one of the expression's operands";
440b9c1b51eSKate Stone static const char *interpreter_internal_error =
441b9c1b51eSKate Stone     "Interpreter encountered an internal error";
442b9c1b51eSKate Stone static const char *bad_value_error =
443b9c1b51eSKate Stone     "Interpreter couldn't resolve a value during execution";
444b9c1b51eSKate Stone static const char *memory_allocation_error =
445b9c1b51eSKate Stone     "Interpreter couldn't allocate memory";
446175a0d04SSean Callanan static const char *memory_write_error = "Interpreter couldn't write to memory";
447175a0d04SSean Callanan static const char *memory_read_error = "Interpreter couldn't read from memory";
448175a0d04SSean Callanan static const char *infinite_loop_error = "Interpreter ran for too many cycles";
449b9c1b51eSKate Stone static const char *too_many_functions_error =
450b9c1b51eSKate Stone     "Interpreter doesn't handle modules with multiple function bodies.";
451175a0d04SSean Callanan 
CanResolveConstant(llvm::Constant * constant)452b9c1b51eSKate Stone static bool CanResolveConstant(llvm::Constant *constant) {
453b9c1b51eSKate Stone   switch (constant->getValueID()) {
4548c62daf2SSean Callanan   default:
4558c62daf2SSean Callanan     return false;
4568c62daf2SSean Callanan   case Value::ConstantIntVal:
4578c62daf2SSean Callanan   case Value::ConstantFPVal:
4587071c5fdSTed Woodward   case Value::FunctionVal:
4598c62daf2SSean Callanan     return true;
4608c62daf2SSean Callanan   case Value::ConstantExprVal:
461b9c1b51eSKate Stone     if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
462b9c1b51eSKate Stone       switch (constant_expr->getOpcode()) {
4638c62daf2SSean Callanan       default:
4648c62daf2SSean Callanan         return false;
4658c62daf2SSean Callanan       case Instruction::IntToPtr:
4668c62daf2SSean Callanan       case Instruction::PtrToInt:
4678c62daf2SSean Callanan       case Instruction::BitCast:
4688c62daf2SSean Callanan         return CanResolveConstant(constant_expr->getOperand(0));
469b9c1b51eSKate Stone       case Instruction::GetElementPtr: {
470afb446e8SAndy Yankovsky         // Check that the base can be constant-resolved.
4718c62daf2SSean Callanan         ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
4728c62daf2SSean Callanan         Constant *base = dyn_cast<Constant>(*op_cursor);
473afb446e8SAndy Yankovsky         if (!base || !CanResolveConstant(base))
4748c62daf2SSean Callanan           return false;
4758c62daf2SSean Callanan 
476afb446e8SAndy Yankovsky         // Check that all other operands are just ConstantInt.
477afb446e8SAndy Yankovsky         for (Value *op : make_range(constant_expr->op_begin() + 1,
478afb446e8SAndy Yankovsky                                     constant_expr->op_end())) {
479afb446e8SAndy Yankovsky           ConstantInt *constant_int = dyn_cast<ConstantInt>(op);
480afb446e8SAndy Yankovsky           if (!constant_int)
481afb446e8SAndy Yankovsky             return false;
482afb446e8SAndy Yankovsky         }
483afb446e8SAndy Yankovsky         return true;
4848c62daf2SSean Callanan       }
4858c62daf2SSean Callanan       }
4868c62daf2SSean Callanan     } else {
4878c62daf2SSean Callanan       return false;
4888c62daf2SSean Callanan     }
4898c62daf2SSean Callanan   case Value::ConstantPointerNullVal:
4908c62daf2SSean Callanan     return true;
4918c62daf2SSean Callanan   }
4928c62daf2SSean Callanan }
4938c62daf2SSean Callanan 
CanInterpret(llvm::Module & module,llvm::Function & function,lldb_private::Status & error,const bool support_function_calls)494b9c1b51eSKate Stone bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
49597206d57SZachary Turner                                  lldb_private::Status &error,
496b9c1b51eSKate Stone                                  const bool support_function_calls) {
497a007a6d8SPavel Labath   lldb_private::Log *log(GetLog(LLDBLog::Expressions));
4983bfdaa2aSSean Callanan 
49985fc8761SSean Callanan   bool saw_function_with_body = false;
500af4adb07SRaphael Isemann   for (Function &f : module) {
501af4adb07SRaphael Isemann     if (f.begin() != f.end()) {
502b9c1b51eSKate Stone       if (saw_function_with_body) {
50363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "More than one function in the module has a body");
5043f998107SAdrian McCarthy         error.SetErrorToGenericError();
5053f998107SAdrian McCarthy         error.SetErrorString(too_many_functions_error);
50685fc8761SSean Callanan         return false;
5073f998107SAdrian McCarthy       }
50885fc8761SSean Callanan       saw_function_with_body = true;
50985fc8761SSean Callanan     }
51085fc8761SSean Callanan   }
51185fc8761SSean Callanan 
512af4adb07SRaphael Isemann   for (BasicBlock &bb : function) {
513af4adb07SRaphael Isemann     for (Instruction &ii : bb) {
514af4adb07SRaphael Isemann       switch (ii.getOpcode()) {
515b9c1b51eSKate Stone       default: {
516af4adb07SRaphael Isemann         LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&ii).c_str());
51744342735SSean Callanan         error.SetErrorToGenericError();
51844342735SSean Callanan         error.SetErrorString(unsupported_opcode_error);
5193bfdaa2aSSean Callanan         return false;
5203bfdaa2aSSean Callanan       }
5213bfdaa2aSSean Callanan       case Instruction::Add:
5223bfdaa2aSSean Callanan       case Instruction::Alloca:
5233bfdaa2aSSean Callanan       case Instruction::BitCast:
5243bfdaa2aSSean Callanan       case Instruction::Br:
5253fe71581SMarianne Mailhot-Sarrasin       case Instruction::PHI:
526576a4374SSean Callanan         break;
527b9c1b51eSKate Stone       case Instruction::Call: {
528af4adb07SRaphael Isemann         CallInst *call_inst = dyn_cast<CallInst>(&ii);
529576a4374SSean Callanan 
530b9c1b51eSKate Stone         if (!call_inst) {
531576a4374SSean Callanan           error.SetErrorToGenericError();
532576a4374SSean Callanan           error.SetErrorString(interpreter_internal_error);
533576a4374SSean Callanan           return false;
534576a4374SSean Callanan         }
535576a4374SSean Callanan 
536b9c1b51eSKate Stone         if (!CanIgnoreCall(call_inst) && !support_function_calls) {
53763e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported instruction: %s",
538af4adb07SRaphael Isemann                     PrintValue(&ii).c_str());
539576a4374SSean Callanan           error.SetErrorToGenericError();
540576a4374SSean Callanan           error.SetErrorString(unsupported_opcode_error);
541576a4374SSean Callanan           return false;
542576a4374SSean Callanan         }
543b9c1b51eSKate Stone       } break;
5443bfdaa2aSSean Callanan       case Instruction::GetElementPtr:
5453bfdaa2aSSean Callanan         break;
546b9c1b51eSKate Stone       case Instruction::ICmp: {
547af4adb07SRaphael Isemann         ICmpInst *icmp_inst = dyn_cast<ICmpInst>(&ii);
5483bfdaa2aSSean Callanan 
549b9c1b51eSKate Stone         if (!icmp_inst) {
55044342735SSean Callanan           error.SetErrorToGenericError();
55144342735SSean Callanan           error.SetErrorString(interpreter_internal_error);
5523bfdaa2aSSean Callanan           return false;
553175a0d04SSean Callanan         }
5543bfdaa2aSSean Callanan 
555b9c1b51eSKate Stone         switch (icmp_inst->getPredicate()) {
556b9c1b51eSKate Stone         default: {
55763e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported ICmp predicate: %s",
558af4adb07SRaphael Isemann                     PrintValue(&ii).c_str());
559175a0d04SSean Callanan 
56044342735SSean Callanan           error.SetErrorToGenericError();
56144342735SSean Callanan           error.SetErrorString(unsupported_opcode_error);
5623bfdaa2aSSean Callanan           return false;
5633bfdaa2aSSean Callanan         }
5643bfdaa2aSSean Callanan         case CmpInst::ICMP_EQ:
5653bfdaa2aSSean Callanan         case CmpInst::ICMP_NE:
5663bfdaa2aSSean Callanan         case CmpInst::ICMP_UGT:
5673bfdaa2aSSean Callanan         case CmpInst::ICMP_UGE:
5683bfdaa2aSSean Callanan         case CmpInst::ICMP_ULT:
5693bfdaa2aSSean Callanan         case CmpInst::ICMP_ULE:
5703bfdaa2aSSean Callanan         case CmpInst::ICMP_SGT:
5713bfdaa2aSSean Callanan         case CmpInst::ICMP_SGE:
5723bfdaa2aSSean Callanan         case CmpInst::ICMP_SLT:
5733bfdaa2aSSean Callanan         case CmpInst::ICMP_SLE:
5743bfdaa2aSSean Callanan           break;
5753bfdaa2aSSean Callanan         }
576b9c1b51eSKate Stone       } break;
577087f437bSSean Callanan       case Instruction::And:
578087f437bSSean Callanan       case Instruction::AShr:
57980c48c10SSean Callanan       case Instruction::IntToPtr:
5802abffe05SSean Callanan       case Instruction::PtrToInt:
5813bfdaa2aSSean Callanan       case Instruction::Load:
582087f437bSSean Callanan       case Instruction::LShr:
5833bfdaa2aSSean Callanan       case Instruction::Mul:
584087f437bSSean Callanan       case Instruction::Or:
5853bfdaa2aSSean Callanan       case Instruction::Ret:
5863bfdaa2aSSean Callanan       case Instruction::SDiv:
587415422ceSSean Callanan       case Instruction::SExt:
588087f437bSSean Callanan       case Instruction::Shl:
589f466a6edSSean Callanan       case Instruction::SRem:
5903bfdaa2aSSean Callanan       case Instruction::Store:
5913bfdaa2aSSean Callanan       case Instruction::Sub:
5928c46bacaSSean Callanan       case Instruction::Trunc:
5933bfdaa2aSSean Callanan       case Instruction::UDiv:
594f466a6edSSean Callanan       case Instruction::URem:
595087f437bSSean Callanan       case Instruction::Xor:
5961ef77434SSean Callanan       case Instruction::ZExt:
5973bfdaa2aSSean Callanan         break;
5983bfdaa2aSSean Callanan       }
5993fa3e65dSSean Callanan 
600af4adb07SRaphael Isemann       for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
601af4adb07SRaphael Isemann         Value *operand = ii.getOperand(oi);
6023fa3e65dSSean Callanan         Type *operand_type = operand->getType();
6033fa3e65dSSean Callanan 
604d405d279SDavide Italiano         switch (operand_type->getTypeID()) {
605d405d279SDavide Italiano         default:
606d405d279SDavide Italiano           break;
6072dea3f12SChristopher Tetreault         case Type::FixedVectorTyID:
6082dea3f12SChristopher Tetreault         case Type::ScalableVectorTyID: {
60963e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported operand type: %s",
610b9c1b51eSKate Stone                     PrintType(operand_type).c_str());
6113fa3e65dSSean Callanan           error.SetErrorString(unsupported_operand_error);
6123fa3e65dSSean Callanan           return false;
613d405d279SDavide Italiano         }
614d405d279SDavide Italiano         }
6158c62daf2SSean Callanan 
6165f6789efSDavide Italiano         // The IR interpreter currently doesn't know about
6175f6789efSDavide Italiano         // 128-bit integers. As they're not that frequent,
6185f6789efSDavide Italiano         // we can just fall back to the JIT rather than
6195f6789efSDavide Italiano         // choking.
6205f6789efSDavide Italiano         if (operand_type->getPrimitiveSizeInBits() > 64) {
62163e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Unsupported operand type: %s",
6225f6789efSDavide Italiano                     PrintType(operand_type).c_str());
6235f6789efSDavide Italiano           error.SetErrorString(unsupported_operand_error);
6245f6789efSDavide Italiano           return false;
6255f6789efSDavide Italiano         }
6265f6789efSDavide Italiano 
627d405d279SDavide Italiano         if (Constant *constant = llvm::dyn_cast<Constant>(operand)) {
628b9c1b51eSKate Stone           if (!CanResolveConstant(constant)) {
62963e5fb76SJonas Devlieghere             LLDB_LOGF(log, "Unsupported constant: %s",
630b9c1b51eSKate Stone                       PrintValue(constant).c_str());
6318c62daf2SSean Callanan             error.SetErrorString(unsupported_operand_error);
6328c62daf2SSean Callanan             return false;
6338c62daf2SSean Callanan           }
6348c62daf2SSean Callanan         }
6353fa3e65dSSean Callanan       }
6363fa3e65dSSean Callanan     }
6373fa3e65dSSean Callanan   }
6383bfdaa2aSSean Callanan 
6393f998107SAdrian McCarthy   return true;
6403f998107SAdrian McCarthy }
64114cb2aaaSSean Callanan 
Interpret(llvm::Module & module,llvm::Function & function,llvm::ArrayRef<lldb::addr_t> args,lldb_private::IRExecutionUnit & execution_unit,lldb_private::Status & error,lldb::addr_t stack_frame_bottom,lldb::addr_t stack_frame_top,lldb_private::ExecutionContext & exe_ctx)642b9c1b51eSKate Stone bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
6431582ee68SSean Callanan                               llvm::ArrayRef<lldb::addr_t> args,
6447071c5fdSTed Woodward                               lldb_private::IRExecutionUnit &execution_unit,
64597206d57SZachary Turner                               lldb_private::Status &error,
646df56540aSSean Callanan                               lldb::addr_t stack_frame_bottom,
64790ff7911SEwan Crawford                               lldb::addr_t stack_frame_top,
648b9c1b51eSKate Stone                               lldb_private::ExecutionContext &exe_ctx) {
649a007a6d8SPavel Labath   lldb_private::Log *log(GetLog(LLDBLog::Expressions));
65014cb2aaaSSean Callanan 
651b9c1b51eSKate Stone   if (log) {
6521582ee68SSean Callanan     std::string s;
6531582ee68SSean Callanan     raw_string_ostream oss(s);
6541582ee68SSean Callanan 
655248a1305SKonrad Kleine     module.print(oss, nullptr);
6561582ee68SSean Callanan 
6571582ee68SSean Callanan     oss.flush();
6581582ee68SSean Callanan 
65963e5fb76SJonas Devlieghere     LLDB_LOGF(log, "Module as passed in to IRInterpreter::Interpret: \n\"%s\"",
660b9c1b51eSKate Stone               s.c_str());
6611582ee68SSean Callanan   }
6621582ee68SSean Callanan 
66314cb2aaaSSean Callanan   DataLayout data_layout(&module);
66414cb2aaaSSean Callanan 
665b9c1b51eSKate Stone   InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom,
666b9c1b51eSKate Stone                               stack_frame_top);
66714cb2aaaSSean Callanan 
668b9c1b51eSKate Stone   if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS) {
6691582ee68SSean Callanan     error.SetErrorString("Couldn't allocate stack frame");
6701582ee68SSean Callanan   }
6711582ee68SSean Callanan 
6721582ee68SSean Callanan   int arg_index = 0;
6731582ee68SSean Callanan 
674b9c1b51eSKate Stone   for (llvm::Function::arg_iterator ai = function.arg_begin(),
675b9c1b51eSKate Stone                                     ae = function.arg_end();
676b9c1b51eSKate Stone        ai != ae; ++ai, ++arg_index) {
677b9c1b51eSKate Stone     if (args.size() <= static_cast<size_t>(arg_index)) {
6781582ee68SSean Callanan       error.SetErrorString("Not enough arguments passed in to function");
6791582ee68SSean Callanan       return false;
6801582ee68SSean Callanan     }
6811582ee68SSean Callanan 
6821582ee68SSean Callanan     lldb::addr_t ptr = args[arg_index];
6831582ee68SSean Callanan 
68433e43ca6SDuncan P. N. Exon Smith     frame.MakeArgument(&*ai, ptr);
6851582ee68SSean Callanan   }
6861582ee68SSean Callanan 
68714cb2aaaSSean Callanan   uint32_t num_insts = 0;
68814cb2aaaSSean Callanan 
68933e43ca6SDuncan P. N. Exon Smith   frame.Jump(&function.front());
69014cb2aaaSSean Callanan 
691b9c1b51eSKate Stone   while (frame.m_ii != frame.m_ie && (++num_insts < 4096)) {
69233e43ca6SDuncan P. N. Exon Smith     const Instruction *inst = &*frame.m_ii;
69314cb2aaaSSean Callanan 
69463e5fb76SJonas Devlieghere     LLDB_LOGF(log, "Interpreting %s", PrintValue(inst).c_str());
69514cb2aaaSSean Callanan 
696b9c1b51eSKate Stone     switch (inst->getOpcode()) {
69714cb2aaaSSean Callanan     default:
69814cb2aaaSSean Callanan       break;
699576a4374SSean Callanan 
70014cb2aaaSSean Callanan     case Instruction::Add:
70114cb2aaaSSean Callanan     case Instruction::Sub:
70214cb2aaaSSean Callanan     case Instruction::Mul:
70314cb2aaaSSean Callanan     case Instruction::SDiv:
70414cb2aaaSSean Callanan     case Instruction::UDiv:
70514cb2aaaSSean Callanan     case Instruction::SRem:
70614cb2aaaSSean Callanan     case Instruction::URem:
70714cb2aaaSSean Callanan     case Instruction::Shl:
70814cb2aaaSSean Callanan     case Instruction::LShr:
70914cb2aaaSSean Callanan     case Instruction::AShr:
71014cb2aaaSSean Callanan     case Instruction::And:
71114cb2aaaSSean Callanan     case Instruction::Or:
712b9c1b51eSKate Stone     case Instruction::Xor: {
71314cb2aaaSSean Callanan       const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
71414cb2aaaSSean Callanan 
715b9c1b51eSKate Stone       if (!bin_op) {
71663e5fb76SJonas Devlieghere         LLDB_LOGF(
71763e5fb76SJonas Devlieghere             log,
718b9c1b51eSKate Stone             "getOpcode() returns %s, but instruction is not a BinaryOperator",
719b9c1b51eSKate Stone             inst->getOpcodeName());
72014cb2aaaSSean Callanan         error.SetErrorToGenericError();
72114cb2aaaSSean Callanan         error.SetErrorString(interpreter_internal_error);
72214cb2aaaSSean Callanan         return false;
72314cb2aaaSSean Callanan       }
72414cb2aaaSSean Callanan 
72514cb2aaaSSean Callanan       Value *lhs = inst->getOperand(0);
72614cb2aaaSSean Callanan       Value *rhs = inst->getOperand(1);
72714cb2aaaSSean Callanan 
72814cb2aaaSSean Callanan       lldb_private::Scalar L;
72914cb2aaaSSean Callanan       lldb_private::Scalar R;
73014cb2aaaSSean Callanan 
731b9c1b51eSKate Stone       if (!frame.EvaluateValue(L, lhs, module)) {
73263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
73314cb2aaaSSean Callanan         error.SetErrorToGenericError();
73414cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
73514cb2aaaSSean Callanan         return false;
73614cb2aaaSSean Callanan       }
73714cb2aaaSSean Callanan 
738b9c1b51eSKate Stone       if (!frame.EvaluateValue(R, rhs, module)) {
73963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
74014cb2aaaSSean Callanan         error.SetErrorToGenericError();
74114cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
74214cb2aaaSSean Callanan         return false;
74314cb2aaaSSean Callanan       }
74414cb2aaaSSean Callanan 
74514cb2aaaSSean Callanan       lldb_private::Scalar result;
74614cb2aaaSSean Callanan 
747b9c1b51eSKate Stone       switch (inst->getOpcode()) {
74814cb2aaaSSean Callanan       default:
74914cb2aaaSSean Callanan         break;
75014cb2aaaSSean Callanan       case Instruction::Add:
75114cb2aaaSSean Callanan         result = L + R;
75214cb2aaaSSean Callanan         break;
75314cb2aaaSSean Callanan       case Instruction::Mul:
75414cb2aaaSSean Callanan         result = L * R;
75514cb2aaaSSean Callanan         break;
75614cb2aaaSSean Callanan       case Instruction::Sub:
75714cb2aaaSSean Callanan         result = L - R;
75814cb2aaaSSean Callanan         break;
75914cb2aaaSSean Callanan       case Instruction::SDiv:
7600b342b6dSSean Callanan         L.MakeSigned();
7610b342b6dSSean Callanan         R.MakeSigned();
76214cb2aaaSSean Callanan         result = L / R;
76314cb2aaaSSean Callanan         break;
76414cb2aaaSSean Callanan       case Instruction::UDiv:
7659521ad2aSUlrich Weigand         L.MakeUnsigned();
7669521ad2aSUlrich Weigand         R.MakeUnsigned();
7679521ad2aSUlrich Weigand         result = L / R;
76814cb2aaaSSean Callanan         break;
76914cb2aaaSSean Callanan       case Instruction::SRem:
7700b342b6dSSean Callanan         L.MakeSigned();
7710b342b6dSSean Callanan         R.MakeSigned();
77214cb2aaaSSean Callanan         result = L % R;
77314cb2aaaSSean Callanan         break;
77414cb2aaaSSean Callanan       case Instruction::URem:
7759521ad2aSUlrich Weigand         L.MakeUnsigned();
7769521ad2aSUlrich Weigand         R.MakeUnsigned();
7779521ad2aSUlrich Weigand         result = L % R;
77814cb2aaaSSean Callanan         break;
77914cb2aaaSSean Callanan       case Instruction::Shl:
78014cb2aaaSSean Callanan         result = L << R;
78114cb2aaaSSean Callanan         break;
78214cb2aaaSSean Callanan       case Instruction::AShr:
78314cb2aaaSSean Callanan         result = L >> R;
78414cb2aaaSSean Callanan         break;
78514cb2aaaSSean Callanan       case Instruction::LShr:
78614cb2aaaSSean Callanan         result = L;
78714cb2aaaSSean Callanan         result.ShiftRightLogical(R);
78814cb2aaaSSean Callanan         break;
78914cb2aaaSSean Callanan       case Instruction::And:
79014cb2aaaSSean Callanan         result = L & R;
79114cb2aaaSSean Callanan         break;
79214cb2aaaSSean Callanan       case Instruction::Or:
79314cb2aaaSSean Callanan         result = L | R;
79414cb2aaaSSean Callanan         break;
79514cb2aaaSSean Callanan       case Instruction::Xor:
79614cb2aaaSSean Callanan         result = L ^ R;
79714cb2aaaSSean Callanan         break;
79814cb2aaaSSean Callanan       }
79914cb2aaaSSean Callanan 
80014cb2aaaSSean Callanan       frame.AssignValue(inst, result, module);
80114cb2aaaSSean Callanan 
802b9c1b51eSKate Stone       if (log) {
80363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
80463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  L : %s", frame.SummarizeValue(lhs).c_str());
80563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : %s", frame.SummarizeValue(rhs).c_str());
80663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  = : %s", frame.SummarizeValue(inst).c_str());
80714cb2aaaSSean Callanan       }
808b9c1b51eSKate Stone     } break;
809b9c1b51eSKate Stone     case Instruction::Alloca: {
810f18370feSRaphael Isemann       const AllocaInst *alloca_inst = cast<AllocaInst>(inst);
81114cb2aaaSSean Callanan 
812b9c1b51eSKate Stone       if (alloca_inst->isArrayAllocation()) {
81363e5fb76SJonas Devlieghere         LLDB_LOGF(log,
814b9c1b51eSKate Stone                   "AllocaInsts are not handled if isArrayAllocation() is true");
81514cb2aaaSSean Callanan         error.SetErrorToGenericError();
81614cb2aaaSSean Callanan         error.SetErrorString(unsupported_opcode_error);
81714cb2aaaSSean Callanan         return false;
81814cb2aaaSSean Callanan       }
81914cb2aaaSSean Callanan 
82014cb2aaaSSean Callanan       // The semantics of Alloca are:
821b9c1b51eSKate Stone       //   Create a region R of virtual memory of type T, backed by a data
822b9c1b51eSKate Stone       //   buffer
823b9c1b51eSKate Stone       //   Create a region P of virtual memory of type T*, backed by a data
824b9c1b51eSKate Stone       //   buffer
82514cb2aaaSSean Callanan       //   Write the virtual address of R into P
82614cb2aaaSSean Callanan 
82714cb2aaaSSean Callanan       Type *T = alloca_inst->getAllocatedType();
82814cb2aaaSSean Callanan       Type *Tptr = alloca_inst->getType();
82914cb2aaaSSean Callanan 
83014cb2aaaSSean Callanan       lldb::addr_t R = frame.Malloc(T);
83114cb2aaaSSean Callanan 
832b9c1b51eSKate Stone       if (R == LLDB_INVALID_ADDRESS) {
83363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst");
83414cb2aaaSSean Callanan         error.SetErrorToGenericError();
83514cb2aaaSSean Callanan         error.SetErrorString(memory_allocation_error);
83614cb2aaaSSean Callanan         return false;
83714cb2aaaSSean Callanan       }
83814cb2aaaSSean Callanan 
83914cb2aaaSSean Callanan       lldb::addr_t P = frame.Malloc(Tptr);
84014cb2aaaSSean Callanan 
841b9c1b51eSKate Stone       if (P == LLDB_INVALID_ADDRESS) {
84263e5fb76SJonas Devlieghere         LLDB_LOGF(log,
84363e5fb76SJonas Devlieghere                   "Couldn't allocate the result pointer for an AllocaInst");
84414cb2aaaSSean Callanan         error.SetErrorToGenericError();
84514cb2aaaSSean Callanan         error.SetErrorString(memory_allocation_error);
84614cb2aaaSSean Callanan         return false;
84714cb2aaaSSean Callanan       }
84814cb2aaaSSean Callanan 
84997206d57SZachary Turner       lldb_private::Status write_error;
85014cb2aaaSSean Callanan 
8517071c5fdSTed Woodward       execution_unit.WritePointerToMemory(P, R, write_error);
85214cb2aaaSSean Callanan 
853b9c1b51eSKate Stone       if (!write_error.Success()) {
85463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't write the result pointer for an AllocaInst");
85514cb2aaaSSean Callanan         error.SetErrorToGenericError();
85614cb2aaaSSean Callanan         error.SetErrorString(memory_write_error);
85797206d57SZachary Turner         lldb_private::Status free_error;
8587071c5fdSTed Woodward         execution_unit.Free(P, free_error);
8597071c5fdSTed Woodward         execution_unit.Free(R, free_error);
86014cb2aaaSSean Callanan         return false;
86114cb2aaaSSean Callanan       }
86214cb2aaaSSean Callanan 
86314cb2aaaSSean Callanan       frame.m_values[alloca_inst] = P;
86414cb2aaaSSean Callanan 
865b9c1b51eSKate Stone       if (log) {
86663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted an AllocaInst");
86763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
86863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
86914cb2aaaSSean Callanan       }
870b9c1b51eSKate Stone     } break;
87114cb2aaaSSean Callanan     case Instruction::BitCast:
872b9c1b51eSKate Stone     case Instruction::ZExt: {
873f18370feSRaphael Isemann       const CastInst *cast_inst = cast<CastInst>(inst);
87414cb2aaaSSean Callanan 
87514cb2aaaSSean Callanan       Value *source = cast_inst->getOperand(0);
87614cb2aaaSSean Callanan 
87714cb2aaaSSean Callanan       lldb_private::Scalar S;
87814cb2aaaSSean Callanan 
879b9c1b51eSKate Stone       if (!frame.EvaluateValue(S, source, module)) {
88063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
88114cb2aaaSSean Callanan         error.SetErrorToGenericError();
88214cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
88314cb2aaaSSean Callanan         return false;
88414cb2aaaSSean Callanan       }
88514cb2aaaSSean Callanan 
88614cb2aaaSSean Callanan       frame.AssignValue(inst, S, module);
887b9c1b51eSKate Stone     } break;
888b9c1b51eSKate Stone     case Instruction::SExt: {
889f18370feSRaphael Isemann       const CastInst *cast_inst = cast<CastInst>(inst);
890415422ceSSean Callanan 
891415422ceSSean Callanan       Value *source = cast_inst->getOperand(0);
892415422ceSSean Callanan 
893415422ceSSean Callanan       lldb_private::Scalar S;
894415422ceSSean Callanan 
895b9c1b51eSKate Stone       if (!frame.EvaluateValue(S, source, module)) {
89663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
897415422ceSSean Callanan         error.SetErrorToGenericError();
898415422ceSSean Callanan         error.SetErrorString(bad_value_error);
899415422ceSSean Callanan         return false;
900415422ceSSean Callanan       }
901415422ceSSean Callanan 
902415422ceSSean Callanan       S.MakeSigned();
903415422ceSSean Callanan 
904415422ceSSean Callanan       lldb_private::Scalar S_signextend(S.SLongLong());
905415422ceSSean Callanan 
906415422ceSSean Callanan       frame.AssignValue(inst, S_signextend, module);
907b9c1b51eSKate Stone     } break;
908b9c1b51eSKate Stone     case Instruction::Br: {
909f18370feSRaphael Isemann       const BranchInst *br_inst = cast<BranchInst>(inst);
91014cb2aaaSSean Callanan 
911b9c1b51eSKate Stone       if (br_inst->isConditional()) {
91214cb2aaaSSean Callanan         Value *condition = br_inst->getCondition();
91314cb2aaaSSean Callanan 
91414cb2aaaSSean Callanan         lldb_private::Scalar C;
91514cb2aaaSSean Callanan 
916b9c1b51eSKate Stone         if (!frame.EvaluateValue(C, condition, module)) {
91763e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str());
91814cb2aaaSSean Callanan           error.SetErrorToGenericError();
91914cb2aaaSSean Callanan           error.SetErrorString(bad_value_error);
92014cb2aaaSSean Callanan           return false;
92114cb2aaaSSean Callanan         }
92214cb2aaaSSean Callanan 
9239521ad2aSUlrich Weigand         if (!C.IsZero())
92414cb2aaaSSean Callanan           frame.Jump(br_inst->getSuccessor(0));
92514cb2aaaSSean Callanan         else
92614cb2aaaSSean Callanan           frame.Jump(br_inst->getSuccessor(1));
92714cb2aaaSSean Callanan 
928b9c1b51eSKate Stone         if (log) {
92963e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Interpreted a BrInst with a condition");
93063e5fb76SJonas Devlieghere           LLDB_LOGF(log, "  cond : %s",
93163e5fb76SJonas Devlieghere                     frame.SummarizeValue(condition).c_str());
93214cb2aaaSSean Callanan         }
933b9c1b51eSKate Stone       } else {
93414cb2aaaSSean Callanan         frame.Jump(br_inst->getSuccessor(0));
93514cb2aaaSSean Callanan 
936b9c1b51eSKate Stone         if (log) {
93763e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Interpreted a BrInst with no condition");
93814cb2aaaSSean Callanan         }
93914cb2aaaSSean Callanan       }
94014cb2aaaSSean Callanan     }
94114cb2aaaSSean Callanan       continue;
942b9c1b51eSKate Stone     case Instruction::PHI: {
943f18370feSRaphael Isemann       const PHINode *phi_inst = cast<PHINode>(inst);
944b9c1b51eSKate Stone       if (!frame.m_prev_bb) {
94563e5fb76SJonas Devlieghere         LLDB_LOGF(log,
94663e5fb76SJonas Devlieghere                   "Encountered PHI node without having jumped from another "
947b9c1b51eSKate Stone                   "basic block");
9483fe71581SMarianne Mailhot-Sarrasin         error.SetErrorToGenericError();
9493fe71581SMarianne Mailhot-Sarrasin         error.SetErrorString(interpreter_internal_error);
9503fe71581SMarianne Mailhot-Sarrasin         return false;
9513fe71581SMarianne Mailhot-Sarrasin       }
9523fe71581SMarianne Mailhot-Sarrasin 
9533fe71581SMarianne Mailhot-Sarrasin       Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb);
9543fe71581SMarianne Mailhot-Sarrasin       lldb_private::Scalar result;
955b9c1b51eSKate Stone       if (!frame.EvaluateValue(result, value, module)) {
95663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str());
9573fe71581SMarianne Mailhot-Sarrasin         error.SetErrorToGenericError();
9583fe71581SMarianne Mailhot-Sarrasin         error.SetErrorString(bad_value_error);
9593fe71581SMarianne Mailhot-Sarrasin         return false;
9603fe71581SMarianne Mailhot-Sarrasin       }
9613fe71581SMarianne Mailhot-Sarrasin       frame.AssignValue(inst, result, module);
9623fe71581SMarianne Mailhot-Sarrasin 
963b9c1b51eSKate Stone       if (log) {
96463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
96563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Incoming value : %s",
966b9c1b51eSKate Stone                   frame.SummarizeValue(value).c_str());
9673fe71581SMarianne Mailhot-Sarrasin       }
968b9c1b51eSKate Stone     } break;
969b9c1b51eSKate Stone     case Instruction::GetElementPtr: {
970f18370feSRaphael Isemann       const GetElementPtrInst *gep_inst = cast<GetElementPtrInst>(inst);
97114cb2aaaSSean Callanan 
97214cb2aaaSSean Callanan       const Value *pointer_operand = gep_inst->getPointerOperand();
973d05b8992SEduard Burtescu       Type *src_elem_ty = gep_inst->getSourceElementType();
97414cb2aaaSSean Callanan 
97514cb2aaaSSean Callanan       lldb_private::Scalar P;
97614cb2aaaSSean Callanan 
977b9c1b51eSKate Stone       if (!frame.EvaluateValue(P, pointer_operand, module)) {
97863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s",
979b9c1b51eSKate Stone                   PrintValue(pointer_operand).c_str());
98014cb2aaaSSean Callanan         error.SetErrorToGenericError();
98114cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
98214cb2aaaSSean Callanan         return false;
98314cb2aaaSSean Callanan       }
98414cb2aaaSSean Callanan 
98514cb2aaaSSean Callanan       typedef SmallVector<Value *, 8> IndexVector;
98614cb2aaaSSean Callanan       typedef IndexVector::iterator IndexIterator;
98714cb2aaaSSean Callanan 
98814cb2aaaSSean Callanan       SmallVector<Value *, 8> indices(gep_inst->idx_begin(),
98914cb2aaaSSean Callanan                                       gep_inst->idx_end());
99014cb2aaaSSean Callanan 
99114cb2aaaSSean Callanan       SmallVector<Value *, 8> const_indices;
99214cb2aaaSSean Callanan 
993b9c1b51eSKate Stone       for (IndexIterator ii = indices.begin(), ie = indices.end(); ii != ie;
994b9c1b51eSKate Stone            ++ii) {
99514cb2aaaSSean Callanan         ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);
99614cb2aaaSSean Callanan 
997b9c1b51eSKate Stone         if (!constant_index) {
99814cb2aaaSSean Callanan           lldb_private::Scalar I;
99914cb2aaaSSean Callanan 
1000b9c1b51eSKate Stone           if (!frame.EvaluateValue(I, *ii, module)) {
100163e5fb76SJonas Devlieghere             LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str());
100214cb2aaaSSean Callanan             error.SetErrorToGenericError();
100314cb2aaaSSean Callanan             error.SetErrorString(bad_value_error);
100414cb2aaaSSean Callanan             return false;
100514cb2aaaSSean Callanan           }
100614cb2aaaSSean Callanan 
100763e5fb76SJonas Devlieghere           LLDB_LOGF(log, "Evaluated constant index %s as %llu",
100863e5fb76SJonas Devlieghere                     PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
100914cb2aaaSSean Callanan 
1010b9c1b51eSKate Stone           constant_index = cast<ConstantInt>(ConstantInt::get(
1011b9c1b51eSKate Stone               (*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
101214cb2aaaSSean Callanan         }
101314cb2aaaSSean Callanan 
101414cb2aaaSSean Callanan         const_indices.push_back(constant_index);
101514cb2aaaSSean Callanan       }
101614cb2aaaSSean Callanan 
1017b9c1b51eSKate Stone       uint64_t offset =
1018b9c1b51eSKate Stone           data_layout.getIndexedOffsetInType(src_elem_ty, const_indices);
101914cb2aaaSSean Callanan 
102014cb2aaaSSean Callanan       lldb_private::Scalar Poffset = P + offset;
102114cb2aaaSSean Callanan 
102214cb2aaaSSean Callanan       frame.AssignValue(inst, Poffset, module);
102314cb2aaaSSean Callanan 
1024b9c1b51eSKate Stone       if (log) {
102563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a GetElementPtrInst");
102663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P       : %s",
1027b9c1b51eSKate Stone                   frame.SummarizeValue(pointer_operand).c_str());
102863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Poffset : %s", frame.SummarizeValue(inst).c_str());
102914cb2aaaSSean Callanan       }
1030b9c1b51eSKate Stone     } break;
1031b9c1b51eSKate Stone     case Instruction::ICmp: {
1032f18370feSRaphael Isemann       const ICmpInst *icmp_inst = cast<ICmpInst>(inst);
103314cb2aaaSSean Callanan 
103414cb2aaaSSean Callanan       CmpInst::Predicate predicate = icmp_inst->getPredicate();
103514cb2aaaSSean Callanan 
103614cb2aaaSSean Callanan       Value *lhs = inst->getOperand(0);
103714cb2aaaSSean Callanan       Value *rhs = inst->getOperand(1);
103814cb2aaaSSean Callanan 
103914cb2aaaSSean Callanan       lldb_private::Scalar L;
104014cb2aaaSSean Callanan       lldb_private::Scalar R;
104114cb2aaaSSean Callanan 
1042b9c1b51eSKate Stone       if (!frame.EvaluateValue(L, lhs, module)) {
104363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
104414cb2aaaSSean Callanan         error.SetErrorToGenericError();
104514cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
104614cb2aaaSSean Callanan         return false;
104714cb2aaaSSean Callanan       }
104814cb2aaaSSean Callanan 
1049b9c1b51eSKate Stone       if (!frame.EvaluateValue(R, rhs, module)) {
105063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
105114cb2aaaSSean Callanan         error.SetErrorToGenericError();
105214cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
105314cb2aaaSSean Callanan         return false;
105414cb2aaaSSean Callanan       }
105514cb2aaaSSean Callanan 
105614cb2aaaSSean Callanan       lldb_private::Scalar result;
105714cb2aaaSSean Callanan 
1058b9c1b51eSKate Stone       switch (predicate) {
105914cb2aaaSSean Callanan       default:
106014cb2aaaSSean Callanan         return false;
106114cb2aaaSSean Callanan       case CmpInst::ICMP_EQ:
106214cb2aaaSSean Callanan         result = (L == R);
106314cb2aaaSSean Callanan         break;
106414cb2aaaSSean Callanan       case CmpInst::ICMP_NE:
106514cb2aaaSSean Callanan         result = (L != R);
106614cb2aaaSSean Callanan         break;
106714cb2aaaSSean Callanan       case CmpInst::ICMP_UGT:
10689521ad2aSUlrich Weigand         L.MakeUnsigned();
10699521ad2aSUlrich Weigand         R.MakeUnsigned();
10709521ad2aSUlrich Weigand         result = (L > R);
107114cb2aaaSSean Callanan         break;
107214cb2aaaSSean Callanan       case CmpInst::ICMP_UGE:
10739521ad2aSUlrich Weigand         L.MakeUnsigned();
10749521ad2aSUlrich Weigand         R.MakeUnsigned();
10759521ad2aSUlrich Weigand         result = (L >= R);
107614cb2aaaSSean Callanan         break;
107714cb2aaaSSean Callanan       case CmpInst::ICMP_ULT:
10789521ad2aSUlrich Weigand         L.MakeUnsigned();
10799521ad2aSUlrich Weigand         R.MakeUnsigned();
10809521ad2aSUlrich Weigand         result = (L < R);
108114cb2aaaSSean Callanan         break;
108214cb2aaaSSean Callanan       case CmpInst::ICMP_ULE:
10839521ad2aSUlrich Weigand         L.MakeUnsigned();
10849521ad2aSUlrich Weigand         R.MakeUnsigned();
10859521ad2aSUlrich Weigand         result = (L <= R);
108614cb2aaaSSean Callanan         break;
108714cb2aaaSSean Callanan       case CmpInst::ICMP_SGT:
10880b342b6dSSean Callanan         L.MakeSigned();
10890b342b6dSSean Callanan         R.MakeSigned();
109014cb2aaaSSean Callanan         result = (L > R);
109114cb2aaaSSean Callanan         break;
109214cb2aaaSSean Callanan       case CmpInst::ICMP_SGE:
10930b342b6dSSean Callanan         L.MakeSigned();
10940b342b6dSSean Callanan         R.MakeSigned();
109514cb2aaaSSean Callanan         result = (L >= R);
109614cb2aaaSSean Callanan         break;
109714cb2aaaSSean Callanan       case CmpInst::ICMP_SLT:
10980b342b6dSSean Callanan         L.MakeSigned();
10990b342b6dSSean Callanan         R.MakeSigned();
110014cb2aaaSSean Callanan         result = (L < R);
110114cb2aaaSSean Callanan         break;
110214cb2aaaSSean Callanan       case CmpInst::ICMP_SLE:
11030b342b6dSSean Callanan         L.MakeSigned();
11040b342b6dSSean Callanan         R.MakeSigned();
110514cb2aaaSSean Callanan         result = (L <= R);
110614cb2aaaSSean Callanan         break;
110714cb2aaaSSean Callanan       }
110814cb2aaaSSean Callanan 
110914cb2aaaSSean Callanan       frame.AssignValue(inst, result, module);
111014cb2aaaSSean Callanan 
1111b9c1b51eSKate Stone       if (log) {
111263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted an ICmpInst");
111363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  L : %s", frame.SummarizeValue(lhs).c_str());
111463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : %s", frame.SummarizeValue(rhs).c_str());
111563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  = : %s", frame.SummarizeValue(inst).c_str());
111614cb2aaaSSean Callanan       }
1117b9c1b51eSKate Stone     } break;
1118b9c1b51eSKate Stone     case Instruction::IntToPtr: {
1119f18370feSRaphael Isemann       const IntToPtrInst *int_to_ptr_inst = cast<IntToPtrInst>(inst);
112014cb2aaaSSean Callanan 
112114cb2aaaSSean Callanan       Value *src_operand = int_to_ptr_inst->getOperand(0);
112214cb2aaaSSean Callanan 
112314cb2aaaSSean Callanan       lldb_private::Scalar I;
112414cb2aaaSSean Callanan 
1125b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, src_operand, module)) {
112663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
112714cb2aaaSSean Callanan         error.SetErrorToGenericError();
112814cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
112914cb2aaaSSean Callanan         return false;
113014cb2aaaSSean Callanan       }
113114cb2aaaSSean Callanan 
113214cb2aaaSSean Callanan       frame.AssignValue(inst, I, module);
113314cb2aaaSSean Callanan 
1134b9c1b51eSKate Stone       if (log) {
113563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted an IntToPtr");
113663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
113763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
113814cb2aaaSSean Callanan       }
1139b9c1b51eSKate Stone     } break;
1140b9c1b51eSKate Stone     case Instruction::PtrToInt: {
1141f18370feSRaphael Isemann       const PtrToIntInst *ptr_to_int_inst = cast<PtrToIntInst>(inst);
114214cb2aaaSSean Callanan 
114314cb2aaaSSean Callanan       Value *src_operand = ptr_to_int_inst->getOperand(0);
114414cb2aaaSSean Callanan 
114514cb2aaaSSean Callanan       lldb_private::Scalar I;
114614cb2aaaSSean Callanan 
1147b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, src_operand, module)) {
114863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
114914cb2aaaSSean Callanan         error.SetErrorToGenericError();
115014cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
115114cb2aaaSSean Callanan         return false;
115214cb2aaaSSean Callanan       }
115314cb2aaaSSean Callanan 
115414cb2aaaSSean Callanan       frame.AssignValue(inst, I, module);
115514cb2aaaSSean Callanan 
1156b9c1b51eSKate Stone       if (log) {
115763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a PtrToInt");
115863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
115963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
116014cb2aaaSSean Callanan       }
1161b9c1b51eSKate Stone     } break;
1162b9c1b51eSKate Stone     case Instruction::Trunc: {
1163f18370feSRaphael Isemann       const TruncInst *trunc_inst = cast<TruncInst>(inst);
11648c46bacaSSean Callanan 
11658c46bacaSSean Callanan       Value *src_operand = trunc_inst->getOperand(0);
11668c46bacaSSean Callanan 
11678c46bacaSSean Callanan       lldb_private::Scalar I;
11688c46bacaSSean Callanan 
1169b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, src_operand, module)) {
117063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
11718c46bacaSSean Callanan         error.SetErrorToGenericError();
11728c46bacaSSean Callanan         error.SetErrorString(bad_value_error);
11738c46bacaSSean Callanan         return false;
11748c46bacaSSean Callanan       }
11758c46bacaSSean Callanan 
11768c46bacaSSean Callanan       frame.AssignValue(inst, I, module);
11778c46bacaSSean Callanan 
1178b9c1b51eSKate Stone       if (log) {
117963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a Trunc");
118063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
118163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
11828c46bacaSSean Callanan       }
1183b9c1b51eSKate Stone     } break;
1184b9c1b51eSKate Stone     case Instruction::Load: {
1185f18370feSRaphael Isemann       const LoadInst *load_inst = cast<LoadInst>(inst);
118614cb2aaaSSean Callanan 
118714cb2aaaSSean Callanan       // The semantics of Load are:
118814cb2aaaSSean Callanan       //   Create a region D that will contain the loaded data
118914cb2aaaSSean Callanan       //   Resolve the region P containing a pointer
119014cb2aaaSSean Callanan       //   Dereference P to get the region R that the data should be loaded from
119114cb2aaaSSean Callanan       //   Transfer a unit of type type(D) from R to D
119214cb2aaaSSean Callanan 
119314cb2aaaSSean Callanan       const Value *pointer_operand = load_inst->getPointerOperand();
119414cb2aaaSSean Callanan 
119514cb2aaaSSean Callanan       lldb::addr_t D = frame.ResolveValue(load_inst, module);
119614cb2aaaSSean Callanan       lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
119714cb2aaaSSean Callanan 
1198b9c1b51eSKate Stone       if (D == LLDB_INVALID_ADDRESS) {
119963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything");
120014cb2aaaSSean Callanan         error.SetErrorToGenericError();
120114cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
120214cb2aaaSSean Callanan         return false;
120314cb2aaaSSean Callanan       }
120414cb2aaaSSean Callanan 
1205b9c1b51eSKate Stone       if (P == LLDB_INVALID_ADDRESS) {
120663e5fb76SJonas Devlieghere         LLDB_LOGF(log, "LoadInst's pointer doesn't resolve to anything");
120714cb2aaaSSean Callanan         error.SetErrorToGenericError();
120814cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
120914cb2aaaSSean Callanan         return false;
121014cb2aaaSSean Callanan       }
121114cb2aaaSSean Callanan 
121214cb2aaaSSean Callanan       lldb::addr_t R;
121397206d57SZachary Turner       lldb_private::Status read_error;
12147071c5fdSTed Woodward       execution_unit.ReadPointerFromMemory(&R, P, read_error);
121514cb2aaaSSean Callanan 
1216b9c1b51eSKate Stone       if (!read_error.Success()) {
121763e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
121814cb2aaaSSean Callanan         error.SetErrorToGenericError();
121914cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
122014cb2aaaSSean Callanan         return false;
122114cb2aaaSSean Callanan       }
122214cb2aaaSSean Callanan 
12232df9430fSNikita Popov       Type *target_ty = load_inst->getType();
122414cb2aaaSSean Callanan       size_t target_size = data_layout.getTypeStoreSize(target_ty);
122514cb2aaaSSean Callanan       lldb_private::DataBufferHeap buffer(target_size, 0);
122614cb2aaaSSean Callanan 
122714cb2aaaSSean Callanan       read_error.Clear();
1228b9c1b51eSKate Stone       execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(),
1229b9c1b51eSKate Stone                                 read_error);
1230b9c1b51eSKate Stone       if (!read_error.Success()) {
123163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read from a region on behalf of a LoadInst");
123214cb2aaaSSean Callanan         error.SetErrorToGenericError();
123314cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
123414cb2aaaSSean Callanan         return false;
123514cb2aaaSSean Callanan       }
123614cb2aaaSSean Callanan 
123797206d57SZachary Turner       lldb_private::Status write_error;
1238b9c1b51eSKate Stone       execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(),
1239b9c1b51eSKate Stone                                  write_error);
1240b9c1b51eSKate Stone       if (!write_error.Success()) {
124163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst");
124214cb2aaaSSean Callanan         error.SetErrorToGenericError();
12431b7e5d46SAndy Yankovsky         error.SetErrorString(memory_write_error);
124414cb2aaaSSean Callanan         return false;
124514cb2aaaSSean Callanan       }
124614cb2aaaSSean Callanan 
1247b9c1b51eSKate Stone       if (log) {
124863e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a LoadInst");
124963e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
125063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
125163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  D : 0x%" PRIx64, D);
125214cb2aaaSSean Callanan       }
1253b9c1b51eSKate Stone     } break;
1254b9c1b51eSKate Stone     case Instruction::Ret: {
125514cb2aaaSSean Callanan       return true;
125614cb2aaaSSean Callanan     }
1257b9c1b51eSKate Stone     case Instruction::Store: {
1258f18370feSRaphael Isemann       const StoreInst *store_inst = cast<StoreInst>(inst);
125914cb2aaaSSean Callanan 
126014cb2aaaSSean Callanan       // The semantics of Store are:
126114cb2aaaSSean Callanan       //   Resolve the region D containing the data to be stored
126214cb2aaaSSean Callanan       //   Resolve the region P containing a pointer
126314cb2aaaSSean Callanan       //   Dereference P to get the region R that the data should be stored in
126414cb2aaaSSean Callanan       //   Transfer a unit of type type(D) from D to R
126514cb2aaaSSean Callanan 
126614cb2aaaSSean Callanan       const Value *value_operand = store_inst->getValueOperand();
126714cb2aaaSSean Callanan       const Value *pointer_operand = store_inst->getPointerOperand();
126814cb2aaaSSean Callanan 
126914cb2aaaSSean Callanan       lldb::addr_t D = frame.ResolveValue(value_operand, module);
127014cb2aaaSSean Callanan       lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
127114cb2aaaSSean Callanan 
1272b9c1b51eSKate Stone       if (D == LLDB_INVALID_ADDRESS) {
127363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything");
127414cb2aaaSSean Callanan         error.SetErrorToGenericError();
127514cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
127614cb2aaaSSean Callanan         return false;
127714cb2aaaSSean Callanan       }
127814cb2aaaSSean Callanan 
1279b9c1b51eSKate Stone       if (P == LLDB_INVALID_ADDRESS) {
128063e5fb76SJonas Devlieghere         LLDB_LOGF(log, "StoreInst's pointer doesn't resolve to anything");
128114cb2aaaSSean Callanan         error.SetErrorToGenericError();
128214cb2aaaSSean Callanan         error.SetErrorString(bad_value_error);
128314cb2aaaSSean Callanan         return false;
128414cb2aaaSSean Callanan       }
128514cb2aaaSSean Callanan 
128614cb2aaaSSean Callanan       lldb::addr_t R;
128797206d57SZachary Turner       lldb_private::Status read_error;
12887071c5fdSTed Woodward       execution_unit.ReadPointerFromMemory(&R, P, read_error);
128914cb2aaaSSean Callanan 
1290b9c1b51eSKate Stone       if (!read_error.Success()) {
129163e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
129214cb2aaaSSean Callanan         error.SetErrorToGenericError();
129314cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
129414cb2aaaSSean Callanan         return false;
129514cb2aaaSSean Callanan       }
129614cb2aaaSSean Callanan 
12972df9430fSNikita Popov       Type *target_ty = value_operand->getType();
129814cb2aaaSSean Callanan       size_t target_size = data_layout.getTypeStoreSize(target_ty);
129914cb2aaaSSean Callanan       lldb_private::DataBufferHeap buffer(target_size, 0);
130014cb2aaaSSean Callanan 
130114cb2aaaSSean Callanan       read_error.Clear();
1302b9c1b51eSKate Stone       execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(),
1303b9c1b51eSKate Stone                                 read_error);
1304b9c1b51eSKate Stone       if (!read_error.Success()) {
130563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't read from a region on behalf of a StoreInst");
130614cb2aaaSSean Callanan         error.SetErrorToGenericError();
130714cb2aaaSSean Callanan         error.SetErrorString(memory_read_error);
130814cb2aaaSSean Callanan         return false;
130914cb2aaaSSean Callanan       }
131014cb2aaaSSean Callanan 
131197206d57SZachary Turner       lldb_private::Status write_error;
1312b9c1b51eSKate Stone       execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(),
1313b9c1b51eSKate Stone                                  write_error);
1314b9c1b51eSKate Stone       if (!write_error.Success()) {
131563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Couldn't write to a region on behalf of a StoreInst");
131614cb2aaaSSean Callanan         error.SetErrorToGenericError();
131749630e7fSSean Callanan         error.SetErrorString(memory_write_error);
131814cb2aaaSSean Callanan         return false;
131914cb2aaaSSean Callanan       }
132014cb2aaaSSean Callanan 
1321b9c1b51eSKate Stone       if (log) {
132263e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Interpreted a StoreInst");
132363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  D : 0x%" PRIx64, D);
132463e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
132563e5fb76SJonas Devlieghere         LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
132614cb2aaaSSean Callanan       }
1327b9c1b51eSKate Stone     } break;
1328b9c1b51eSKate Stone     case Instruction::Call: {
1329f18370feSRaphael Isemann       const CallInst *call_inst = cast<CallInst>(inst);
133090ff7911SEwan Crawford 
133190ff7911SEwan Crawford       if (CanIgnoreCall(call_inst))
133290ff7911SEwan Crawford         break;
133390ff7911SEwan Crawford 
133490ff7911SEwan Crawford       // Get the return type
133590ff7911SEwan Crawford       llvm::Type *returnType = call_inst->getType();
1336b9c1b51eSKate Stone       if (returnType == nullptr) {
133790ff7911SEwan Crawford         error.SetErrorToGenericError();
133890ff7911SEwan Crawford         error.SetErrorString("unable to access return type");
133990ff7911SEwan Crawford         return false;
134090ff7911SEwan Crawford       }
134190ff7911SEwan Crawford 
134290ff7911SEwan Crawford       // Work with void, integer and pointer return types
1343b9c1b51eSKate Stone       if (!returnType->isVoidTy() && !returnType->isIntegerTy() &&
1344b9c1b51eSKate Stone           !returnType->isPointerTy()) {
134590ff7911SEwan Crawford         error.SetErrorToGenericError();
134690ff7911SEwan Crawford         error.SetErrorString("return type is not supported");
134790ff7911SEwan Crawford         return false;
134890ff7911SEwan Crawford       }
134990ff7911SEwan Crawford 
135090ff7911SEwan Crawford       // Check we can actually get a thread
1351b9c1b51eSKate Stone       if (exe_ctx.GetThreadPtr() == nullptr) {
135290ff7911SEwan Crawford         error.SetErrorToGenericError();
135389533764SJonas Devlieghere         error.SetErrorString("unable to acquire thread");
135490ff7911SEwan Crawford         return false;
135590ff7911SEwan Crawford       }
135690ff7911SEwan Crawford 
135790ff7911SEwan Crawford       // Make sure we have a valid process
1358b9c1b51eSKate Stone       if (!exe_ctx.GetProcessPtr()) {
135990ff7911SEwan Crawford         error.SetErrorToGenericError();
136089533764SJonas Devlieghere         error.SetErrorString("unable to get the process");
136190ff7911SEwan Crawford         return false;
136290ff7911SEwan Crawford       }
136390ff7911SEwan Crawford 
136490ff7911SEwan Crawford       // Find the address of the callee function
136590ff7911SEwan Crawford       lldb_private::Scalar I;
1366a58b62b4SCraig Topper       const llvm::Value *val = call_inst->getCalledOperand();
136790ff7911SEwan Crawford 
1368b9c1b51eSKate Stone       if (!frame.EvaluateValue(I, val, module)) {
136990ff7911SEwan Crawford         error.SetErrorToGenericError();
137090ff7911SEwan Crawford         error.SetErrorString("unable to get address of function");
137190ff7911SEwan Crawford         return false;
137290ff7911SEwan Crawford       }
137390ff7911SEwan Crawford       lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS));
137490ff7911SEwan Crawford 
1375579e70c9SSean Callanan       lldb_private::DiagnosticManager diagnostics;
137690ff7911SEwan Crawford       lldb_private::EvaluateExpressionOptions options;
137790ff7911SEwan Crawford 
1378ad1feef7SNikita Popov       llvm::FunctionType *prototype = call_inst->getFunctionType();
137990ff7911SEwan Crawford 
138090ff7911SEwan Crawford       // Find number of arguments
138180e39366SKazu Hirata       const int numArgs = call_inst->arg_size();
138290ff7911SEwan Crawford 
138390ff7911SEwan Crawford       // We work with a fixed array of 16 arguments which is our upper limit
138490ff7911SEwan Crawford       static lldb_private::ABI::CallArgument rawArgs[16];
1385b9c1b51eSKate Stone       if (numArgs >= 16) {
138690ff7911SEwan Crawford         error.SetErrorToGenericError();
138789533764SJonas Devlieghere         error.SetErrorString("function takes too many arguments");
138890ff7911SEwan Crawford         return false;
138990ff7911SEwan Crawford       }
139090ff7911SEwan Crawford 
139105097246SAdrian Prantl       // Push all function arguments to the argument list that will be passed
139205097246SAdrian Prantl       // to the call function thread plan
1393b9c1b51eSKate Stone       for (int i = 0; i < numArgs; i++) {
139490ff7911SEwan Crawford         // Get details of this argument
139590ff7911SEwan Crawford         llvm::Value *arg_op = call_inst->getArgOperand(i);
139690ff7911SEwan Crawford         llvm::Type *arg_ty = arg_op->getType();
139790ff7911SEwan Crawford 
139890ff7911SEwan Crawford         // Ensure that this argument is an supported type
1399b9c1b51eSKate Stone         if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) {
140090ff7911SEwan Crawford           error.SetErrorToGenericError();
140190ff7911SEwan Crawford           error.SetErrorStringWithFormat("argument %d must be integer type", i);
140290ff7911SEwan Crawford           return false;
140390ff7911SEwan Crawford         }
140490ff7911SEwan Crawford 
140590ff7911SEwan Crawford         // Extract the arguments value
140690ff7911SEwan Crawford         lldb_private::Scalar tmp_op = 0;
1407b9c1b51eSKate Stone         if (!frame.EvaluateValue(tmp_op, arg_op, module)) {
140890ff7911SEwan Crawford           error.SetErrorToGenericError();
140990ff7911SEwan Crawford           error.SetErrorStringWithFormat("unable to evaluate argument %d", i);
141090ff7911SEwan Crawford           return false;
141190ff7911SEwan Crawford         }
141290ff7911SEwan Crawford 
141390ff7911SEwan Crawford         // Check if this is a string literal or constant string pointer
1414b9c1b51eSKate Stone         if (arg_ty->isPointerTy()) {
141590ff7911SEwan Crawford           lldb::addr_t addr = tmp_op.ULongLong();
141690ff7911SEwan Crawford           size_t dataSize = 0;
141790ff7911SEwan Crawford 
1418a322f36cSDavid Blaikie           bool Success = execution_unit.GetAllocSize(addr, dataSize);
1419a322f36cSDavid Blaikie           (void)Success;
1420a322f36cSDavid Blaikie           assert(Success &&
1421a322f36cSDavid Blaikie                  "unable to locate host data for transfer to device");
142290ff7911SEwan Crawford           // Create the required buffer
142390ff7911SEwan Crawford           rawArgs[i].size = dataSize;
1424d5b44036SJonas Devlieghere           rawArgs[i].data_up.reset(new uint8_t[dataSize + 1]);
142590ff7911SEwan Crawford 
142690ff7911SEwan Crawford           // Read string from host memory
1427d5b44036SJonas Devlieghere           execution_unit.ReadMemory(rawArgs[i].data_up.get(), addr, dataSize,
1428b9c1b51eSKate Stone                                     error);
1429a322f36cSDavid Blaikie           assert(!error.Fail() &&
1430a322f36cSDavid Blaikie                  "we have failed to read the string from memory");
1431a322f36cSDavid Blaikie 
143290ff7911SEwan Crawford           // Add null terminator
1433d5b44036SJonas Devlieghere           rawArgs[i].data_up[dataSize] = '\0';
143490ff7911SEwan Crawford           rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer;
1435b9c1b51eSKate Stone         } else /* if ( arg_ty->isPointerTy() ) */
143690ff7911SEwan Crawford         {
143790ff7911SEwan Crawford           rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue;
143890ff7911SEwan Crawford           // Get argument size in bytes
143990ff7911SEwan Crawford           rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8;
144090ff7911SEwan Crawford           // Push value into argument list for thread plan
144190ff7911SEwan Crawford           rawArgs[i].value = tmp_op.ULongLong();
144290ff7911SEwan Crawford         }
144390ff7911SEwan Crawford       }
144490ff7911SEwan Crawford 
144590ff7911SEwan Crawford       // Pack the arguments into an llvm::array
144690ff7911SEwan Crawford       llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs);
144790ff7911SEwan Crawford 
144890ff7911SEwan Crawford       // Setup a thread plan to call the target function
1449b9c1b51eSKate Stone       lldb::ThreadPlanSP call_plan_sp(
1450b9c1b51eSKate Stone           new lldb_private::ThreadPlanCallFunctionUsingABI(
1451b9c1b51eSKate Stone               exe_ctx.GetThreadRef(), funcAddr, *prototype, *returnType, args,
1452b9c1b51eSKate Stone               options));
145390ff7911SEwan Crawford 
145490ff7911SEwan Crawford       // Check if the plan is valid
1455579e70c9SSean Callanan       lldb_private::StreamString ss;
1456b9c1b51eSKate Stone       if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) {
145790ff7911SEwan Crawford         error.SetErrorToGenericError();
1458b9c1b51eSKate Stone         error.SetErrorStringWithFormat(
1459b9c1b51eSKate Stone             "unable to make ThreadPlanCallFunctionUsingABI for 0x%llx",
1460579e70c9SSean Callanan             I.ULongLong());
146190ff7911SEwan Crawford         return false;
146290ff7911SEwan Crawford       }
146390ff7911SEwan Crawford 
146490ff7911SEwan Crawford       exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
146590ff7911SEwan Crawford 
146690ff7911SEwan Crawford       // Execute the actual function call thread plan
1467b9c1b51eSKate Stone       lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan(
1468b9c1b51eSKate Stone           exe_ctx, call_plan_sp, options, diagnostics);
146990ff7911SEwan Crawford 
147090ff7911SEwan Crawford       // Check that the thread plan completed successfully
1471b9c1b51eSKate Stone       if (res != lldb::ExpressionResults::eExpressionCompleted) {
147290ff7911SEwan Crawford         error.SetErrorToGenericError();
147389533764SJonas Devlieghere         error.SetErrorString("ThreadPlanCallFunctionUsingABI failed");
147490ff7911SEwan Crawford         return false;
147590ff7911SEwan Crawford       }
147690ff7911SEwan Crawford 
147790ff7911SEwan Crawford       exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
147890ff7911SEwan Crawford 
147990ff7911SEwan Crawford       // Void return type
1480b9c1b51eSKate Stone       if (returnType->isVoidTy()) {
148190ff7911SEwan Crawford         // Cant assign to void types, so we leave the frame untouched
1482b9c1b51eSKate Stone       } else
148390ff7911SEwan Crawford           // Integer or pointer return type
1484b9c1b51eSKate Stone           if (returnType->isIntegerTy() || returnType->isPointerTy()) {
148590ff7911SEwan Crawford         // Get the encapsulated return value
148690ff7911SEwan Crawford         lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject();
148790ff7911SEwan Crawford 
148890ff7911SEwan Crawford         lldb_private::Scalar returnVal = -1;
148990ff7911SEwan Crawford         lldb_private::ValueObject *vobj = retVal.get();
149090ff7911SEwan Crawford 
149190ff7911SEwan Crawford         // Check if the return value is valid
1492363f05b8SPavel Labath         if (vobj == nullptr || !retVal) {
149390ff7911SEwan Crawford           error.SetErrorToGenericError();
149489533764SJonas Devlieghere           error.SetErrorString("unable to get the return value");
149590ff7911SEwan Crawford           return false;
149690ff7911SEwan Crawford         }
149790ff7911SEwan Crawford 
149890ff7911SEwan Crawford         // Extract the return value as a integer
149990ff7911SEwan Crawford         lldb_private::Value &value = vobj->GetValue();
150090ff7911SEwan Crawford         returnVal = value.GetScalar();
150190ff7911SEwan Crawford 
150290ff7911SEwan Crawford         // Push the return value as the result
150390ff7911SEwan Crawford         frame.AssignValue(inst, returnVal, module);
150490ff7911SEwan Crawford       }
1505b9c1b51eSKate Stone     } break;
150614cb2aaaSSean Callanan     }
150714cb2aaaSSean Callanan 
150814cb2aaaSSean Callanan     ++frame.m_ii;
150914cb2aaaSSean Callanan   }
151014cb2aaaSSean Callanan 
1511b9c1b51eSKate Stone   if (num_insts >= 4096) {
151214cb2aaaSSean Callanan     error.SetErrorToGenericError();
151314cb2aaaSSean Callanan     error.SetErrorString(infinite_loop_error);
151414cb2aaaSSean Callanan     return false;
151514cb2aaaSSean Callanan   }
151614cb2aaaSSean Callanan 
151714cb2aaaSSean Callanan   return false;
151814cb2aaaSSean Callanan }
1519