diff options
Diffstat (limited to 'lldb/source/Expression/IRInterpreter.cpp')
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 277 |
1 files changed, 196 insertions, 81 deletions
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 622156302ae..bfd8abe793a 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -89,6 +89,10 @@ public: BasicBlock::const_iterator m_ii; BasicBlock::const_iterator m_ie; + lldb::addr_t m_frame_process_address; + size_t m_frame_size; + lldb::addr_t m_stack_pointer; + lldb::ByteOrder m_byte_order; size_t m_addr_byte_size; @@ -101,6 +105,36 @@ public: { m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig); m_addr_byte_size = (target_data.getPointerSize(0)); + + m_frame_size = 512 * 1024; + + lldb_private::Error alloc_error; + + m_frame_process_address = memory_map.Malloc(m_frame_size, + m_addr_byte_size, + lldb::ePermissionsReadable | lldb::ePermissionsWritable, + lldb_private::IRMemoryMap::eAllocationPolicyMirror, + alloc_error); + + if (alloc_error.Success()) + { + m_stack_pointer = m_frame_process_address + m_frame_size; + } + else + { + m_frame_process_address = LLDB_INVALID_ADDRESS; + m_stack_pointer = LLDB_INVALID_ADDRESS; + } + } + + ~InterpreterStackFrame () + { + if (m_frame_process_address != LLDB_INVALID_ADDRESS) + { + lldb_private::Error free_error; + m_memory_map.Free(m_frame_process_address, free_error); + m_frame_process_address = LLDB_INVALID_ADDRESS; + } } void Jump (const BasicBlock *bb) @@ -216,59 +250,108 @@ public: bool ResolveConstantValue (APInt &value, const Constant *constant) { - if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) - { - value = constant_int->getValue(); - return true; - } - else if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) - { - value = constant_fp->getValueAPF().bitcastToAPInt(); - return true; - } - else if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) + switch (constant->getValueID()) { - switch (constant_expr->getOpcode()) + default: + break; + case Value::ConstantIntVal: + if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) { - default: - return false; - case Instruction::IntToPtr: - case Instruction::PtrToInt: - case Instruction::BitCast: - return ResolveConstantValue(value, constant_expr->getOperand(0)); - case Instruction::GetElementPtr: + value = constant_int->getValue(); + return true; + } + break; + case Value::ConstantFPVal: + if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) + { + value = constant_fp->getValueAPF().bitcastToAPInt(); + return true; + } + break; + case Value::ConstantExprVal: + if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) + { + switch (constant_expr->getOpcode()) { - ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); - ConstantExpr::const_op_iterator op_end = constant_expr->op_end(); - - Constant *base = dyn_cast<Constant>(*op_cursor); - - if (!base) - return false; - - if (!ResolveConstantValue(value, base)) + default: return false; - - op_cursor++; - - if (op_cursor == op_end) - return true; // no offset to apply! - - SmallVector <Value *, 8> indices (op_cursor, op_end); - - uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices); - - const bool is_signed = true; - value += APInt(value.getBitWidth(), offset, is_signed); - - return true; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + case Instruction::BitCast: + return ResolveConstantValue(value, constant_expr->getOperand(0)); + case Instruction::GetElementPtr: + { + ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); + ConstantExpr::const_op_iterator op_end = constant_expr->op_end(); + + Constant *base = dyn_cast<Constant>(*op_cursor); + + if (!base) + return false; + + if (!ResolveConstantValue(value, base)) + return false; + + op_cursor++; + + if (op_cursor == op_end) + return true; // no offset to apply! + + SmallVector <Value *, 8> indices (op_cursor, op_end); + + uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices); + + const bool is_signed = true; + value += APInt(value.getBitWidth(), offset, is_signed); + + return true; + } } } + break; + case Value::ConstantPointerNullVal: + if (isa<ConstantPointerNull>(constant)) + { + value = APInt(m_target_data.getPointerSizeInBits(), 0); + return true; + } + break; } - return false; } + bool MakeArgument(const Argument *value, uint64_t address) + { + lldb::addr_t data_address = Malloc(value->getType()); + + if (data_address == LLDB_INVALID_ADDRESS) + return false; + + lldb_private::Error write_error; + + m_memory_map.WritePointerToMemory(data_address, address, write_error); + + if (!write_error.Success()) + { + lldb_private::Error free_error; + m_memory_map.Free(data_address, free_error); + return false; + } + + m_values[value] = data_address; + + lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + { + log->Printf("Made an allocation for argument %s", PrintValue(value).c_str()); + log->Printf(" Data region : %llx", (unsigned long long)address); + log->Printf(" Ref region : %llx", (unsigned long long)data_address); + } + + return true; + } + bool ResolveConstant (lldb::addr_t process_address, const Constant *constant) { APInt resolved_value; @@ -287,31 +370,30 @@ public: return write_error.Success(); } - lldb::addr_t MallocPointer () + lldb::addr_t Malloc (size_t size, uint8_t byte_alignment) { - lldb_private::Error alloc_error; - - lldb::addr_t ret = m_memory_map.Malloc(m_target_data.getPointerSize(), m_target_data.getPointerPrefAlignment(), lldb::ePermissionsReadable | lldb::ePermissionsWritable, lldb_private::IRMemoryMap::eAllocationPolicyMirror, alloc_error); + lldb::addr_t ret = m_stack_pointer; - if (alloc_error.Success()) - return ret; - else + ret -= size; + ret -= (ret % byte_alignment); + + if (ret < m_frame_process_address) return LLDB_INVALID_ADDRESS; + + m_stack_pointer = ret; + return ret; + } + + lldb::addr_t MallocPointer () + { + return Malloc(m_target_data.getPointerSize(), m_target_data.getPointerPrefAlignment()); } - lldb::addr_t Malloc (llvm::Type *type, size_t override_byte_size = 0) + lldb::addr_t Malloc (llvm::Type *type) { lldb_private::Error alloc_error; - if (!override_byte_size) - override_byte_size = m_target_data.getTypeStoreSize(type); - - lldb::addr_t ret = m_memory_map.Malloc(override_byte_size, m_target_data.getPrefTypeAlignment(type), lldb::ePermissionsReadable | lldb::ePermissionsWritable, lldb_private::IRMemoryMap::eAllocationPolicyMirror, alloc_error); - - if (alloc_error.Success()) - return ret; - else - return LLDB_INVALID_ADDRESS; + return Malloc(m_target_data.getTypeAllocSize(type), m_target_data.getPrefTypeAlignment(type)); } lldb::addr_t PlaceLLDBValue (const llvm::Value *value, lldb_private::Value lldb_value) @@ -325,6 +407,7 @@ public: lldb::addr_t ret; size_t value_size = m_target_data.getTypeStoreSize(value->getType()); + size_t value_align = m_target_data.getPrefTypeAlignment(value->getType()); if (reg_info && (reg_info->encoding == lldb::eEncodingVector)) value_size = reg_info->byte_size; @@ -332,7 +415,7 @@ public: if (!reg_info && (lldb_value.GetValueType() == lldb_private::Value::eValueTypeLoadAddress)) return lldb_value.GetScalar().ULongLong(); - ret = Malloc(value->getType(), value_size); + ret = Malloc(value_size, value_align); if (ret == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; @@ -403,14 +486,28 @@ public: lldb::addr_t ResolveValue (const Value *value, Module &module) { - if (!m_decl_map) - return LLDB_INVALID_ADDRESS; - ValueMap::iterator i = m_values.find(value); if (i != m_values.end()) return i->second; + // Fall back and allocate space [allocation type Alloca] + + lldb::addr_t data_address = Malloc(value->getType()); + + if (const Constant *constant = dyn_cast<Constant>(value)) + { + if (!ResolveConstant (data_address, constant)) + { + lldb_private::Error free_error; + m_memory_map.Free(data_address, free_error); + return LLDB_INVALID_ADDRESS; + } + } + + m_values[value] = data_address; + return data_address; + const GlobalValue *global_value = dyn_cast<GlobalValue>(value); // If the variable is indirected through the argument @@ -686,23 +783,6 @@ public: } } while(0); - - // Fall back and allocate space [allocation type Alloca] - - lldb::addr_t data_address = Malloc(value->getType()); - - if (const Constant *constant = dyn_cast<Constant>(value)) - { - if (!ResolveConstant (data_address, constant)) - { - lldb_private::Error free_error; - m_memory_map.Free(data_address, free_error); - return LLDB_INVALID_ADDRESS; - } - } - - m_values[value] = data_address; - return data_address; } bool ConstructResult (lldb::ClangExpressionVariableSP &result, @@ -1698,15 +1778,50 @@ IRInterpreter::CanInterpret (llvm::Module &module, bool IRInterpreter::Interpret (llvm::Module &module, llvm::Function &function, + llvm::ArrayRef<lldb::addr_t> args, lldb_private::IRMemoryMap &memory_map, lldb_private::Error &error) { lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (log) + { + std::string s; + raw_string_ostream oss(s); + + module.print(oss, NULL); + + oss.flush(); + + log->Printf("Module as passed in to IRInterpreter::Interpret: \n\"%s\"", s.c_str()); + } + DataLayout data_layout(&module); InterpreterStackFrame frame(data_layout, NULL, memory_map); + if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS) + { + error.SetErrorString("Couldn't allocate stack frame"); + } + + int arg_index = 0; + + for (llvm::Function::arg_iterator ai = function.arg_begin(), ae = function.arg_end(); + ai != ae; + ++ai, ++arg_index) + { + if (args.size() < arg_index) + { + error.SetErrorString ("Not enough arguments passed in to function"); + return false; + } + + lldb::addr_t ptr = args[arg_index]; + + frame.MakeArgument(ai, ptr); + } + uint32_t num_insts = 0; frame.Jump(function.begin()); |