https://github.com/dsandersllvm created https://github.com/llvm/llvm-project/pull/155000
This allows the debugger to evaluate expressions without requiring the expression to be CodeGen'd and executed on the target. This should be more efficient for many existing targets but is necessary for targets which are not yet able to evaluate on the target. As far as I know most targets have a vector memory layout that matches the IR element order. Most little endian targets choose to use a little endian element order, and two out of the three big endian targets I know of (MIPS MSA and ARM NEON) choose to use little endian element order even when the elements are big endian which matches LLVM-IR's order. The third is PowerPC Altivec which has the highest indexed element first for big-endian mode. I've attempted to implement the correct element ordering on the relevant operations but I don't really have a means to test the case where the element order doesn't match LLVM-IR's element order so I've chosen to have a guard against element order mismatches to ensure that this change can't break expression evaluation on those targets. >From 3d736e3685776467dd03d53d0f2c6abb4252e062 Mon Sep 17 00:00:00 2001 From: Daniel Sanders <daniel_l_sand...@apple.com> Date: Fri, 22 Aug 2025 10:54:52 -0700 Subject: [PATCH 1/2] [lldb] Add some vector operations to the IRInterpreter This allows the debugger to evaluate expressions without requiring the expression to be CodeGen'd and executed on the target. This should be more efficient for many existing targets but is necessary for targets which are not yet able to evaluate on the target. As far as I know most targets have a vector memory layout that matches the IR element order. Most little endian targets choose to use a little endian element order, and two out of the three big endian targets I know of (MIPS MSA and ARM NEON) choose to use little endian element order even when the elements are big endian which matches LLVM-IR's order. The third is PowerPC Altivec which has the highest indexed element first for big-endian mode. I've attempted to implement the correct element ordering on the relevant operations but I don't really have a means to test the case where the element order doesn't match LLVM-IR's element order so I've chosen to have a guard against element order mismatches to ensure that this change can't break expression evaluation on those targets. --- lldb/include/lldb/Core/Architecture.h | 11 + lldb/include/lldb/Expression/IRInterpreter.h | 3 +- lldb/source/Expression/IRInterpreter.cpp | 207 +++++++++++++++++- .../Architecture/PPC64/ArchitecturePPC64.cpp | 7 +- .../Architecture/PPC64/ArchitecturePPC64.h | 6 +- .../Clang/ClangExpressionParser.cpp | 2 +- .../vector-types/TestVectorTypesFormatting.py | 36 ++- 7 files changed, 255 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/Core/Architecture.h b/lldb/include/lldb/Core/Architecture.h index b6fc1a20e1e69..435fe20121869 100644 --- a/lldb/include/lldb/Core/Architecture.h +++ b/lldb/include/lldb/Core/Architecture.h @@ -129,6 +129,17 @@ class Architecture : public PluginInterface { RegisterContext ®_context) const { return false; } + + // Get the vector element order for this architecture. This determines how + // vector elements are indexed. This matters in a few places such as reading/ + // writing LLVM-IR values to/from target memory. Some architectures use + // little-endian element ordering where element 0 is at the lowest address + // even when the architecture is otherwise big-endian (e.g. MIPS MSA, ARM + // NEON), but some architectures like PowerPC may use big-endian element + // ordering where element 0 is at the highest address. + virtual lldb::ByteOrder GetVectorElementOrder() const { + return lldb::eByteOrderLittle; + } }; } // namespace lldb_private diff --git a/lldb/include/lldb/Expression/IRInterpreter.h b/lldb/include/lldb/Expression/IRInterpreter.h index 9106f1b4d1c3d..1c0f10aabed21 100644 --- a/lldb/include/lldb/Expression/IRInterpreter.h +++ b/lldb/include/lldb/Expression/IRInterpreter.h @@ -37,7 +37,8 @@ class IRInterpreter { public: static bool CanInterpret(llvm::Module &module, llvm::Function &function, lldb_private::Status &error, - const bool support_function_calls); + const bool support_function_calls, + lldb_private::ExecutionContext &exe_ctx); static bool Interpret(llvm::Module &module, llvm::Function &function, llvm::ArrayRef<lldb::addr_t> args, diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 91404831aeb9b..73e33ed27d8f1 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -70,6 +70,17 @@ static std::string PrintType(const Type *type, bool truncate = false) { return s; } +static bool MemoryMatchesIRElementOrder(lldb_private::ExecutionContext &exe_ctx) { + lldb::TargetSP target_sp = exe_ctx.GetTargetSP(); + if (target_sp) { + const auto *arch_plugin = target_sp->GetArchitecturePlugin(); + if (arch_plugin) { + return arch_plugin->GetVectorElementOrder() == lldb::eByteOrderLittle; + } + } + return true; // Default to little-endian (matches IR) +} + static bool CanIgnoreCall(const CallInst *call) { const llvm::Function *called_function = call->getCalledFunction(); @@ -124,6 +135,17 @@ class InterpreterStackFrame { ~InterpreterStackFrame() = default; + bool MemoryMatchesIRElementOrder() { + lldb::TargetSP target_sp = m_execution_unit.GetTarget(); + if (target_sp) { + const auto *arch_plugin = target_sp->GetArchitecturePlugin(); + if (arch_plugin) { + return arch_plugin->GetVectorElementOrder() == lldb::eByteOrderLittle; + } + } + return true; + } + void Jump(const BasicBlock *bb) { m_prev_bb = m_bb; m_bb = bb; @@ -367,7 +389,66 @@ class InterpreterStackFrame { return true; } + bool ResolveVectorConstant(lldb::addr_t process_address, + const Constant *constant) { + auto *vector_type = dyn_cast<FixedVectorType>(constant->getType()); + if (!vector_type) + return false; + + Type *element_type = vector_type->getElementType(); + unsigned num_elements = vector_type->getNumElements(); + size_t element_size = m_target_data.getTypeStoreSize(element_type); + size_t total_size = element_size * num_elements; + bool reverse_elements = !MemoryMatchesIRElementOrder(); + + lldb_private::DataBufferHeap buf(total_size, 0); + uint8_t *data_ptr = buf.GetBytes(); + + if (isa<ConstantAggregateZero>(constant)) { + // Zero initializer - buffer is already zeroed, just write it + lldb_private::Status write_error; + m_execution_unit.WriteMemory(process_address, buf.GetBytes(), + buf.GetByteSize(), write_error); + return write_error.Success(); + } + + if (const ConstantDataVector *cdv = dyn_cast<ConstantDataVector>(constant)) { + for (unsigned i = 0; i < num_elements; ++i) { + const Constant *element = cdv->getElementAsConstant(i); + APInt element_value; + if (!ResolveConstantValue(element_value, element)) + return false; + + // Calculate target offset based on element ordering + unsigned target_index = + !reverse_elements ? i : (num_elements - 1 - i); + size_t offset = target_index * element_size; + + lldb_private::Scalar element_scalar( + element_value.zextOrTrunc(element_size * 8)); + lldb_private::Status get_data_error; + if (!element_scalar.GetAsMemoryData(data_ptr + offset, + element_size, m_byte_order, + get_data_error)) + return false; + } + lldb_private::Status write_error; + m_execution_unit.WriteMemory(process_address, buf.GetBytes(), + buf.GetByteSize(), write_error); + + return write_error.Success(); + } + + return false; + } + bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) { + // Handle vector constants specially since they can't be represented as a + // single APInt + if (constant->getType()->isVectorTy()) { + return ResolveVectorConstant(process_address, constant); + } + APInt resolved_value; if (!ResolveConstantValue(resolved_value, constant)) @@ -484,8 +565,13 @@ static bool CanResolveConstant(llvm::Constant *constant) { return false; case Value::ConstantIntVal: case Value::ConstantFPVal: + return true; + case Value::ConstantDataVectorVal: case Value::FunctionVal: return true; + case Value::ConstantAggregateZeroVal: + // Zero initializers can be resolved + return true; case Value::ConstantExprVal: if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) { switch (constant_expr->getOpcode()) { @@ -522,7 +608,8 @@ static bool CanResolveConstant(llvm::Constant *constant) { bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, lldb_private::Status &error, - const bool support_function_calls) { + const bool support_function_calls, + lldb_private::ExecutionContext &exe_ctx) { lldb_private::Log *log(GetLog(LLDBLog::Expressions)); bool saw_function_with_body = false; @@ -551,6 +638,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, case Instruction::BitCast: case Instruction::Br: case Instruction::PHI: + case Instruction::ExtractElement: break; case Instruction::Call: { CallInst *call_inst = dyn_cast<CallInst>(&ii); @@ -644,7 +732,24 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, switch (operand_type->getTypeID()) { default: break; - case Type::FixedVectorTyID: + case Type::FixedVectorTyID: { + // If the element order is big-endian (highest index first) then it + // doesn't match LLVM-IR and must be transformed to correctly transfer + // between LLVM-IR and memory. This might not be fully implemented so + // decline to interpret this case. + if (exe_ctx.GetTargetPtr()) { + const auto *arch_plugin = + exe_ctx.GetTargetRef().GetArchitecturePlugin(); + if (arch_plugin && + arch_plugin->GetVectorElementOrder() == lldb::eByteOrderBig) { + LLDB_LOGF(log, "Unsupported big-endian vector element ordering"); + error = lldb_private::Status::FromErrorString( + "IR interpreter doesn't support big-endian vector element ordering"); + return false; + } + } + break; + } case Type::ScalableVectorTyID: { LLDB_LOGF(log, "Unsupported operand type: %s", PrintType(operand_type).c_str()); @@ -657,8 +762,9 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, // The IR interpreter currently doesn't know about // 128-bit integers. As they're not that frequent, // we can just fall back to the JIT rather than - // choking. - if (operand_type->getPrimitiveSizeInBits() > 64) { + // choking. However, allow vectors since we handle them above. + if (operand_type->getPrimitiveSizeInBits() > 64 && + !operand_type->isVectorTy()) { LLDB_LOGF(log, "Unsupported operand type: %s", PrintType(operand_type).c_str()); error = @@ -1567,6 +1673,99 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, frame.AssignValue(inst, returnVal, module); } } break; + case Instruction::ExtractElement: { + const ExtractElementInst *extract_inst = cast<ExtractElementInst>(inst); + + // Get the vector and index operands + const Value *vector_operand = extract_inst->getVectorOperand(); + const Value *index_operand = extract_inst->getIndexOperand(); + + // Get the vector address + lldb::addr_t vector_addr = frame.ResolveValue(vector_operand, module); + + if (vector_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, "ExtractElement's vector doesn't resolve to anything"); + error = lldb_private::Status::FromErrorString(bad_value_error); + return false; + } + + // Evaluate the index + lldb_private::Scalar index_scalar; + if (!frame.EvaluateValue(index_scalar, index_operand, module)) { + LLDB_LOGF(log, "Couldn't evaluate index %s", + PrintValue(index_operand).c_str()); + error = lldb_private::Status::FromErrorString(bad_value_error); + return false; + } + + uint64_t index = index_scalar.ULongLong(); + + // Get the vector type information + auto *vector_type = dyn_cast<FixedVectorType>(vector_operand->getType()); + if (!vector_type) { + LLDB_LOGF(log, "ExtractElement instruction doesn't have a fixed vector " + "operand type"); + error = lldb_private::Status::FromErrorString(interpreter_internal_error); + return false; + } + + unsigned num_elements = vector_type->getNumElements(); + if (index >= num_elements) { + LLDB_LOGF(log, + "ExtractElement index %llu is out of bounds for vector with " + "%u elements", + (unsigned long long)index, num_elements); + error = lldb_private::Status::FromErrorString(bad_value_error); + return false; + } + + Type *element_type = vector_type->getElementType(); + size_t element_size = data_layout.getTypeStoreSize(element_type); + + // Handle target-specific vector element ordering + bool reverse_elements = !MemoryMatchesIRElementOrder(exe_ctx); + uint64_t target_index = + reverse_elements ? (num_elements - 1 - index) : index; + size_t element_offset = target_index * element_size; + + // Allocate space for the result element + lldb::addr_t result_addr = frame.ResolveValue(extract_inst, module); + if (result_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, "ExtractElement's result doesn't resolve to anything"); + error = lldb_private::Status::FromErrorString(bad_value_error); + return false; + } + + // Read the element from the vector + lldb_private::DataBufferHeap element_buffer(element_size, 0); + lldb_private::Status read_error; + execution_unit.ReadMemory(element_buffer.GetBytes(), + vector_addr + element_offset, element_size, + read_error); + if (!read_error.Success()) { + LLDB_LOGF(log, "Couldn't read element data for ExtractElement"); + error = lldb_private::Status::FromErrorString(memory_read_error); + return false; + } + + // Write the element to the result location + lldb_private::Status write_error; + execution_unit.WriteMemory(result_addr, element_buffer.GetBytes(), + element_size, write_error); + if (!write_error.Success()) { + LLDB_LOGF(log, "Couldn't write result for ExtractElement"); + error = lldb_private::Status::FromErrorString(memory_write_error); + return false; + } + + if (log) { + LLDB_LOGF(log, "Interpreted an ExtractElement"); + LLDB_LOGF(log, " Vector: 0x%" PRIx64, vector_addr); + LLDB_LOGF(log, " Index: %llu", (unsigned long long)index); + LLDB_LOGF(log, " Element offset: %zu", element_offset); + LLDB_LOGF(log, " Result: 0x%" PRIx64, result_addr); + } + } break; } ++frame.m_ii; diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp index b8fac55e41da7..a4690cc561a28 100644 --- a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp +++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp @@ -35,7 +35,8 @@ void ArchitecturePPC64::Terminate() { std::unique_ptr<Architecture> ArchitecturePPC64::Create(const ArchSpec &arch) { if (arch.GetTriple().isPPC64() && arch.GetTriple().getObjectFormat() == llvm::Triple::ObjectFormatType::ELF) - return std::unique_ptr<Architecture>(new ArchitecturePPC64()); + return std::unique_ptr<Architecture>( + new ArchitecturePPC64(arch.GetByteOrder())); return nullptr; } @@ -60,3 +61,7 @@ void ArchitecturePPC64::AdjustBreakpointAddress(const Symbol &func, addr.SetOffset(addr.GetOffset() + loffs); } + +lldb::ByteOrder ArchitecturePPC64::GetVectorElementOrder() const { + return m_vector_element_order; +} diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h index 80f7f27b54cce..dc042eee6b917 100644 --- a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h +++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h @@ -30,9 +30,13 @@ class ArchitecturePPC64 : public Architecture { void AdjustBreakpointAddress(const Symbol &func, Address &addr) const override; + lldb::ByteOrder GetVectorElementOrder() const override; + private: static std::unique_ptr<Architecture> Create(const ArchSpec &arch); - ArchitecturePPC64() = default; + ArchitecturePPC64(lldb::ByteOrder vector_element_order) : m_vector_element_order(vector_element_order) {} + + lldb::ByteOrder m_vector_element_order; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 86ff010e760fa..3b2f7a2bedb50 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1523,7 +1523,7 @@ lldb_private::Status ClangExpressionParser::DoPrepareForExecution( !process ? false : process->CanInterpretFunctionCalls(); can_interpret = IRInterpreter::CanInterpret( *execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), - interpret_error, interpret_function_calls); + interpret_error, interpret_function_calls, exe_ctx); if (!can_interpret && execution_policy == eExecutionPolicyNever) { err = Status::FromErrorStringWithFormat( diff --git a/lldb/test/API/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py b/lldb/test/API/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py index 1839c28aeb29f..885844f9c640b 100644 --- a/lldb/test/API/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py +++ b/lldb/test/API/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py @@ -15,10 +15,7 @@ def setUp(self): # Find the line number to break at. self.line = line_number("main.cpp", "// break here") - # rdar://problem/14035604 - @skipIf(compiler="gcc") # gcc don't have ext_vector_type extension - def test_with_run_command(self): - """Check that vector types format properly""" + def setup_and_run_to_breakpoint(self): self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) @@ -43,8 +40,7 @@ def cleanup(): # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) - pass # my code never fails - + def vector_formatting_test(self, allow_jit=True): v = self.frame().FindVariable("v") v.SetPreferSyntheticValue(True) v.SetFormat(lldb.eFormatVectorOfFloat32) @@ -66,15 +62,25 @@ def cleanup(): v.GetChildAtIndex(3).GetData().float[0], 2.50, "child 3 == 2.50" ) + jit_flag = "" if allow_jit else " --allow-jit false" self.expect( - "expr -f int16_t[] -- v", + f"expr{jit_flag} -f int16_t[] -- v", substrs=["(0, 16288, 0, 16288, 0, 16416, 0, 16416)"], ) self.expect( - "expr -f uint128_t[] -- v", + f"expr{jit_flag} -f uint128_t[] -- v", substrs=["(85236745249553456609335044694184296448)"], ) - self.expect("expr -f float32[] -- v", substrs=["(1.25, 1.25, 2.5, 2.5)"]) + self.expect(f"expr{jit_flag} -f float32[] -- v", substrs=["(1.25, 1.25, 2.5, 2.5)"]) + + self.expect(f"expr{jit_flag} -- f4", substrs=["(1.25, 1.25, 2.5, 2.5)"]) + + self.expect(f"expr{jit_flag} -- float4(0)", substrs=["(0, 0, 0, 0)"]) + self.expect(f"expr{jit_flag} -- float4(1)", substrs=["(1, 1, 1, 1)"]) + self.expect(f"expr{jit_flag} -- float4{0.1, 0.2, 0.3, 0.4}", + substrs=["(0.1, 0.2, 0.3, 0.4)"]) + self.expect(f"expr{jit_flag} -- float4{0.1, 0.2, 0.3, 0.4}[0]", + substrs=["0.1"]) oldValue = v.GetChildAtIndex(0).GetValue() v.SetFormat(lldb.eFormatHex) @@ -93,3 +99,15 @@ def cleanup(): self.assertEqual(f3.GetChildAtIndex(0).GetData().float[0], 1.25) self.assertEqual(f3.GetChildAtIndex(1).GetData().float[0], 2.50) self.assertEqual(f3.GetChildAtIndex(2).GetData().float[0], 2.50) + + # rdar://problem/14035604 + @skipIf(compiler="gcc") # gcc don't have ext_vector_type extension + def test_with_run_command(self): + self.setup_and_run_to_breakpoint() + self.runCmd("settings set plugin.jit-loader.gdb.enable on") + self.vector_formatting_test() + + @skipIf(compiler="gcc") # gcc don't have ext_vector_type extension + def test_with_run_command_no_jit(self): + self.setup_and_run_to_breakpoint() + self.vector_formatting_test(allow_jit=False) >From 202ddf8bed6987df20a127bda94848175d4c4451 Mon Sep 17 00:00:00 2001 From: Daniel Sanders <daniel_l_sand...@apple.com> Date: Fri, 22 Aug 2025 11:08:34 -0700 Subject: [PATCH 2/2] fixup: De-duplicate MemoryMatchesIRElementOrder by plumbing in exe_ctx This is a separate commit because it's a fairly noisy change. It'll be squashed into the previous commit before landing --- lldb/source/Expression/IRInterpreter.cpp | 98 +++++++++++------------- 1 file changed, 45 insertions(+), 53 deletions(-) diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 73e33ed27d8f1..a01a3e989398d 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -135,17 +135,6 @@ class InterpreterStackFrame { ~InterpreterStackFrame() = default; - bool MemoryMatchesIRElementOrder() { - lldb::TargetSP target_sp = m_execution_unit.GetTarget(); - if (target_sp) { - const auto *arch_plugin = target_sp->GetArchitecturePlugin(); - if (arch_plugin) { - return arch_plugin->GetVectorElementOrder() == lldb::eByteOrderLittle; - } - } - return true; - } - void Jump(const BasicBlock *bb) { m_prev_bb = m_bb; m_bb = bb; @@ -184,7 +173,7 @@ class InterpreterStackFrame { } bool EvaluateValue(lldb_private::Scalar &scalar, const Value *value, - Module &module) { + Module &module, lldb_private::ExecutionContext &exe_ctx) { const Constant *constant = dyn_cast<Constant>(value); if (constant) { @@ -208,7 +197,7 @@ class InterpreterStackFrame { return AssignToMatchType(scalar, value_apint, value->getType()); } - lldb::addr_t process_address = ResolveValue(value, module); + lldb::addr_t process_address = ResolveValue(value, module, exe_ctx); size_t value_size = m_target_data.getTypeStoreSize(value->getType()); lldb_private::DataExtractor value_extractor; @@ -240,8 +229,8 @@ class InterpreterStackFrame { } bool AssignValue(const Value *value, lldb_private::Scalar scalar, - Module &module) { - lldb::addr_t process_address = ResolveValue(value, module); + Module &module, lldb_private::ExecutionContext &exe_ctx) { + lldb::addr_t process_address = ResolveValue(value, module, exe_ctx); if (process_address == LLDB_INVALID_ADDRESS) return false; @@ -390,7 +379,8 @@ class InterpreterStackFrame { } bool ResolveVectorConstant(lldb::addr_t process_address, - const Constant *constant) { + const Constant *constant, + lldb_private::ExecutionContext &exe_ctx) { auto *vector_type = dyn_cast<FixedVectorType>(constant->getType()); if (!vector_type) return false; @@ -399,7 +389,7 @@ class InterpreterStackFrame { unsigned num_elements = vector_type->getNumElements(); size_t element_size = m_target_data.getTypeStoreSize(element_type); size_t total_size = element_size * num_elements; - bool reverse_elements = !MemoryMatchesIRElementOrder(); + bool reverse_elements = !MemoryMatchesIRElementOrder(exe_ctx); lldb_private::DataBufferHeap buf(total_size, 0); uint8_t *data_ptr = buf.GetBytes(); @@ -442,11 +432,12 @@ class InterpreterStackFrame { return false; } - bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) { + bool ResolveConstant(lldb::addr_t process_address, const Constant *constant, + lldb_private::ExecutionContext &exe_ctx) { // Handle vector constants specially since they can't be represented as a // single APInt if (constant->getType()->isVectorTy()) { - return ResolveVectorConstant(process_address, constant); + return ResolveVectorConstant(process_address, constant, exe_ctx); } APInt resolved_value; @@ -517,7 +508,8 @@ class InterpreterStackFrame { return std::string(ss.GetString()); } - lldb::addr_t ResolveValue(const Value *value, Module &module) { + lldb::addr_t ResolveValue(const Value *value, Module &module, + lldb_private::ExecutionContext &exe_ctx) { ValueMap::iterator i = m_values.find(value); if (i != m_values.end()) @@ -528,7 +520,7 @@ class InterpreterStackFrame { lldb::addr_t data_address = Malloc(value->getType()); if (const Constant *constant = dyn_cast<Constant>(value)) { - if (!ResolveConstant(data_address, constant)) { + if (!ResolveConstant(data_address, constant, exe_ctx)) { lldb_private::Status free_error; m_execution_unit.Free(data_address, free_error); return LLDB_INVALID_ADDRESS; @@ -905,13 +897,13 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar L; lldb_private::Scalar R; - if (!frame.EvaluateValue(L, lhs, module)) { + if (!frame.EvaluateValue(L, lhs, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - if (!frame.EvaluateValue(R, rhs, module)) { + if (!frame.EvaluateValue(R, rhs, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; @@ -978,7 +970,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, break; } - frame.AssignValue(inst, result, module); + frame.AssignValue(inst, result, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName()); @@ -1053,13 +1045,13 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar S; - if (!frame.EvaluateValue(S, source, module)) { + if (!frame.EvaluateValue(S, source, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - frame.AssignValue(inst, S, module); + frame.AssignValue(inst, S, module, exe_ctx); } break; case Instruction::SExt: { const CastInst *cast_inst = cast<CastInst>(inst); @@ -1068,7 +1060,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar S; - if (!frame.EvaluateValue(S, source, module)) { + if (!frame.EvaluateValue(S, source, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; @@ -1078,7 +1070,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar S_signextend(S.SLongLong()); - frame.AssignValue(inst, S_signextend, module); + frame.AssignValue(inst, S_signextend, module, exe_ctx); } break; case Instruction::Br: { const BranchInst *br_inst = cast<BranchInst>(inst); @@ -1088,7 +1080,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar C; - if (!frame.EvaluateValue(C, condition, module)) { + if (!frame.EvaluateValue(C, condition, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; @@ -1126,12 +1118,12 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb); lldb_private::Scalar result; - if (!frame.EvaluateValue(result, value, module)) { + if (!frame.EvaluateValue(result, value, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - frame.AssignValue(inst, result, module); + frame.AssignValue(inst, result, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName()); @@ -1147,7 +1139,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar P; - if (!frame.EvaluateValue(P, pointer_operand, module)) { + if (!frame.EvaluateValue(P, pointer_operand, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(pointer_operand).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); @@ -1169,7 +1161,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, if (!constant_index) { lldb_private::Scalar I; - if (!frame.EvaluateValue(I, *ii, module)) { + if (!frame.EvaluateValue(I, *ii, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; @@ -1190,7 +1182,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar Poffset = P + offset; - frame.AssignValue(inst, Poffset, module); + frame.AssignValue(inst, Poffset, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted a GetElementPtrInst"); @@ -1211,13 +1203,13 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar L; lldb_private::Scalar R; - if (!frame.EvaluateValue(L, lhs, module)) { + if (!frame.EvaluateValue(L, lhs, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - if (!frame.EvaluateValue(R, rhs, module)) { + if (!frame.EvaluateValue(R, rhs, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; @@ -1290,7 +1282,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, break; } - frame.AssignValue(inst, result, module); + frame.AssignValue(inst, result, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted an ICmpInst"); @@ -1306,13 +1298,13 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar I; - if (!frame.EvaluateValue(I, src_operand, module)) { + if (!frame.EvaluateValue(I, src_operand, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - frame.AssignValue(inst, I, module); + frame.AssignValue(inst, I, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted an IntToPtr"); @@ -1327,13 +1319,13 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar I; - if (!frame.EvaluateValue(I, src_operand, module)) { + if (!frame.EvaluateValue(I, src_operand, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - frame.AssignValue(inst, I, module); + frame.AssignValue(inst, I, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted a PtrToInt"); @@ -1348,13 +1340,13 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar I; - if (!frame.EvaluateValue(I, src_operand, module)) { + if (!frame.EvaluateValue(I, src_operand, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); return false; } - frame.AssignValue(inst, I, module); + frame.AssignValue(inst, I, module, exe_ctx); if (log) { LLDB_LOGF(log, "Interpreted a Trunc"); @@ -1373,8 +1365,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, const Value *pointer_operand = load_inst->getPointerOperand(); - lldb::addr_t D = frame.ResolveValue(load_inst, module); - lldb::addr_t P = frame.ResolveValue(pointer_operand, module); + lldb::addr_t D = frame.ResolveValue(load_inst, module, exe_ctx); + lldb::addr_t P = frame.ResolveValue(pointer_operand, module, exe_ctx); if (D == LLDB_INVALID_ADDRESS) { LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything"); @@ -1442,8 +1434,8 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, const Value *value_operand = store_inst->getValueOperand(); const Value *pointer_operand = store_inst->getPointerOperand(); - lldb::addr_t D = frame.ResolveValue(value_operand, module); - lldb::addr_t P = frame.ResolveValue(pointer_operand, module); + lldb::addr_t D = frame.ResolveValue(value_operand, module, exe_ctx); + lldb::addr_t P = frame.ResolveValue(pointer_operand, module, exe_ctx); if (D == LLDB_INVALID_ADDRESS) { LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything"); @@ -1536,7 +1528,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, lldb_private::Scalar I; const llvm::Value *val = call_inst->getCalledOperand(); - if (!frame.EvaluateValue(I, val, module)) { + if (!frame.EvaluateValue(I, val, module, exe_ctx)) { error = lldb_private::Status::FromErrorString( "unable to get address of function"); return false; @@ -1575,7 +1567,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, // Extract the arguments value lldb_private::Scalar tmp_op = 0; - if (!frame.EvaluateValue(tmp_op, arg_op, module)) { + if (!frame.EvaluateValue(tmp_op, arg_op, module, exe_ctx)) { error = lldb_private::Status::FromErrorStringWithFormat( "unable to evaluate argument %d", i); return false; @@ -1670,7 +1662,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, returnVal = value.GetScalar(); // Push the return value as the result - frame.AssignValue(inst, returnVal, module); + frame.AssignValue(inst, returnVal, module, exe_ctx); } } break; case Instruction::ExtractElement: { @@ -1681,7 +1673,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, const Value *index_operand = extract_inst->getIndexOperand(); // Get the vector address - lldb::addr_t vector_addr = frame.ResolveValue(vector_operand, module); + lldb::addr_t vector_addr = frame.ResolveValue(vector_operand, module, exe_ctx); if (vector_addr == LLDB_INVALID_ADDRESS) { LLDB_LOGF(log, "ExtractElement's vector doesn't resolve to anything"); @@ -1691,7 +1683,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, // Evaluate the index lldb_private::Scalar index_scalar; - if (!frame.EvaluateValue(index_scalar, index_operand, module)) { + if (!frame.EvaluateValue(index_scalar, index_operand, module, exe_ctx)) { LLDB_LOGF(log, "Couldn't evaluate index %s", PrintValue(index_operand).c_str()); error = lldb_private::Status::FromErrorString(bad_value_error); @@ -1729,7 +1721,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, size_t element_offset = target_index * element_size; // Allocate space for the result element - lldb::addr_t result_addr = frame.ResolveValue(extract_inst, module); + lldb::addr_t result_addr = frame.ResolveValue(extract_inst, module, exe_ctx); if (result_addr == LLDB_INVALID_ADDRESS) { LLDB_LOGF(log, "ExtractElement's result doesn't resolve to anything"); error = lldb_private::Status::FromErrorString(bad_value_error); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits