124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFAbbreviationDeclaration.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/dwarf.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFFormValue.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() :
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_code  (InvalidCode),
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_tag   (0),
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_has_children (0),
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_attributes()
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) :
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_code  (InvalidCode),
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_tag   (tag),
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_has_children (has_children),
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_attributes()
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
3536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonDWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr)
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
4136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonDWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_code = code;
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_attributes.clear();
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_code)
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_tag = data.GetULEB128(offset_ptr);
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_has_children = data.GetU8(offset_ptr);
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (data.ValidOffset(*offset_ptr))
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            dw_attr_t attr = data.GetULEB128(offset_ptr);
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            dw_form_t form = data.GetULEB128(offset_ptr);
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (attr && form)
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                m_attributes.push_back(DWARFAttribute(attr, form));
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return m_tag != 0;
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_tag = 0;
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_has_children = 0;
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::Dump(Stream *s)  const
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  *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;
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  DWARFAttribute::const_iterator pos;
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      *ostrm_ptr << "      " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl;
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  *ostrm_ptr << std::endl;
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::IsValid()
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_code != 0 && m_tag != 0;
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx)
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_code = abbr_decl.Code();  // Invalidate the code since that can't be copied safely.
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_tag = abbr_decl.Tag();
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_has_children = abbr_decl.HasChildren();
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t num_abbr_decl_attributes = attributes.size();
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_attr_t attr;
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_form_t form;
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i = 0; i < num_abbr_decl_attributes; ++i)
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        attributes[i].get(attr, form);
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (attr)
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_AT_location:
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_AT_frame_base:
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Only add these if they are location expressions (have a single
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // value) and not location lists (have a lists of location
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // expressions which are only valid over specific address ranges)
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (DWARFFormValue::IsBlockForm(form))
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                m_attributes.push_back(DWARFAttribute(attr, form));
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_AT_low_pc:
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_AT_high_pc:
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_AT_ranges:
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case DW_AT_entry_pc:
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Don't add these attributes
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (i >= idx)
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Fall through and add attribute
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Add anything that isn't address related
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_attributes.push_back(DWARFAttribute(attr, form));
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::CopyChangingStringToStrp(
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const DWARFAbbreviationDeclaration& abbr_decl,
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const DataExtractor& debug_info_data,
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_offset_t debug_info_offset,
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const DWARFCompileUnit* cu,
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t strp_min_len
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_code = InvalidCode;
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_tag = abbr_decl.Tag();
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_has_children = abbr_decl.HasChildren();
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t num_abbr_decl_attributes = attributes.size();
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_attr_t attr;
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_form_t form;
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
15836da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    lldb::offset_t offset = debug_info_offset;
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i = 0; i < num_abbr_decl_attributes; ++i)
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        attributes[i].get(attr, form);
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        dw_offset_t attr_offset = offset;
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (form == DW_FORM_string && ((offset - attr_offset) >= strp_min_len))
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_attributes.push_back(DWARFAttribute(attr, DW_FORM_strp));
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_attributes.push_back(DWARFAttribute(attr, form));
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t kNumAttributes = m_attributes.size();
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i = 0; i < kNumAttributes; ++i)
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_attributes[i].get_attr() == attr)
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return i;
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return DW_INVALID_INDEX;
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return Tag()            == rhs.Tag()
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        && HasChildren()    == rhs.HasChildren()
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        && Attributes()     == rhs.Attributes();
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#if 0
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclaration::Append(BinaryStreamBuf& out_buff) const
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    out_buff.Append32_as_ULEB128(Code());
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    out_buff.Append32_as_ULEB128(Tag());
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    out_buff.Append8(HasChildren());
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t kNumAttributes = m_attributes.size();
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (uint32_t i = 0; i < kNumAttributes; ++i)
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        out_buff.Append32_as_ULEB128(m_attributes[i].attr());
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        out_buff.Append32_as_ULEB128(m_attributes[i].form());
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif  // 0
212