[Lldb-commits] [lldb] r245932 - Handle DW_OP_GNU_addr_index in DWARF expressions

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 25 04:46:06 PDT 2015


Author: tberghammer
Date: Tue Aug 25 06:46:06 2015
New Revision: 245932

URL: http://llvm.org/viewvc/llvm-project?rev=245932&view=rev
Log:
Handle DW_OP_GNU_addr_index in DWARF expressions

Differential revision: http://reviews.llvm.org/D12290

Modified:
    lldb/trunk/include/lldb/Expression/DWARFExpression.h
    lldb/trunk/source/Expression/DWARFExpression.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/Function.cpp

Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Tue Aug 25 06:46:06 2015
@@ -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 @@ public:
     //------------------------------------------------------------------
     /// Constructor
     //------------------------------------------------------------------
-    DWARFExpression();
+    explicit DWARFExpression(DWARFCompileUnit* dwarf_cu);
 
     //------------------------------------------------------------------
     /// Constructor
@@ -60,6 +62,7 @@ public:
     //------------------------------------------------------------------
     DWARFExpression(lldb::ModuleSP module,
                     const DataExtractor& data,
+                    DWARFCompileUnit* dwarf_cu,
                     lldb::offset_t data_offset,
                     lldb::offset_t data_length);
 
@@ -356,6 +359,7 @@ public:
               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 @@ protected:
 
     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

Modified: lldb/trunk/source/Expression/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/source/Expression/DWARFExpression.cpp (original)
+++ lldb/trunk/source/Expression/DWARFExpression.cpp Tue Aug 25 06:46:06 2015
@@ -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 @@ DW_OP_value_to_name (uint32_t val)
     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 @@ DW_OP_value_to_name (uint32_t val)
 //----------------------------------------------------------------------
 // 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() :
 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 @@ DWARFExpression::DumpLocation (Stream *s
         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 @@ GetOpcodeDataSize (const DataExtractor &
         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 @@ GetOpcodeDataSize (const DataExtractor &
 }
 
 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 @@ DWARFExpression::GetLocation_DW_OP_addr
             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 @@ DWARFExpression::Update_DW_OP_addr (lldb
             
             // So first we copy the data into a heap buffer
             std::unique_ptr<DataBufferHeap> 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 @@ DWARFExpression::Evaluate
 
                     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 @@ DWARFExpression::Evaluate
     }
 
     // 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 @@ DWARFExpression::Evaluate
     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 @@ DWARFExpression::Evaluate
             }
             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));

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue Aug 25 06:46:06 2015
@@ -1488,7 +1488,11 @@ RegisterContextLLDB::SavedLocationForReg
                                  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 @@ RegisterContextLLDB::ReadCFAValueForRow
                                      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;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp Tue Aug 25 06:46:06 2015
@@ -149,6 +149,8 @@ print_dwarf_exp_op (Stream &s,
             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;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Aug 25 06:46:06 2015
@@ -4013,7 +4013,7 @@ SymbolFileDWARF::ParseVariableDIE
             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;

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Aug 25 06:46:06 2015
@@ -9616,7 +9616,7 @@ ClangASTContext::ParseFunctionFromDWARF
     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 @@ ClangASTContext::ParseChildMembers (cons
                                                                       NULL, // RegisterContext *
                                                                       module_sp,
                                                                       debug_info_data,
+                                                                      dwarf_cu,
                                                                       block_offset,
                                                                       block_length,
                                                                       eRegisterKindDWARF,
@@ -10204,7 +10205,7 @@ ClangASTContext::ParseChildMembers (cons
                 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 @@ ClangASTContext::ParseChildMembers (cons
                                                                        NULL,
                                                                        module_sp,
                                                                        debug_info_data,
+                                                                       dwarf_cu,
                                                                        block_offset,
                                                                        block_length,
                                                                        eRegisterKindDWARF,

Modified: lldb/trunk/source/Symbol/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=245932&r1=245931&r2=245932&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Function.cpp (original)
+++ lldb/trunk/source/Symbol/Function.cpp Tue Aug 25 06:46:06 2015
@@ -217,7 +217,7 @@ Function::Function
     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 @@ Function::Function
     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)
 {




More information about the lldb-commits mailing list