diff options
Diffstat (limited to 'lldb/source/Expression')
-rw-r--r-- | lldb/source/Expression/DWARFExpression.cpp | 423 | ||||
-rw-r--r-- | lldb/source/Expression/Expression.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Expression/FunctionCaller.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Expression/IRExecutionUnit.cpp | 69 | ||||
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 166 | ||||
-rw-r--r-- | lldb/source/Expression/IRMemoryMap.cpp | 12 | ||||
-rw-r--r-- | lldb/source/Expression/LLVMUserExpression.cpp | 298 | ||||
-rw-r--r-- | lldb/source/Expression/REPL.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Expression/UserExpression.cpp | 19 | ||||
-rw-r--r-- | lldb/source/Expression/UtilityFunction.cpp | 11 |
10 files changed, 392 insertions, 624 deletions
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 3789d9147737..69c84640ef93 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -47,22 +47,23 @@ ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu, uint32_t index_size = dwarf_cu->GetAddressByteSize(); dw_offset_t addr_base = dwarf_cu->GetAddrBase(); lldb::offset_t offset = addr_base + index * index_size; - return dwarf_cu->GetSymbolFileDWARF() - .GetDWARFContext() - .getOrLoadAddrData() - .GetMaxU64(&offset, index_size); + const DWARFDataExtractor &data = + dwarf_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadAddrData(); + if (data.ValidOffsetForDataOfSize(offset, index_size)) + return data.GetMaxU64_unchecked(&offset, index_size); + return LLDB_INVALID_ADDRESS; } // DWARFExpression constructor DWARFExpression::DWARFExpression() : m_module_wp(), m_data(), m_dwarf_cu(nullptr), - m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) {} + m_reg_kind(eRegisterKindDWARF) {} DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, const DataExtractor &data, const DWARFUnit *dwarf_cu) : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu), - m_reg_kind(eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) { + m_reg_kind(eRegisterKindDWARF) { if (module_sp) m_module_wp = module_sp; } @@ -84,18 +85,18 @@ void DWARFExpression::UpdateValue(uint64_t const_value, m_data.SetAddressByteSize(addr_byte_size); } -void DWARFExpression::DumpLocation(Stream *s, lldb::offset_t offset, - lldb::offset_t length, +void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data, lldb::DescriptionLevel level, ABI *abi) const { - llvm::DWARFExpression(DataExtractor(m_data, offset, length).GetAsLLVM(), - llvm::dwarf::DWARF_VERSION, m_data.GetAddressByteSize()) + llvm::DWARFExpression(data.GetAsLLVM(), llvm::dwarf::DWARF_VERSION, + data.GetAddressByteSize()) .print(s->AsRawOstream(), abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr); } -void DWARFExpression::SetLocationListSlide(addr_t slide) { - m_loclist_slide = slide; +void DWARFExpression::SetLocationListAddresses(addr_t cu_file_addr, + addr_t func_file_addr) { + m_loclist_addresses = LoclistAddresses{cu_file_addr, func_file_addr}; } int DWARFExpression::GetRegisterKind() { return m_reg_kind; } @@ -105,7 +106,26 @@ void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) { } bool DWARFExpression::IsLocationList() const { - return m_loclist_slide != LLDB_INVALID_ADDRESS; + return bool(m_loclist_addresses); +} + +namespace { +/// Implement enough of the DWARFObject interface in order to be able to call +/// DWARFLocationTable::dumpLocationList. We don't have access to a real +/// DWARFObject here because DWARFExpression is used in non-DWARF scenarios too. +class DummyDWARFObject final: public llvm::DWARFObject { +public: + DummyDWARFObject(bool IsLittleEndian) : IsLittleEndian(IsLittleEndian) {} + + bool isLittleEndian() const override { return IsLittleEndian; } + + llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec, + uint64_t Pos) const override { + return llvm::None; + } +private: + bool IsLittleEndian; +}; } void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level, @@ -114,47 +134,19 @@ void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level, if (IsLocationList()) { // We have a location list lldb::offset_t offset = 0; - uint32_t count = 0; - addr_t curr_base_addr = location_list_base_addr; - while (m_data.ValidOffset(offset)) { - addr_t begin_addr_offset = LLDB_INVALID_ADDRESS; - addr_t end_addr_offset = LLDB_INVALID_ADDRESS; - if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, - begin_addr_offset, end_addr_offset)) - break; + std::unique_ptr<llvm::DWARFLocationTable> loctable_up = + m_dwarf_cu->GetLocationTable(m_data); - if (begin_addr_offset == 0 && end_addr_offset == 0) - break; + llvm::MCRegisterInfo *MRI = abi ? &abi->GetMCRegisterInfo() : nullptr; - if (begin_addr_offset < end_addr_offset) { - if (count > 0) - s->PutCString(", "); - VMRange addr_range(curr_base_addr + begin_addr_offset, - curr_base_addr + end_addr_offset); - addr_range.Dump(s, 0, 8); - s->PutChar('{'); - lldb::offset_t location_length = m_data.GetU16(&offset); - DumpLocation(s, offset, location_length, level, abi); - s->PutChar('}'); - offset += location_length; - } else { - if ((m_data.GetAddressByteSize() == 4 && - (begin_addr_offset == UINT32_MAX)) || - (m_data.GetAddressByteSize() == 8 && - (begin_addr_offset == UINT64_MAX))) { - curr_base_addr = end_addr_offset + location_list_base_addr; - // We have a new base address - if (count > 0) - s->PutCString(", "); - *s << "base_addr = " << end_addr_offset; - } - } - - count++; - } + loctable_up->dumpLocationList( + &offset, s->AsRawOstream(), + llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, MRI, + DummyDWARFObject(m_data.GetByteOrder() == eByteOrderLittle), nullptr, + llvm::DIDumpOptions(), s->GetIndentLevel() + 2); } else { // We have a normal location that contains DW_OP location opcodes - DumpLocation(s, 0, m_data.GetByteSize(), level, abi); + DumpLocation(s, m_data, level, abi); } } @@ -477,7 +469,7 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) { m_data.GetByteOrder(), addr_byte_size); // Replace the address in the new buffer - if (encoder.PutMaxU64(offset, addr_byte_size, file_addr) == UINT32_MAX) + if (encoder.PutUnsigned(offset, addr_byte_size, file_addr) == UINT32_MAX) return false; // All went well, so now we can reset the data using a shared pointer to @@ -583,8 +575,8 @@ bool DWARFExpression::LinkThreadLocalStorage( if (linked_file_addr == LLDB_INVALID_ADDRESS) return false; // Replace the address in the new buffer - if (encoder.PutMaxU64(const_offset, const_byte_size, - linked_file_addr) == UINT32_MAX) + if (encoder.PutUnsigned(const_offset, const_byte_size, + linked_file_addr) == UINT32_MAX) return false; } break; @@ -614,102 +606,29 @@ bool DWARFExpression::LinkThreadLocalStorage( return true; } -bool DWARFExpression::LocationListContainsAddress( - lldb::addr_t loclist_base_addr, lldb::addr_t addr) const { - if (addr == LLDB_INVALID_ADDRESS) +bool DWARFExpression::LocationListContainsAddress(addr_t func_load_addr, + lldb::addr_t addr) const { + if (func_load_addr == LLDB_INVALID_ADDRESS || addr == LLDB_INVALID_ADDRESS) return false; - if (IsLocationList()) { - lldb::offset_t offset = 0; - - if (loclist_base_addr == LLDB_INVALID_ADDRESS) - return false; - - while (m_data.ValidOffset(offset)) { - // We need to figure out what the value is for the location. - addr_t lo_pc = LLDB_INVALID_ADDRESS; - addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, lo_pc, - hi_pc)) - break; - - if (lo_pc == 0 && hi_pc == 0) - break; - - if ((m_data.GetAddressByteSize() == 4 && (lo_pc == UINT32_MAX)) || - (m_data.GetAddressByteSize() == 8 && (lo_pc == UINT64_MAX))) { - loclist_base_addr = hi_pc + m_loclist_slide; - continue; - } - lo_pc += loclist_base_addr - m_loclist_slide; - hi_pc += loclist_base_addr - m_loclist_slide; - - if (lo_pc <= addr && addr < hi_pc) - return true; + if (!IsLocationList()) + return false; - offset += m_data.GetU16(&offset); - } - } - return false; + return GetLocationExpression(func_load_addr, addr) != llvm::None; } -bool DWARFExpression::GetLocation(addr_t base_addr, addr_t pc, - lldb::offset_t &offset, - lldb::offset_t &length) { - offset = 0; +bool DWARFExpression::DumpLocationForAddress(Stream *s, + lldb::DescriptionLevel level, + addr_t func_load_addr, + addr_t address, ABI *abi) { if (!IsLocationList()) { - length = m_data.GetByteSize(); + DumpLocation(s, m_data, level, abi); return true; } - - if (base_addr != LLDB_INVALID_ADDRESS && pc != LLDB_INVALID_ADDRESS) { - addr_t curr_base_addr = base_addr; - - while (m_data.ValidOffset(offset)) { - // We need to figure out what the value is for the location. - addr_t lo_pc = LLDB_INVALID_ADDRESS; - addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, lo_pc, - hi_pc)) - break; - - if (lo_pc == 0 && hi_pc == 0) - break; - - if ((m_data.GetAddressByteSize() == 4 && (lo_pc == UINT32_MAX)) || - (m_data.GetAddressByteSize() == 8 && (lo_pc == UINT64_MAX))) { - curr_base_addr = hi_pc + m_loclist_slide; - continue; - } - - lo_pc += curr_base_addr - m_loclist_slide; - hi_pc += curr_base_addr - m_loclist_slide; - - length = m_data.GetU16(&offset); - - if (length > 0 && lo_pc <= pc && pc < hi_pc) - return true; - - offset += length; - } - } - offset = LLDB_INVALID_OFFSET; - length = 0; - return false; -} - -bool DWARFExpression::DumpLocationForAddress(Stream *s, - lldb::DescriptionLevel level, - addr_t base_addr, addr_t address, - ABI *abi) { - lldb::offset_t offset = 0; - lldb::offset_t length = 0; - - if (GetLocation(base_addr, address, offset, length)) { - if (length > 0) { - DumpLocation(s, offset, length, level, abi); - return true; - } + if (llvm::Optional<DataExtractor> expr = + GetLocationExpression(func_load_addr, address)) { + DumpLocation(s, *expr, level, abi); + return true; } return false; } @@ -830,6 +749,8 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack, CallEdge *call_edge = nullptr; ModuleList &modlist = target.GetImages(); + ExecutionContext parent_exe_ctx = *exe_ctx; + parent_exe_ctx.SetFrameSP(parent_frame); if (!parent_frame->IsArtificial()) { // If the parent frame is not artificial, the current activation may be // produced by an ambiguous tail call. In this case, refuse to proceed. @@ -841,7 +762,7 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack, return_pc, parent_func->GetName()); return false; } - Function *callee_func = call_edge->GetCallee(modlist); + Function *callee_func = call_edge->GetCallee(modlist, parent_exe_ctx); if (callee_func != current_func) { LLDB_LOG(log, "Evaluate_DW_OP_entry_value: ambiguous call sequence, " "can't find real parent frame"); @@ -851,9 +772,9 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack, // The StackFrameList solver machinery has deduced that an unambiguous tail // call sequence that produced the current activation. The first edge in // the parent that points to the current function must be valid. - for (CallEdge &edge : parent_func->GetTailCallingEdges()) { - if (edge.GetCallee(modlist) == current_func) { - call_edge = &edge; + for (auto &edge : parent_func->GetTailCallingEdges()) { + if (edge->GetCallee(modlist, parent_exe_ctx) == current_func) { + call_edge = edge.get(); break; } } @@ -907,8 +828,6 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack, // TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value // subexpresion whenever llvm does. Value result; - ExecutionContext parent_exe_ctx = *exe_ctx; - parent_exe_ctx.SetFrameSP(parent_frame); const DWARFExpression ¶m_expr = matched_param->LocationInCaller; if (!param_expr.Evaluate(&parent_exe_ctx, parent_frame->GetRegisterContext().get(), @@ -936,14 +855,13 @@ bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope, bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, - lldb::addr_t loclist_base_load_addr, + lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) const { ModuleSP module_sp = m_module_wp.lock(); if (IsLocationList()) { - lldb::offset_t offset = 0; addr_t pc; StackFrame *frame = nullptr; if (reg_ctx) @@ -958,45 +876,18 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx, pc = reg_ctx_sp->GetPC(); } - if (loclist_base_load_addr != LLDB_INVALID_ADDRESS) { + if (func_load_addr != LLDB_INVALID_ADDRESS) { if (pc == LLDB_INVALID_ADDRESS) { if (error_ptr) error_ptr->SetErrorString("Invalid PC in frame."); return false; } - addr_t curr_loclist_base_load_addr = loclist_base_load_addr; - - while (m_data.ValidOffset(offset)) { - // We need to figure out what the value is for the location. - addr_t lo_pc = LLDB_INVALID_ADDRESS; - addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (!AddressRangeForLocationListEntry(m_dwarf_cu, m_data, &offset, - lo_pc, hi_pc)) - break; - - if (lo_pc == 0 && hi_pc == 0) - break; - - if ((m_data.GetAddressByteSize() == 4 && - (lo_pc == UINT32_MAX)) || - (m_data.GetAddressByteSize() == 8 && - (lo_pc == UINT64_MAX))) { - curr_loclist_base_load_addr = hi_pc + m_loclist_slide; - continue; - } - lo_pc += curr_loclist_base_load_addr - m_loclist_slide; - hi_pc += curr_loclist_base_load_addr - m_loclist_slide; - - uint16_t length = m_data.GetU16(&offset); - - if (length > 0 && lo_pc <= pc && pc < hi_pc) { - return DWARFExpression::Evaluate( - exe_ctx, reg_ctx, module_sp, - DataExtractor(m_data, offset, length), m_dwarf_cu, m_reg_kind, - initial_value_ptr, object_address_ptr, result, error_ptr); - } - offset += length; + if (llvm::Optional<DataExtractor> expr = + GetLocationExpression(func_load_addr, pc)) { + return DWARFExpression::Evaluate( + exe_ctx, reg_ctx, module_sp, *expr, m_dwarf_cu, m_reg_kind, + initial_value_ptr, object_address_ptr, result, error_ptr); } } if (error_ptr) @@ -2655,62 +2546,6 @@ bool DWARFExpression::Evaluate( return true; // Return true on success } -bool DWARFExpression::AddressRangeForLocationListEntry( - const DWARFUnit *dwarf_cu, const DataExtractor &debug_loc_data, - lldb::offset_t *offset_ptr, lldb::addr_t &low_pc, lldb::addr_t &high_pc) { - if (!debug_loc_data.ValidOffset(*offset_ptr)) - return false; - - DWARFExpression::LocationListFormat format = - dwarf_cu->GetSymbolFileDWARF().GetLocationListFormat(); - switch (format) { - case NonLocationList: - return false; - case RegularLocationList: - low_pc = debug_loc_data.GetAddress(offset_ptr); - high_pc = debug_loc_data.GetAddress(offset_ptr); - return true; - case SplitDwarfLocationList: - case LocLists: - switch (debug_loc_data.GetU8(offset_ptr)) { - case DW_LLE_end_of_list: - return false; - case DW_LLE_startx_endx: { - uint64_t index = debug_loc_data.GetULEB128(offset_ptr); - low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); - index = debug_loc_data.GetULEB128(offset_ptr); - high_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); - return true; - } - case DW_LLE_startx_length: { - uint64_t index = debug_loc_data.GetULEB128(offset_ptr); - low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); - uint64_t length = (format == LocLists) - ? debug_loc_data.GetULEB128(offset_ptr) - : debug_loc_data.GetU32(offset_ptr); - high_pc = low_pc + length; - return true; - } - case DW_LLE_start_length: { - low_pc = debug_loc_data.GetAddress(offset_ptr); - high_pc = low_pc + debug_loc_data.GetULEB128(offset_ptr); - return true; - } - case DW_LLE_start_end: { - low_pc = debug_loc_data.GetAddress(offset_ptr); - high_pc = debug_loc_data.GetAddress(offset_ptr); - return true; - } - default: - // Not supported entry type - lldbassert(false && "Not supported location list type"); - return false; - } - } - assert(false && "Not supported location list type"); - return false; -} - static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size) { @@ -2929,8 +2764,9 @@ void DWARFExpression::PrintDWARFLocationList( s.PutCString("\n "); s.Indent(); if (cu) - s.AddressRange(start_addr + base_addr, end_addr + base_addr, - cu->GetAddressByteSize(), nullptr, ": "); + DumpAddressRange(s.AsRawOstream(), start_addr + base_addr, + end_addr + base_addr, cu->GetAddressByteSize(), nullptr, + ": "); uint32_t loc_length = debug_loc_data.GetU16(&offset); DataExtractor locationData(debug_loc_data, offset, loc_length); @@ -2939,56 +2775,87 @@ void DWARFExpression::PrintDWARFLocationList( } } -bool DWARFExpression::GetOpAndEndOffsets(StackFrame &frame, - lldb::offset_t &op_offset, - lldb::offset_t &end_offset) { - SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction); - if (!sc.function) { - return false; - } - - addr_t loclist_base_file_addr = - sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); - if (loclist_base_file_addr == LLDB_INVALID_ADDRESS) { - return false; - } - - addr_t pc_file_addr = frame.GetFrameCodeAddress().GetFileAddress(); - lldb::offset_t opcodes_offset, opcodes_length; - if (!GetLocation(loclist_base_file_addr, pc_file_addr, opcodes_offset, - opcodes_length)) { - return false; - } - - if (opcodes_length == 0) { - return false; - } +static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc, + ByteOrder byte_order, uint32_t addr_size) { + auto buffer_sp = + std::make_shared<DataBufferHeap>(loc.Expr.data(), loc.Expr.size()); + return DataExtractor(buffer_sp, byte_order, addr_size); +} - op_offset = opcodes_offset; - end_offset = opcodes_offset + opcodes_length; - return true; +llvm::Optional<DataExtractor> +DWARFExpression::GetLocationExpression(addr_t load_function_start, + addr_t addr) const { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + std::unique_ptr<llvm::DWARFLocationTable> loctable_up = + m_dwarf_cu->GetLocationTable(m_data); + llvm::Optional<DataExtractor> result; + uint64_t offset = 0; + auto lookup_addr = + [&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> { + addr_t address = ReadAddressFromDebugAddrSection(m_dwarf_cu, index); + if (address == LLDB_INVALID_ADDRESS) + return llvm::None; + return llvm::object::SectionedAddress{address}; + }; + auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) { + if (!loc) { + LLDB_LOG_ERROR(log, loc.takeError(), "{0}"); + return true; + } + if (loc->Range) { + // This relocates low_pc and high_pc by adding the difference between the + // function file address, and the actual address it is loaded in memory. + addr_t slide = load_function_start - m_loclist_addresses->func_file_addr; + loc->Range->LowPC += slide; + loc->Range->HighPC += slide; + + if (loc->Range->LowPC <= addr && addr < loc->Range->HighPC) + result = ToDataExtractor(*loc, m_data.GetByteOrder(), + m_data.GetAddressByteSize()); + } + return !result; + }; + llvm::Error E = loctable_up->visitAbsoluteLocationList( + offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, + lookup_addr, process_list); + if (E) + LLDB_LOG_ERROR(log, std::move(E), "{0}"); + return result; } bool DWARFExpression::MatchesOperand(StackFrame &frame, const Instruction::Operand &operand) { using namespace OperandMatchers; - lldb::offset_t op_offset; - lldb::offset_t end_offset; - if (!GetOpAndEndOffsets(frame, op_offset, end_offset)) { - return false; - } - - if (!m_data.ValidOffset(op_offset) || op_offset >= end_offset) { - return false; - } - RegisterContextSP reg_ctx_sp = frame.GetRegisterContext(); if (!reg_ctx_sp) { return false; } - DataExtractor opcodes = m_data; + DataExtractor opcodes; + if (IsLocationList()) { + SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction); + if (!sc.function) + return false; + + addr_t load_function_start = + sc.function->GetAddressRange().GetBaseAddress().GetFileAddress(); + if (load_function_start == LLDB_INVALID_ADDRESS) + return false; + + addr_t pc = frame.GetFrameCodeAddress().GetLoadAddress( + frame.CalculateTarget().get()); + + if (llvm::Optional<DataExtractor> expr = GetLocationExpression(load_function_start, pc)) + opcodes = std::move(*expr); + else + return false; + } else + opcodes = m_data; + + + lldb::offset_t op_offset = 0; uint8_t opcode = opcodes.GetU8(&op_offset); if (opcode == DW_OP_fbreg) { diff --git a/lldb/source/Expression/Expression.cpp b/lldb/source/Expression/Expression.cpp index 8e1ef6958cc7..71369d0b9eec 100644 --- a/lldb/source/Expression/Expression.cpp +++ b/lldb/source/Expression/Expression.cpp @@ -12,18 +12,16 @@ using namespace lldb_private; -Expression::Expression(Target &target, ExpressionKind kind) - : m_kind(kind), - m_target_wp(target.shared_from_this()), +Expression::Expression(Target &target) + : m_target_wp(target.shared_from_this()), m_jit_start_addr(LLDB_INVALID_ADDRESS), m_jit_end_addr(LLDB_INVALID_ADDRESS) { // Can't make any kind of expression without a target. assert(m_target_wp.lock()); } -Expression::Expression(ExecutionContextScope &exe_scope, ExpressionKind kind) - : m_kind(kind), - m_target_wp(exe_scope.CalculateTarget()), +Expression::Expression(ExecutionContextScope &exe_scope) + : m_target_wp(exe_scope.CalculateTarget()), m_jit_start_addr(LLDB_INVALID_ADDRESS), m_jit_end_addr(LLDB_INVALID_ADDRESS) { assert(m_target_wp.lock()); diff --git a/lldb/source/Expression/FunctionCaller.cpp b/lldb/source/Expression/FunctionCaller.cpp index 203cfff63d80..dc80c8169d7d 100644 --- a/lldb/source/Expression/FunctionCaller.cpp +++ b/lldb/source/Expression/FunctionCaller.cpp @@ -29,14 +29,16 @@ using namespace lldb_private; +char FunctionCaller::ID; + // FunctionCaller constructor FunctionCaller::FunctionCaller(ExecutionContextScope &exe_scope, const CompilerType &return_type, const Address &functionAddress, const ValueList &arg_value_list, const char *name) - : Expression(exe_scope, eKindFunctionCaller), m_execution_unit_sp(), - m_parser(), m_jit_module_wp(), m_name(name ? name : "<unknown>"), + : Expression(exe_scope), m_execution_unit_sp(), m_parser(), + m_jit_module_wp(), m_name(name ? name : "<unknown>"), m_function_ptr(nullptr), m_function_addr(functionAddress), m_function_return_type(return_type), m_wrapper_function_name("__lldb_caller_function"), diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index b10628e10cc5..e033b90cfd8b 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -348,7 +348,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, return; } m_jitted_functions.push_back(JittedFunction( - function.getName().str().c_str(), external, (lldb::addr_t)fun_ptr)); + function.getName().str().c_str(), external, reinterpret_cast<uintptr_t>(fun_ptr))); } CommitAllocations(process_sp); @@ -728,8 +728,6 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames( if (best_alternate_mangled_name) { CPP_specs.push_back(best_alternate_mangled_name); } - - CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull)); } } @@ -977,30 +975,49 @@ IRExecutionUnit::FindSymbol(lldb_private::ConstString name, bool &missing_weak) void IRExecutionUnit::GetStaticInitializers( std::vector<lldb::addr_t> &static_initializers) { - if (llvm::GlobalVariable *global_ctors = - m_module->getNamedGlobal("llvm.global_ctors")) { - if (llvm::ConstantArray *ctor_array = llvm::dyn_cast<llvm::ConstantArray>( - global_ctors->getInitializer())) { - for (llvm::Use &ctor_use : ctor_array->operands()) { - if (llvm::ConstantStruct *ctor_struct = - llvm::dyn_cast<llvm::ConstantStruct>(ctor_use)) { - lldbassert(ctor_struct->getNumOperands() == - 3); // this is standardized - if (llvm::Function *ctor_function = - llvm::dyn_cast<llvm::Function>(ctor_struct->getOperand(1))) { - ConstString ctor_function_name_cs(ctor_function->getName().str()); - - for (JittedFunction &jitted_function : m_jitted_functions) { - if (ctor_function_name_cs == jitted_function.m_name) { - if (jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS) { - static_initializers.push_back(jitted_function.m_remote_addr); - } - break; - } - } - } - } + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + llvm::GlobalVariable *global_ctors = + m_module->getNamedGlobal("llvm.global_ctors"); + if (!global_ctors) { + LLDB_LOG(log, "Couldn't find llvm.global_ctors."); + return; + } + auto *ctor_array = + llvm::dyn_cast<llvm::ConstantArray>(global_ctors->getInitializer()); + if (!ctor_array) { + LLDB_LOG(log, "llvm.global_ctors not a ConstantArray."); + return; + } + + for (llvm::Use &ctor_use : ctor_array->operands()) { + auto *ctor_struct = llvm::dyn_cast<llvm::ConstantStruct>(ctor_use); + if (!ctor_struct) + continue; + // this is standardized + lldbassert(ctor_struct->getNumOperands() == 3); + auto *ctor_function = + llvm::dyn_cast<llvm::Function>(ctor_struct->getOperand(1)); + if (!ctor_function) { + LLDB_LOG(log, "global_ctor doesn't contain an llvm::Function"); + continue; + } + + ConstString ctor_function_name(ctor_function->getName().str()); + LLDB_LOG(log, "Looking for callable jitted function with name {0}.", + ctor_function_name); + + for (JittedFunction &jitted_function : m_jitted_functions) { + if (ctor_function_name != jitted_function.m_name) + continue; + if (jitted_function.m_remote_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Found jitted function with invalid address."); + continue; } + static_initializers.push_back(jitted_function.m_remote_addr); + LLDB_LOG(log, "Calling function at address {0:x}.", + jitted_function.m_remote_addr); + break; } } } diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 856c9a0244fb..b2e4be5e40fd 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -490,10 +490,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); bool saw_function_with_body = false; - - for (Module::iterator fi = module.begin(), fe = module.end(); fi != fe; - ++fi) { - if (fi->begin() != fi->end()) { + for (Function &f : module) { + if (f.begin() != f.end()) { if (saw_function_with_body) { LLDB_LOGF(log, "More than one function in the module has a body"); error.SetErrorToGenericError(); @@ -504,13 +502,11 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, } } - for (Function::iterator bbi = function.begin(), bbe = function.end(); - bbi != bbe; ++bbi) { - for (BasicBlock::iterator ii = bbi->begin(), ie = bbi->end(); ii != ie; - ++ii) { - switch (ii->getOpcode()) { + for (BasicBlock &bb : function) { + for (Instruction &ii : bb) { + switch (ii.getOpcode()) { default: { - LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&*ii).c_str()); + LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&ii).c_str()); error.SetErrorToGenericError(); error.SetErrorString(unsupported_opcode_error); return false; @@ -522,7 +518,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, case Instruction::PHI: break; case Instruction::Call: { - CallInst *call_inst = dyn_cast<CallInst>(ii); + CallInst *call_inst = dyn_cast<CallInst>(&ii); if (!call_inst) { error.SetErrorToGenericError(); @@ -532,7 +528,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, if (!CanIgnoreCall(call_inst) && !support_function_calls) { LLDB_LOGF(log, "Unsupported instruction: %s", - PrintValue(&*ii).c_str()); + PrintValue(&ii).c_str()); error.SetErrorToGenericError(); error.SetErrorString(unsupported_opcode_error); return false; @@ -541,7 +537,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, case Instruction::GetElementPtr: break; case Instruction::ICmp: { - ICmpInst *icmp_inst = dyn_cast<ICmpInst>(ii); + ICmpInst *icmp_inst = dyn_cast<ICmpInst>(&ii); if (!icmp_inst) { error.SetErrorToGenericError(); @@ -552,7 +548,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, switch (icmp_inst->getPredicate()) { default: { LLDB_LOGF(log, "Unsupported ICmp predicate: %s", - PrintValue(&*ii).c_str()); + PrintValue(&ii).c_str()); error.SetErrorToGenericError(); error.SetErrorString(unsupported_opcode_error); @@ -594,8 +590,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, break; } - for (int oi = 0, oe = ii->getNumOperands(); oi != oe; ++oi) { - Value *operand = ii->getOperand(oi); + for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) { + Value *operand = ii.getOperand(oi); Type *operand_type = operand->getType(); switch (operand_type->getTypeID()) { @@ -804,15 +800,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::Alloca: { - const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst); - - if (!alloca_inst) { - LLDB_LOGF(log, "getOpcode() returns Alloca, but instruction is not an " - "AllocaInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const AllocaInst *alloca_inst = cast<AllocaInst>(inst); if (alloca_inst->isArrayAllocation()) { LLDB_LOGF(log, @@ -875,16 +863,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } break; case Instruction::BitCast: case Instruction::ZExt: { - const CastInst *cast_inst = dyn_cast<CastInst>(inst); - - if (!cast_inst) { - LLDB_LOGF( - log, "getOpcode() returns %s, but instruction is not a BitCastInst", - cast_inst->getOpcodeName()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const CastInst *cast_inst = cast<CastInst>(inst); Value *source = cast_inst->getOperand(0); @@ -900,16 +879,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, frame.AssignValue(inst, S, module); } break; case Instruction::SExt: { - const CastInst *cast_inst = dyn_cast<CastInst>(inst); - - if (!cast_inst) { - LLDB_LOGF( - log, "getOpcode() returns %s, but instruction is not a BitCastInst", - cast_inst->getOpcodeName()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const CastInst *cast_inst = cast<CastInst>(inst); Value *source = cast_inst->getOperand(0); @@ -929,15 +899,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, frame.AssignValue(inst, S_signextend, module); } break; case Instruction::Br: { - const BranchInst *br_inst = dyn_cast<BranchInst>(inst); - - if (!br_inst) { - LLDB_LOGF( - log, "getOpcode() returns Br, but instruction is not a BranchInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const BranchInst *br_inst = cast<BranchInst>(inst); if (br_inst->isConditional()) { Value *condition = br_inst->getCondition(); @@ -971,15 +933,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } continue; case Instruction::PHI: { - const PHINode *phi_inst = dyn_cast<PHINode>(inst); - - if (!phi_inst) { - LLDB_LOGF(log, - "getOpcode() returns PHI, but instruction is not a PHINode"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const PHINode *phi_inst = cast<PHINode>(inst); if (!frame.m_prev_bb) { LLDB_LOGF(log, "Encountered PHI node without having jumped from another " @@ -1006,15 +960,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::GetElementPtr: { - const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst); - - if (!gep_inst) { - LLDB_LOGF(log, "getOpcode() returns GetElementPtr, but instruction is " - "not a GetElementPtrInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const GetElementPtrInst *gep_inst = cast<GetElementPtrInst>(inst); const Value *pointer_operand = gep_inst->getPointerOperand(); Type *src_elem_ty = gep_inst->getSourceElementType(); @@ -1076,16 +1022,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::ICmp: { - const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst); - - if (!icmp_inst) { - LLDB_LOGF( - log, - "getOpcode() returns ICmp, but instruction is not an ICmpInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const ICmpInst *icmp_inst = cast<ICmpInst>(inst); CmpInst::Predicate predicate = icmp_inst->getPredicate(); @@ -1172,16 +1109,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::IntToPtr: { - const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst); - - if (!int_to_ptr_inst) { - LLDB_LOGF(log, - "getOpcode() returns IntToPtr, but instruction is not an " - "IntToPtrInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const IntToPtrInst *int_to_ptr_inst = cast<IntToPtrInst>(inst); Value *src_operand = int_to_ptr_inst->getOperand(0); @@ -1203,16 +1131,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::PtrToInt: { - const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst); - - if (!ptr_to_int_inst) { - LLDB_LOGF(log, - "getOpcode() returns PtrToInt, but instruction is not an " - "PtrToIntInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const PtrToIntInst *ptr_to_int_inst = cast<PtrToIntInst>(inst); Value *src_operand = ptr_to_int_inst->getOperand(0); @@ -1234,16 +1153,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::Trunc: { - const TruncInst *trunc_inst = dyn_cast<TruncInst>(inst); - - if (!trunc_inst) { - LLDB_LOGF( - log, - "getOpcode() returns Trunc, but instruction is not a TruncInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const TruncInst *trunc_inst = cast<TruncInst>(inst); Value *src_operand = trunc_inst->getOperand(0); @@ -1265,15 +1175,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::Load: { - const LoadInst *load_inst = dyn_cast<LoadInst>(inst); - - if (!load_inst) { - LLDB_LOGF( - log, "getOpcode() returns Load, but instruction is not a LoadInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const LoadInst *load_inst = cast<LoadInst>(inst); // The semantics of Load are: // Create a region D that will contain the loaded data @@ -1355,16 +1257,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, return true; } case Instruction::Store: { - const StoreInst *store_inst = dyn_cast<StoreInst>(inst); - - if (!store_inst) { - LLDB_LOGF( - log, - "getOpcode() returns Store, but instruction is not a StoreInst"); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const StoreInst *store_inst = cast<StoreInst>(inst); // The semantics of Store are: // Resolve the region D containing the data to be stored @@ -1440,16 +1333,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } } break; case Instruction::Call: { - const CallInst *call_inst = dyn_cast<CallInst>(inst); - - if (!call_inst) { - LLDB_LOGF(log, - "getOpcode() returns %s, but instruction is not a CallInst", - inst->getOpcodeName()); - error.SetErrorToGenericError(); - error.SetErrorString(interpreter_internal_error); - return false; - } + const CallInst *call_inst = cast<CallInst>(inst); if (CanIgnoreCall(call_inst)) break; diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp index 5fdf452bf94e..02a875ec833b 100644 --- a/lldb/source/Expression/IRMemoryMap.cpp +++ b/lldb/source/Expression/IRMemoryMap.cpp @@ -328,9 +328,9 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment, case eAllocationPolicyMirror: process_sp = m_process_wp.lock(); LLDB_LOGF(log, - "IRMemoryMap::%s process_sp=0x%" PRIx64 + "IRMemoryMap::%s process_sp=0x%" PRIxPTR ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s", - __FUNCTION__, (lldb::addr_t)process_sp.get(), + __FUNCTION__, reinterpret_cast<uintptr_t>(process_sp.get()), process_sp && process_sp->CanJIT() ? "true" : "false", process_sp && process_sp->IsAlive() ? "true" : "false"); if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) { @@ -577,9 +577,9 @@ void IRMemoryMap::WriteMemory(lldb::addr_t process_address, if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { LLDB_LOGF(log, - "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 + "IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIxPTR ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")", - (uint64_t)process_address, (uint64_t)bytes, (uint64_t)size, + (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size, (uint64_t)allocation.m_process_start, (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); @@ -708,9 +708,9 @@ void IRMemoryMap::ReadMemory(uint8_t *bytes, lldb::addr_t process_address, if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) { LLDB_LOGF(log, - "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 + "IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIxPTR ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")", - (uint64_t)process_address, (uint64_t)bytes, (uint64_t)size, + (uint64_t)process_address, reinterpret_cast<uintptr_t>(bytes), (uint64_t)size, (uint64_t)allocation.m_process_start, (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); diff --git a/lldb/source/Expression/LLVMUserExpression.cpp b/lldb/source/Expression/LLVMUserExpression.cpp index 99e0c11df420..1fc878bbd616 100644 --- a/lldb/source/Expression/LLVMUserExpression.cpp +++ b/lldb/source/Expression/LLVMUserExpression.cpp @@ -35,20 +35,20 @@ using namespace lldb_private; +char LLVMUserExpression::ID; + LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options, - ExpressionKind kind) - : UserExpression(exe_scope, expr, prefix, language, desired_type, options, - kind), + const EvaluateExpressionOptions &options) + : UserExpression(exe_scope, expr, prefix, language, desired_type, options), m_stack_frame_bottom(LLDB_INVALID_ADDRESS), m_stack_frame_top(LLDB_INVALID_ADDRESS), m_allow_cxx(false), m_allow_objc(false), m_transformed_text(), m_execution_unit_sp(), - m_materializer_up(), m_jit_module_wp(), - m_can_interpret(false), m_materialized_address(LLDB_INVALID_ADDRESS) {} + m_materializer_up(), m_jit_module_wp(), m_can_interpret(false), + m_materialized_address(LLDB_INVALID_ADDRESS) {} LLVMUserExpression::~LLVMUserExpression() { if (m_target) { @@ -70,174 +70,172 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); - if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) { - lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; + if (m_jit_start_addr == LLDB_INVALID_ADDRESS && !m_can_interpret) { + diagnostic_manager.PutString( + eDiagnosticSeverityError, + "Expression can't be run, because there is no JIT compiled function"); + return lldb::eExpressionSetupError; + } - if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx, - struct_address)) { - diagnostic_manager.Printf( + lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; + + if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx, + struct_address)) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, + "errored out in %s, couldn't PrepareToExecuteJITExpression", + __FUNCTION__); + return lldb::eExpressionSetupError; + } + + lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; + lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; + + if (m_can_interpret) { + llvm::Module *module = m_execution_unit_sp->GetModule(); + llvm::Function *function = m_execution_unit_sp->GetFunction(); + + if (!module || !function) { + diagnostic_manager.PutString( eDiagnosticSeverityError, - "errored out in %s, couldn't PrepareToExecuteJITExpression", - __FUNCTION__); + "supposed to interpret, but nothing is there"); return lldb::eExpressionSetupError; } - lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; - lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; + Status interpreter_error; - if (m_can_interpret) { - llvm::Module *module = m_execution_unit_sp->GetModule(); - llvm::Function *function = m_execution_unit_sp->GetFunction(); + std::vector<lldb::addr_t> args; - if (!module || !function) { - diagnostic_manager.PutString( - eDiagnosticSeverityError, - "supposed to interpret, but nothing is there"); - return lldb::eExpressionSetupError; - } + if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "errored out in %s, couldn't AddArguments", + __FUNCTION__); + return lldb::eExpressionSetupError; + } - Status interpreter_error; + function_stack_bottom = m_stack_frame_bottom; + function_stack_top = m_stack_frame_top; - std::vector<lldb::addr_t> args; + IRInterpreter::Interpret(*module, *function, args, *m_execution_unit_sp, + interpreter_error, function_stack_bottom, + function_stack_top, exe_ctx); - if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "errored out in %s, couldn't AddArguments", - __FUNCTION__); - return lldb::eExpressionSetupError; - } + if (!interpreter_error.Success()) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "supposed to interpret, but failed: %s", + interpreter_error.AsCString()); + return lldb::eExpressionDiscarded; + } + } else { + if (!exe_ctx.HasThreadScope()) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "%s called with no thread selected", + __FUNCTION__); + return lldb::eExpressionSetupError; + } - function_stack_bottom = m_stack_frame_bottom; - function_stack_top = m_stack_frame_top; + Address wrapper_address(m_jit_start_addr); - IRInterpreter::Interpret(*module, *function, args, *m_execution_unit_sp, - interpreter_error, function_stack_bottom, - function_stack_top, exe_ctx); + std::vector<lldb::addr_t> args; - if (!interpreter_error.Success()) { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "supposed to interpret, but failed: %s", - interpreter_error.AsCString()); - return lldb::eExpressionDiscarded; - } - } else { - if (!exe_ctx.HasThreadScope()) { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "%s called with no thread selected", - __FUNCTION__); - return lldb::eExpressionSetupError; - } + if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "errored out in %s, couldn't AddArguments", + __FUNCTION__); + return lldb::eExpressionSetupError; + } - Address wrapper_address(m_jit_start_addr); + lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression( + exe_ctx.GetThreadRef(), wrapper_address, args, options, + shared_ptr_to_me)); - std::vector<lldb::addr_t> args; + StreamString ss; + if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) { + diagnostic_manager.PutString(eDiagnosticSeverityError, ss.GetString()); + return lldb::eExpressionSetupError; + } - if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "errored out in %s, couldn't AddArguments", - __FUNCTION__); - return lldb::eExpressionSetupError; - } + ThreadPlanCallUserExpression *user_expression_plan = + static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); - lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression( - exe_ctx.GetThreadRef(), wrapper_address, args, options, - shared_ptr_to_me)); + lldb::addr_t function_stack_pointer = + user_expression_plan->GetFunctionStackPointer(); - StreamString ss; - if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) { - diagnostic_manager.PutString(eDiagnosticSeverityError, ss.GetString()); - return lldb::eExpressionSetupError; - } + function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); + function_stack_top = function_stack_pointer; + + LLDB_LOGF(log, + "-- [UserExpression::Execute] Execution of expression begins --"); + + if (exe_ctx.GetProcessPtr()) + exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); + + lldb::ExpressionResults execution_result = + exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, + diagnostic_manager); + + if (exe_ctx.GetProcessPtr()) + exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); - ThreadPlanCallUserExpression *user_expression_plan = - static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); - - lldb::addr_t function_stack_pointer = - user_expression_plan->GetFunctionStackPointer(); - - function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); - function_stack_top = function_stack_pointer; - - LLDB_LOGF( - log, - "-- [UserExpression::Execute] Execution of expression begins --"); - - if (exe_ctx.GetProcessPtr()) - exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); - - lldb::ExpressionResults execution_result = - exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, - diagnostic_manager); - - if (exe_ctx.GetProcessPtr()) - exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); - - LLDB_LOGF(log, "-- [UserExpression::Execute] Execution of expression " - "completed --"); - - if (execution_result == lldb::eExpressionInterrupted || - execution_result == lldb::eExpressionHitBreakpoint) { - const char *error_desc = nullptr; - - if (call_plan_sp) { - lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); - if (real_stop_info_sp) - error_desc = real_stop_info_sp->GetDescription(); - } - if (error_desc) - diagnostic_manager.Printf(eDiagnosticSeverityError, - "Execution was interrupted, reason: %s.", - error_desc); - else - diagnostic_manager.PutString(eDiagnosticSeverityError, - "Execution was interrupted."); - - if ((execution_result == lldb::eExpressionInterrupted && - options.DoesUnwindOnError()) || - (execution_result == lldb::eExpressionHitBreakpoint && - options.DoesIgnoreBreakpoints())) - diagnostic_manager.AppendMessageToDiagnostic( - "The process has been returned to the state before expression " - "evaluation."); - else { - if (execution_result == lldb::eExpressionHitBreakpoint) - user_expression_plan->TransferExpressionOwnership(); - diagnostic_manager.AppendMessageToDiagnostic( - "The process has been left at the point where it was " - "interrupted, " - "use \"thread return -x\" to return to the state before " - "expression evaluation."); - } - - return execution_result; - } else if (execution_result == lldb::eExpressionStoppedForDebug) { - diagnostic_manager.PutString( - eDiagnosticSeverityRemark, - "Execution was halted at the first instruction of the expression " - "function because \"debug\" was requested.\n" - "Use \"thread return -x\" to return to the state before expression " + LLDB_LOGF(log, "-- [UserExpression::Execute] Execution of expression " + "completed --"); + + if (execution_result == lldb::eExpressionInterrupted || + execution_result == lldb::eExpressionHitBreakpoint) { + const char *error_desc = nullptr; + + if (call_plan_sp) { + lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); + if (real_stop_info_sp) + error_desc = real_stop_info_sp->GetDescription(); + } + if (error_desc) + diagnostic_manager.Printf(eDiagnosticSeverityError, + "Execution was interrupted, reason: %s.", + error_desc); + else + diagnostic_manager.PutString(eDiagnosticSeverityError, + "Execution was interrupted."); + + if ((execution_result == lldb::eExpressionInterrupted && + options.DoesUnwindOnError()) || + (execution_result == lldb::eExpressionHitBreakpoint && + options.DoesIgnoreBreakpoints())) + diagnostic_manager.AppendMessageToDiagnostic( + "The process has been returned to the state before expression " "evaluation."); - return execution_result; - } else if (execution_result != lldb::eExpressionCompleted) { - diagnostic_manager.Printf( - eDiagnosticSeverityError, - "Couldn't execute function; result was %s", - Process::ExecutionResultAsCString(execution_result)); - return execution_result; + else { + if (execution_result == lldb::eExpressionHitBreakpoint) + user_expression_plan->TransferExpressionOwnership(); + diagnostic_manager.AppendMessageToDiagnostic( + "The process has been left at the point where it was " + "interrupted, " + "use \"thread return -x\" to return to the state before " + "expression evaluation."); } - } - if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result, - function_stack_bottom, function_stack_top)) { - return lldb::eExpressionCompleted; - } else { - return lldb::eExpressionResultUnavailable; + return execution_result; + } else if (execution_result == lldb::eExpressionStoppedForDebug) { + diagnostic_manager.PutString( + eDiagnosticSeverityRemark, + "Execution was halted at the first instruction of the expression " + "function because \"debug\" was requested.\n" + "Use \"thread return -x\" to return to the state before expression " + "evaluation."); + return execution_result; + } else if (execution_result != lldb::eExpressionCompleted) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, "Couldn't execute function; result was %s", + Process::ExecutionResultAsCString(execution_result)); + return execution_result; } + } + + if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result, + function_stack_bottom, function_stack_top)) { + return lldb::eExpressionCompleted; } else { - diagnostic_manager.PutString( - eDiagnosticSeverityError, - "Expression can't be run, because there is no JIT compiled function"); - return lldb::eExpressionSetupError; + return lldb::eExpressionResultUnavailable; } } diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp index 4f81ee3e56dd..fcd083684738 100644 --- a/lldb/source/Expression/REPL.cpp +++ b/lldb/source/Expression/REPL.cpp @@ -283,6 +283,8 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { PersistentExpressionState *persistent_state = m_target.GetPersistentExpressionStateForLanguage(GetLanguage()); + if (!persistent_state) + return; const size_t var_count_before = persistent_state->GetSize(); diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp index e2d1d2f2b3d2..3b507da8e4ab 100644 --- a/lldb/source/Expression/UserExpression.cpp +++ b/lldb/source/Expression/UserExpression.cpp @@ -46,13 +46,14 @@ using namespace lldb_private; +char UserExpression::ID; + UserExpression::UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options, - ExpressionKind kind) - : Expression(exe_scope, kind), m_expr_text(expr), m_expr_prefix(prefix), + const EvaluateExpressionOptions &options) + : Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix), m_language(language), m_desired_type(desired_type), m_options(options) {} UserExpression::~UserExpression() {} @@ -83,10 +84,9 @@ bool UserExpression::LockAndCheckContext(ExecutionContext &exe_ctx, if (m_address.IsValid()) { if (!frame_sp) return false; - else - return (0 == Address::CompareLoadAddress(m_address, - frame_sp->GetFrameCodeAddress(), - target_sp.get())); + return (Address::CompareLoadAddress(m_address, + frame_sp->GetFrameCodeAddress(), + target_sp.get()) == 0); } return true; @@ -396,8 +396,9 @@ UserExpression::Execute(DiagnosticManager &diagnostic_manager, diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); Target *target = exe_ctx.GetTargetPtr(); if (options.GetResultIsInternal() && result_var && target) { - target->GetPersistentExpressionStateForLanguage(m_language) - ->RemovePersistentVariable(result_var); + if (auto *persistent_state = + target->GetPersistentExpressionStateForLanguage(m_language)) + persistent_state->RemovePersistentVariable(result_var); } return expr_result; } diff --git a/lldb/source/Expression/UtilityFunction.cpp b/lldb/source/Expression/UtilityFunction.cpp index aac8b33a6bfa..2dbc0e9d73ed 100644 --- a/lldb/source/Expression/UtilityFunction.cpp +++ b/lldb/source/Expression/UtilityFunction.cpp @@ -31,6 +31,8 @@ using namespace lldb_private; using namespace lldb; +char UtilityFunction::ID; + /// Constructor /// /// \param[in] text @@ -39,12 +41,9 @@ using namespace lldb; /// \param[in] name /// The name of the function, as used in the text. UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope, - const char *text, const char *name, - ExpressionKind kind) - : Expression(exe_scope, kind), - m_execution_unit_sp(), m_jit_module_wp(), - m_function_text(), - m_function_name(name) {} + const char *text, const char *name) + : Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(), + m_function_text(), m_function_name(name) {} UtilityFunction::~UtilityFunction() { lldb::ProcessSP process_sp(m_jit_process_wp.lock()); |