Index: lldb/trunk/include/lldb/Expression/DWARFExpression.h =================================================================== --- lldb/trunk/include/lldb/Expression/DWARFExpression.h +++ lldb/trunk/include/lldb/Expression/DWARFExpression.h @@ -17,12 +17,14 @@ #include "lldb/Core/Error.h" #include "lldb/Core/Scalar.h" +class DWARFCompileUnit; + namespace lldb_private { +class ClangExpressionDeclMap; class ClangExpressionVariable; class ClangExpressionVariableList; -class ClangExpressionDeclMap; //---------------------------------------------------------------------- /// @class DWARFExpression DWARFExpression.h "lldb/Expression/DWARFExpression.h" @@ -43,7 +45,7 @@ //------------------------------------------------------------------ /// Constructor //------------------------------------------------------------------ - DWARFExpression(); + explicit DWARFExpression(DWARFCompileUnit* dwarf_cu); //------------------------------------------------------------------ /// Constructor @@ -60,6 +62,7 @@ //------------------------------------------------------------------ DWARFExpression(lldb::ModuleSP module, const DataExtractor& data, + DWARFCompileUnit* dwarf_cu, lldb::offset_t data_offset, lldb::offset_t data_length); @@ -356,6 +359,7 @@ RegisterContext *reg_ctx, lldb::ModuleSP opcode_ctx, const DataExtractor& opcodes, + DWARFCompileUnit* dwarf_cu, const lldb::offset_t offset, const lldb::offset_t length, const lldb::RegisterKind reg_set, @@ -436,6 +440,9 @@ lldb::ModuleWP m_module_wp; ///< Module which defined this expression. DataExtractor m_data; ///< A data extractor capable of reading opcode bytes + DWARFCompileUnit* m_dwarf_cu; ///< The DWARF compile unit this expression belongs to. It is used + ///< to evaluate values indexing into the .debug_addr section (e.g. + ///< DW_OP_GNU_addr_index lldb::RegisterKind m_reg_kind; ///< One of the defines that starts with LLDB_REGKIND_ lldb::addr_t m_loclist_slide; ///< A value used to slide the location list offsets so that ///< they are relative to the object that owns the location list Index: lldb/trunk/source/Expression/DWARFExpression.cpp =================================================================== --- lldb/trunk/source/Expression/DWARFExpression.cpp +++ lldb/trunk/source/Expression/DWARFExpression.cpp @@ -38,6 +38,8 @@ #include "lldb/Target/StackID.h" #include "lldb/Target/Thread.h" +#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h" + using namespace lldb; using namespace lldb_private; @@ -196,6 +198,7 @@ case 0x98: return "DW_OP_call2"; case 0x99: return "DW_OP_call4"; case 0x9a: return "DW_OP_call_ref"; + case 0xfb: return "DW_OP_GNU_addr_index"; // case DW_OP_APPLE_array_ref: return "DW_OP_APPLE_array_ref"; // case DW_OP_APPLE_extern: return "DW_OP_APPLE_extern"; case DW_OP_APPLE_uninit: return "DW_OP_APPLE_uninit"; @@ -219,9 +222,10 @@ //---------------------------------------------------------------------- // DWARFExpression constructor //---------------------------------------------------------------------- -DWARFExpression::DWARFExpression() : +DWARFExpression::DWARFExpression(DWARFCompileUnit* dwarf_cu) : m_module_wp(), m_data(), + m_dwarf_cu(dwarf_cu), m_reg_kind (eRegisterKindDWARF), m_loclist_slide (LLDB_INVALID_ADDRESS) { @@ -230,15 +234,21 @@ DWARFExpression::DWARFExpression(const DWARFExpression& rhs) : m_module_wp(rhs.m_module_wp), m_data(rhs.m_data), + m_dwarf_cu(rhs.m_dwarf_cu), m_reg_kind (rhs.m_reg_kind), m_loclist_slide(rhs.m_loclist_slide) { } -DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) : +DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp, + const DataExtractor& data, + DWARFCompileUnit* dwarf_cu, + lldb::offset_t data_offset, + lldb::offset_t data_length) : m_module_wp(), m_data(data, data_offset, data_length), + m_dwarf_cu(dwarf_cu), m_reg_kind (eRegisterKindDWARF), m_loclist_slide(LLDB_INVALID_ADDRESS) { @@ -624,6 +634,9 @@ case DW_OP_form_tls_address: s->PutCString("DW_OP_form_tls_address"); // 0x9b break; + case DW_OP_GNU_addr_index: // 0xfb + s->Printf("DW_OP_GNU_addr_index(0x%" PRIx64 ")", m_data.GetULEB128(&offset)); + break; case DW_OP_GNU_push_tls_address: s->PutCString("DW_OP_GNU_push_tls_address"); // 0xe0 break; @@ -1027,6 +1040,7 @@ case DW_OP_regx: // 0x90 1 ULEB128 register case DW_OP_fbreg: // 0x91 1 SLEB128 offset case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed + case DW_OP_GNU_addr_index: // 0xfb 1 ULEB128 index data.Skip_LEB128(&offset); return offset - data_offset; @@ -1051,7 +1065,8 @@ } lldb::addr_t -DWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const +DWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, + bool &error) const { error = false; if (IsLocationList()) @@ -1070,6 +1085,25 @@ else ++curr_op_addr_idx; } + else if (op == DW_OP_GNU_addr_index) + { + uint64_t index = m_data.GetULEB128(&offset); + if (curr_op_addr_idx == op_addr_idx) + { + if (!m_dwarf_cu) + { + error = true; + break; + } + + uint32_t index_size = m_dwarf_cu->GetAddressByteSize(); + dw_offset_t addr_base = m_dwarf_cu->GetAddrBase(); + lldb::offset_t offset = addr_base + index * index_size; + return m_dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset, index_size); + } + else + ++curr_op_addr_idx; + } else { const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op); @@ -1104,7 +1138,7 @@ // So first we copy the data into a heap buffer std::unique_ptr head_data_ap (new DataBufferHeap (m_data.GetDataStart(), - m_data.GetByteSize())); + m_data.GetByteSize())); // Make en encoder so we can write the address into the buffer using // the correct byte order (endianness) @@ -1310,7 +1344,19 @@ if (length > 0 && lo_pc <= pc && pc < hi_pc) { - return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr); + return DWARFExpression::Evaluate (exe_ctx, + expr_locals, + decl_map, + reg_ctx, + module_sp, + m_data, + m_dwarf_cu, + offset, + length, + m_reg_kind, + initial_value_ptr, + result, + error_ptr); } offset += length; } @@ -1322,7 +1368,19 @@ } // Not a location list, just a single expression. - return DWARFExpression::Evaluate (exe_ctx, expr_locals, decl_map, reg_ctx, module_sp, m_data, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr); + return DWARFExpression::Evaluate (exe_ctx, + expr_locals, + decl_map, + reg_ctx, + module_sp, + m_data, + m_dwarf_cu, + 0, + m_data.GetByteSize(), + m_reg_kind, + initial_value_ptr, + result, + error_ptr); } @@ -1336,6 +1394,7 @@ RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor& opcodes, + DWARFCompileUnit* dwarf_cu, const lldb::offset_t opcodes_offset, const lldb::offset_t opcodes_length, const lldb::RegisterKind reg_kind, @@ -2950,6 +3009,32 @@ } break; + //---------------------------------------------------------------------- + // OPCODE: DW_OP_GNU_addr_index + // OPERANDS: 1 + // ULEB128: index to the .debug_addr section + // DESCRIPTION: Pushes an address to the stack from the .debug_addr + // section with the base address specified by the DW_AT_addr_base + // attribute and the 0 based index is the ULEB128 encoded index. + //---------------------------------------------------------------------- + case DW_OP_GNU_addr_index: + { + if (!dwarf_cu) + { + if (error_ptr) + error_ptr->SetErrorString ("DW_OP_GNU_addr_index found without a compile being specified"); + return false; + } + uint64_t index = opcodes.GetULEB128(&offset); + uint32_t index_size = dwarf_cu->GetAddressByteSize(); + dw_offset_t addr_base = dwarf_cu->GetAddrBase(); + lldb::offset_t offset = addr_base + index * index_size; + uint64_t value = dwarf_cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset, index_size); + stack.push_back(Scalar(value)); + stack.back().SetValueType(Value::eValueTypeFileAddress); + } + break; + default: if (log) log->Printf("Unhandled opcode %s in DWARFExpression.", DW_OP_value_to_name(op)); Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -1488,7 +1488,11 @@ unwindplan_regloc.GetDWARFExpressionLength(), process->GetByteOrder(), process->GetAddressByteSize()); ModuleSP opcode_ctx; - DWARFExpression dwarfexpr (opcode_ctx, dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength()); + DWARFExpression dwarfexpr (opcode_ctx, + dwarfdata, + nullptr, + 0, + unwindplan_regloc.GetDWARFExpressionLength()); dwarfexpr.SetRegisterKind (unwindplan_registerkind); Value result; Error error; @@ -1784,7 +1788,11 @@ row->GetCFAValue().GetDWARFExpressionLength(), process->GetByteOrder(), process->GetAddressByteSize()); ModuleSP opcode_ctx; - DWARFExpression dwarfexpr (opcode_ctx, dwarfdata, 0, row->GetCFAValue().GetDWARFExpressionLength()); + DWARFExpression dwarfexpr (opcode_ctx, + dwarfdata, + nullptr, + 0, + row->GetCFAValue().GetDWARFExpressionLength()); dwarfexpr.SetRegisterKind (row_register_kind); Value result; Error error; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp @@ -149,6 +149,8 @@ size = 128; break; case DW_OP_regx: size = 128; break; + case DW_OP_GNU_addr_index: + size = 128; break; default: s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); return 1; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -4013,7 +4013,7 @@ Declaration decl; uint32_t i; lldb::user_id_t type_uid = LLDB_INVALID_UID; - DWARFExpression location; + DWARFExpression location(dwarf_cu); bool is_external = false; bool is_artificial = false; bool location_is_const_value_data = false; Index: lldb/trunk/source/Symbol/ClangASTContext.cpp =================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp +++ lldb/trunk/source/Symbol/ClangASTContext.cpp @@ -9616,7 +9616,7 @@ int call_file = 0; int call_line = 0; int call_column = 0; - DWARFExpression frame_base; + DWARFExpression frame_base(dwarf_cu); assert (die->Tag() == DW_TAG_subprogram); @@ -9835,6 +9835,7 @@ NULL, // RegisterContext * module_sp, debug_info_data, + dwarf_cu, block_offset, block_length, eRegisterKindDWARF, @@ -10204,7 +10205,7 @@ if (num_attributes > 0) { Declaration decl; - DWARFExpression location; + DWARFExpression location(dwarf_cu); lldb::user_id_t encoding_uid = LLDB_INVALID_UID; AccessType accessibility = default_accessibility; bool is_virtual = false; @@ -10237,6 +10238,7 @@ NULL, module_sp, debug_info_data, + dwarf_cu, block_offset, block_length, eRegisterKindDWARF, Index: lldb/trunk/source/Symbol/Function.cpp =================================================================== --- lldb/trunk/source/Symbol/Function.cpp +++ lldb/trunk/source/Symbol/Function.cpp @@ -217,7 +217,7 @@ m_mangled (mangled), m_block (func_uid), m_range (range), - m_frame_base (), + m_frame_base (nullptr), m_flags (), m_prologue_byte_size (0) { @@ -241,7 +241,7 @@ m_mangled (ConstString(mangled), true), m_block (func_uid), m_range (range), - m_frame_base (), + m_frame_base (nullptr), m_flags (), m_prologue_byte_size (0) {