Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "DWARFAbbreviationDeclaration.h"
     11 
     12 #include "lldb/Core/dwarf.h"
     13 
     14 #include "DWARFFormValue.h"
     15 
     16 using namespace lldb_private;
     17 
     18 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() :
     19     m_code  (InvalidCode),
     20     m_tag   (0),
     21     m_has_children (0),
     22     m_attributes()
     23 {
     24 }
     25 
     26 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) :
     27     m_code  (InvalidCode),
     28     m_tag   (tag),
     29     m_has_children (has_children),
     30     m_attributes()
     31 {
     32 }
     33 
     34 bool
     35 DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr)
     36 {
     37     return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
     38 }
     39 
     40 bool
     41 DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
     42 {
     43     m_code = code;
     44     m_attributes.clear();
     45     if (m_code)
     46     {
     47         m_tag = data.GetULEB128(offset_ptr);
     48         m_has_children = data.GetU8(offset_ptr);
     49 
     50         while (data.ValidOffset(*offset_ptr))
     51         {
     52             dw_attr_t attr = data.GetULEB128(offset_ptr);
     53             dw_form_t form = data.GetULEB128(offset_ptr);
     54 
     55             if (attr && form)
     56                 m_attributes.push_back(DWARFAttribute(attr, form));
     57             else
     58                 break;
     59         }
     60 
     61         return m_tag != 0;
     62     }
     63     else
     64     {
     65         m_tag = 0;
     66         m_has_children = 0;
     67     }
     68 
     69     return false;
     70 }
     71 
     72 
     73 void
     74 DWARFAbbreviationDeclaration::Dump(Stream *s)  const
     75 {
     76 //  *ostrm_ptr << std::setfill(' ') << std::dec << '[' << std::setw(3) << std::right << m_code << ']' << ' ' << std::setw(30) << std::left << DW_TAG_value_to_name(m_tag) << DW_CHILDREN_value_to_name(m_has_children) << std::endl;
     77 //
     78 //  DWARFAttribute::const_iterator pos;
     79 //
     80 //  for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
     81 //      *ostrm_ptr << "      " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl;
     82 //
     83 //  *ostrm_ptr << std::endl;
     84 }
     85 
     86 
     87 
     88 bool
     89 DWARFAbbreviationDeclaration::IsValid()
     90 {
     91     return m_code != 0 && m_tag != 0;
     92 }
     93 
     94 
     95 void
     96 DWARFAbbreviationDeclaration::CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx)
     97 {
     98     m_code = abbr_decl.Code();  // Invalidate the code since that can't be copied safely.
     99     m_tag = abbr_decl.Tag();
    100     m_has_children = abbr_decl.HasChildren();
    101 
    102     const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
    103     const uint32_t num_abbr_decl_attributes = attributes.size();
    104 
    105     dw_attr_t attr;
    106     dw_form_t form;
    107     uint32_t i;
    108 
    109     for (i = 0; i < num_abbr_decl_attributes; ++i)
    110     {
    111         attributes[i].get(attr, form);
    112         switch (attr)
    113         {
    114         case DW_AT_location:
    115         case DW_AT_frame_base:
    116             // Only add these if they are location expressions (have a single
    117             // value) and not location lists (have a lists of location
    118             // expressions which are only valid over specific address ranges)
    119             if (DWARFFormValue::IsBlockForm(form))
    120                 m_attributes.push_back(DWARFAttribute(attr, form));
    121             break;
    122 
    123         case DW_AT_low_pc:
    124         case DW_AT_high_pc:
    125         case DW_AT_ranges:
    126         case DW_AT_entry_pc:
    127             // Don't add these attributes
    128             if (i >= idx)
    129                 break;
    130             // Fall through and add attribute
    131         default:
    132             // Add anything that isn't address related
    133             m_attributes.push_back(DWARFAttribute(attr, form));
    134             break;
    135         }
    136     }
    137 }
    138 
    139 void
    140 DWARFAbbreviationDeclaration::CopyChangingStringToStrp(
    141     const DWARFAbbreviationDeclaration& abbr_decl,
    142     const DataExtractor& debug_info_data,
    143     dw_offset_t debug_info_offset,
    144     const DWARFCompileUnit* cu,
    145     const uint32_t strp_min_len
    146 )
    147 {
    148     m_code = InvalidCode;
    149     m_tag = abbr_decl.Tag();
    150     m_has_children = abbr_decl.HasChildren();
    151 
    152     const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
    153     const uint32_t num_abbr_decl_attributes = attributes.size();
    154 
    155     dw_attr_t attr;
    156     dw_form_t form;
    157     uint32_t i;
    158     lldb::offset_t offset = debug_info_offset;
    159 
    160     for (i = 0; i < num_abbr_decl_attributes; ++i)
    161     {
    162         attributes[i].get(attr, form);
    163         dw_offset_t attr_offset = offset;
    164         DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
    165 
    166         if (form == DW_FORM_string && ((offset - attr_offset) >= strp_min_len))
    167             m_attributes.push_back(DWARFAttribute(attr, DW_FORM_strp));
    168         else
    169             m_attributes.push_back(DWARFAttribute(attr, form));
    170     }
    171 }
    172 
    173 
    174 uint32_t
    175 DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const
    176 {
    177     uint32_t i;
    178     const uint32_t kNumAttributes = m_attributes.size();
    179     for (i = 0; i < kNumAttributes; ++i)
    180     {
    181         if (m_attributes[i].get_attr() == attr)
    182             return i;
    183     }
    184     return DW_INVALID_INDEX;
    185 }
    186 
    187 
    188 bool
    189 DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const
    190 {
    191     return Tag()            == rhs.Tag()
    192         && HasChildren()    == rhs.HasChildren()
    193         && Attributes()     == rhs.Attributes();
    194 }
    195 
    196 #if 0
    197 DWARFAbbreviationDeclaration::Append(BinaryStreamBuf& out_buff) const
    198 {
    199     out_buff.Append32_as_ULEB128(Code());
    200     out_buff.Append32_as_ULEB128(Tag());
    201     out_buff.Append8(HasChildren());
    202     const uint32_t kNumAttributes = m_attributes.size();
    203     for (uint32_t i = 0; i < kNumAttributes; ++i)
    204     {
    205         out_buff.Append32_as_ULEB128(m_attributes[i].attr());
    206         out_buff.Append32_as_ULEB128(m_attributes[i].form());
    207     }
    208     out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
    209     out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
    210 }
    211 #endif  // 0
    212