Initial checkin of lldb code from internal Apple repo.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@105619 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
new file mode 100644
index 0000000..989e494
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -0,0 +1,211 @@
+//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFAbbreviationDeclaration.h"
+
+#include "lldb/Core/dwarf.h"
+
+#include "DWARFFormValue.h"
+
+using namespace lldb_private;
+
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() :
+    m_code  (InvalidCode),
+    m_tag   (0),
+    m_has_children (0),
+    m_attributes()
+{
+}
+
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) :
+    m_code  (InvalidCode),
+    m_tag   (tag),
+    m_has_children (has_children),
+    m_attributes()
+{
+}
+
+bool
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+{
+    return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
+}
+
+bool
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code)
+{
+    m_code = code;
+    m_attributes.clear();
+    if (m_code)
+    {
+        m_tag = data.GetULEB128(offset_ptr);
+        m_has_children = data.GetU8(offset_ptr);
+
+        while (data.ValidOffset(*offset_ptr))
+        {
+            dw_attr_t attr = data.GetULEB128(offset_ptr);
+            dw_form_t form = data.GetULEB128(offset_ptr);
+
+            if (attr && form)
+                m_attributes.push_back(DWARFAttribute(attr, form));
+            else
+                break;
+        }
+
+        return m_tag != 0;
+    }
+    else
+    {
+        m_tag = 0;
+        m_has_children = 0;
+    }
+
+    return false;
+}
+
+
+void
+DWARFAbbreviationDeclaration::Dump(Stream *s)  const
+{
+//  *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;
+//
+//  DWARFAttribute::const_iterator pos;
+//
+//  for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos)
+//      *ostrm_ptr << "      " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl;
+//
+//  *ostrm_ptr << std::endl;
+}
+
+
+
+bool
+DWARFAbbreviationDeclaration::IsValid()
+{
+    return m_code != 0 && m_tag != 0;
+}
+
+
+void
+DWARFAbbreviationDeclaration::CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx)
+{
+    m_code = abbr_decl.Code();  // Invalidate the code since that can't be copied safely.
+    m_tag = abbr_decl.Tag();
+    m_has_children = abbr_decl.HasChildren();
+
+    const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
+    const uint32_t num_abbr_decl_attributes = attributes.size();
+
+    dw_attr_t attr;
+    dw_form_t form;
+    uint32_t i;
+
+    for (i = 0; i < num_abbr_decl_attributes; ++i)
+    {
+        attributes[i].get(attr, form);
+        switch (attr)
+        {
+        case DW_AT_location:
+        case DW_AT_frame_base:
+            // Only add these if they are location expressions (have a single
+            // value) and not location lists (have a lists of location
+            // expressions which are only valid over specific address ranges)
+            if (DWARFFormValue::IsBlockForm(form))
+                m_attributes.push_back(DWARFAttribute(attr, form));
+            break;
+
+        case DW_AT_low_pc:
+        case DW_AT_high_pc:
+        case DW_AT_ranges:
+        case DW_AT_entry_pc:
+            // Don't add these attributes
+            if (i >= idx)
+                break;
+            // Fall through and add attribute
+        default:
+            // Add anything that isn't address related
+            m_attributes.push_back(DWARFAttribute(attr, form));
+            break;
+        }
+    }
+}
+
+void
+DWARFAbbreviationDeclaration::CopyChangingStringToStrp(
+    const DWARFAbbreviationDeclaration& abbr_decl,
+    const DataExtractor& debug_info_data,
+    dw_offset_t debug_info_offset,
+    const DWARFCompileUnit* cu,
+    const uint32_t strp_min_len
+)
+{
+    m_code = InvalidCode;
+    m_tag = abbr_decl.Tag();
+    m_has_children = abbr_decl.HasChildren();
+
+    const DWARFAttribute::collection& attributes = abbr_decl.Attributes();
+    const uint32_t num_abbr_decl_attributes = attributes.size();
+
+    dw_attr_t attr;
+    dw_form_t form;
+    uint32_t i;
+    dw_offset_t offset = debug_info_offset;
+
+    for (i = 0; i < num_abbr_decl_attributes; ++i)
+    {
+        attributes[i].get(attr, form);
+        dw_offset_t attr_offset = offset;
+        DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
+
+        if (form == DW_FORM_string && ((offset - attr_offset) >= strp_min_len))
+            m_attributes.push_back(DWARFAttribute(attr, DW_FORM_strp));
+        else
+            m_attributes.push_back(DWARFAttribute(attr, form));
+    }
+}
+
+
+uint32_t
+DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const
+{
+    uint32_t i;
+    const uint32_t kNumAttributes = m_attributes.size();
+    for (i = 0; i < kNumAttributes; ++i)
+    {
+        if (m_attributes[i].get_attr() == attr)
+            return i;
+    }
+    return DW_INVALID_INDEX;
+}
+
+
+bool
+DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const
+{
+    return Tag()            == rhs.Tag()
+        && HasChildren()    == rhs.HasChildren()
+        && Attributes()     == rhs.Attributes();
+}
+
+#if 0
+DWARFAbbreviationDeclaration::Append(BinaryStreamBuf& out_buff) const
+{
+    out_buff.Append32_as_ULEB128(Code());
+    out_buff.Append32_as_ULEB128(Tag());
+    out_buff.Append8(HasChildren());
+    const uint32_t kNumAttributes = m_attributes.size();
+    for (uint32_t i = 0; i < kNumAttributes; ++i)
+    {
+        out_buff.Append32_as_ULEB128(m_attributes[i].attr());
+        out_buff.Append32_as_ULEB128(m_attributes[i].form());
+    }
+    out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
+    out_buff.Append8(0);    // Output a zero for attr (faster than using Append32_as_ULEB128)
+}
+#endif  // 0
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
new file mode 100644
index 0000000..7959f26
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -0,0 +1,77 @@
+//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFAbbreviationDeclaration_h_
+#define liblldb_DWARFAbbreviationDeclaration_h_
+
+#include "SymbolFileDWARF.h"
+#include "DWARFAttribute.h"
+
+class DWARFCompileUnit;
+
+class DWARFAbbreviationDeclaration
+{
+public:
+    enum { InvalidCode = 0 };
+                    DWARFAbbreviationDeclaration();
+
+                    // For hand crafting an abbreviation declaration
+                    DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children);
+    void            AddAttribute(const DWARFAttribute& attr)
+                    {
+                        m_attributes.push_back(attr);
+                    }
+
+    dw_uleb128_t    Code() const { return m_code; }
+    void            SetCode(dw_uleb128_t code) { m_code = code; }
+    dw_tag_t        Tag() const { return m_tag; }
+    bool            HasChildren() const { return m_has_children; }
+    uint32_t        NumAttributes() const { return m_attributes.size(); }
+    dw_attr_t       GetAttrByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; }
+    dw_form_t       GetFormByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; }
+    bool            GetAttrAndFormByIndex(uint32_t idx, dw_attr_t& attr, dw_form_t& form) const
+                    {
+                        if (m_attributes.size() > idx)
+                        {
+                            m_attributes[idx].get(attr, form);
+                            return true;
+                        }
+                        attr = form = 0;
+                        return false;
+                    }
+
+                    // idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked()
+    void            GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t& attr, dw_form_t& form) const
+                    {
+                        m_attributes[idx].get(attr, form);
+                    }
+    void            CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx);
+    void            CopyChangingStringToStrp(
+                        const DWARFAbbreviationDeclaration& abbr_decl,
+                        const lldb_private::DataExtractor& debug_info_data,
+                        dw_offset_t debug_info_offset,
+                        const DWARFCompileUnit* cu,
+                        const uint32_t strp_min_len);
+    uint32_t        FindAttributeIndex(dw_attr_t attr) const;
+    bool            Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
+    bool            Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code);
+//  void            Append(BinaryStreamBuf& out_buff) const;
+    bool            IsValid();
+    void            Dump(lldb_private::Stream *s) const;
+    bool            operator == (const DWARFAbbreviationDeclaration& rhs) const;
+//  DWARFAttribute::collection& Attributes() { return m_attributes; }
+    const DWARFAttribute::collection& Attributes() const { return m_attributes; }
+protected:
+    dw_uleb128_t        m_code;
+    dw_tag_t            m_tag;
+    uint8_t             m_has_children;
+    DWARFAttribute::collection m_attributes;
+};
+
+#endif  // liblldb_DWARFAbbreviationDeclaration_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
new file mode 100644
index 0000000..0b44926
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -0,0 +1,45 @@
+//===-- DWARFAttribute.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFAttribute_h_
+#define liblldb_DWARFAttribute_h_
+
+#include "DWARFDefines.h"
+#include <vector>
+
+class DWARFAttribute
+{
+public:
+    DWARFAttribute(dw_attr_t attr, dw_form_t form) :
+        m_attr_form ( attr << 16 | form )
+    {
+    }
+
+    void        set(dw_attr_t attr, dw_form_t form) { m_attr_form = (attr << 16) | form; }
+    void        set_attr(dw_attr_t attr) { m_attr_form = (m_attr_form & 0x0000ffffu) | (attr << 16); }
+    void        set_form(dw_form_t form) { m_attr_form = (m_attr_form & 0xffff0000u) | form; }
+    dw_attr_t   get_attr() const { return m_attr_form >> 16; }
+    dw_form_t   get_form() const { return m_attr_form; }
+    void        get(dw_attr_t& attr, dw_form_t& form)  const
+    {
+        register uint32_t attr_form = m_attr_form;
+        attr = attr_form >> 16;
+        form = attr_form;
+    }
+    bool        operator == (const DWARFAttribute& rhs) const { return m_attr_form == rhs.m_attr_form; }
+    typedef std::vector<DWARFAttribute> collection;
+    typedef collection::iterator iterator;
+    typedef collection::const_iterator const_iterator;
+
+protected:
+    uint32_t    m_attr_form;    // Upper 16 bits is attribute, lower 16 bits is form
+};
+
+
+#endif  // liblldb_DWARFAttribute_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
new file mode 100644
index 0000000..e7f92c6
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -0,0 +1,770 @@
+//===-- DWARFCompileUnit.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFCompileUnit.h"
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/Timer.h"
+
+#include "DWARFDebugAbbrev.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDIECollection.h"
+#include "DWARFFormValue.h"
+#include "LogChannelDWARF.h"
+#include "SymbolFileDWARF.h"
+
+using namespace lldb_private;
+using namespace std;
+
+extern int g_verbose;
+
+DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* m_dwarf2Data) :
+    m_dwarf2Data    ( m_dwarf2Data ),
+    m_offset        ( DW_INVALID_OFFSET ),
+    m_length        ( 0 ),
+    m_version       ( 0 ),
+    m_abbrevs       ( NULL ),
+    m_addr_size     ( DWARFCompileUnit::GetDefaultAddressSize() ),
+    m_base_addr     ( 0 ),
+    m_die_array     (),
+    m_aranges_ap    (),
+    m_user_data     ( NULL )
+{
+}
+
+void
+DWARFCompileUnit::Clear()
+{
+    m_offset        = DW_INVALID_OFFSET;
+    m_length        = 0;
+    m_version       = 0;
+    m_abbrevs       = NULL;
+    m_addr_size     = DWARFCompileUnit::GetDefaultAddressSize();
+    m_base_addr     = 0;
+    m_die_array.clear();
+    m_aranges_ap.reset();
+    m_user_data     = NULL;
+}
+
+bool
+DWARFCompileUnit::Extract(const DataExtractor &debug_info, uint32_t* offset_ptr)
+{
+    Clear();
+
+    m_offset = *offset_ptr;
+
+    if (debug_info.ValidOffset(*offset_ptr))
+    {
+        dw_offset_t abbr_offset;
+        const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev();
+        m_length        = debug_info.GetU32(offset_ptr);
+        m_version       = debug_info.GetU16(offset_ptr);
+        abbr_offset     = debug_info.GetU32(offset_ptr);
+        m_addr_size     = debug_info.GetU8 (offset_ptr);
+
+        bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1);
+        bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+        bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
+        bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
+
+        if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL)
+        {
+            m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
+            return true;
+        }
+
+        // reset the offset to where we tried to parse from if anything went wrong
+        *offset_ptr = m_offset;
+    }
+
+    return false;
+}
+
+
+dw_offset_t
+DWARFCompileUnit::Extract(dw_offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs)
+{
+    Clear();
+
+    m_offset = offset;
+
+    if (debug_info_data.ValidOffset(offset))
+    {
+        m_length        = debug_info_data.GetU32(&offset);
+        m_version       = debug_info_data.GetU16(&offset);
+        bool abbrevs_OK = debug_info_data.GetU32(&offset) == abbrevs->GetOffset();
+        m_abbrevs       = abbrevs;
+        m_addr_size     = debug_info_data.GetU8 (&offset);
+
+        bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+        bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
+
+        if (version_OK && addr_size_OK && abbrevs_OK && debug_info_data.ValidOffset(offset))
+            return offset;
+    }
+    return DW_INVALID_OFFSET;
+}
+
+void
+DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die)
+{
+    if (m_die_array.size() > 1)
+    {
+        // std::vectors never get any smaller when resized to a smaller size,
+        // or when clear() or erase() are called, the size will report that it
+        // is smaller, but the memory allocated remains intact (call capacity()
+        // to see this). So we need to create a temporary vector and swap the
+        // contents which will cause just the internal pointers to be swapped
+        // so that when "tmp_array" goes out of scope, it will destroy the
+        // contents.
+
+        // Save at least the compile unit DIE
+        DWARFDebugInfoEntry::collection tmp_array;
+        m_die_array.swap(tmp_array);
+        if (keep_compile_unit_die)
+            m_die_array.push_back(tmp_array.front());
+    }
+}
+
+//----------------------------------------------------------------------
+// ParseCompileUnitDIEsIfNeeded
+//
+// Parses a compile unit and indexes its DIEs if it already hasn't been
+// done.
+//----------------------------------------------------------------------
+size_t
+DWARFCompileUnit::ExtractDIEsIfNeeded (bool cu_die_only)
+{
+    const size_t initial_die_array_size = m_die_array.size();
+    if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1)
+        return 0; // Already parsed
+
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "%8.8x: DWARFCompileUnit::ExtractDIEsIfNeeded( cu_die_only = %i )",
+                        m_offset,
+                        cu_die_only);
+
+    // Set the offset to that of the first DIE
+    uint32_t offset = GetFirstDIEOffset();
+    const dw_offset_t next_cu_offset = GetNextCompileUnitOffset();
+    DWARFDebugInfoEntry die;
+        // Keep a flat array of the DIE for binary lookup by DIE offset
+    Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+//        if (log)
+//            log->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x",
+//                        cu->GetOffset(),
+//                        cu->GetLength(),
+//                        cu->GetVersion(),
+//                        cu->GetAbbrevOffset(),
+//                        cu->GetAddressByteSize());
+
+    uint32_t depth = 0;
+    // We are in our compile unit, parse starting at the offset
+    // we were told to parse
+    while (die.Extract(m_dwarf2Data, this, &offset))
+    {
+        if (log)
+            log->Printf("0x%8.8x: %*.*s%s%s",
+                        die.GetOffset(),
+                        depth * 2, depth * 2, "",
+                        DW_TAG_value_to_name (die.Tag()),
+                        die.HasChildren() ? " *" : "");
+        if (cu_die_only)
+        {
+            AddDIE(die);
+            return 1;
+        }
+        else if (depth == 0 && initial_die_array_size == 1)
+        {
+            // Don't append the CU die as we already did that
+        }
+        else
+        {
+            AddDIE(die);
+        }
+
+        const DWARFAbbreviationDeclaration* abbrDecl = die.GetAbbreviationDeclarationPtr();
+        if (abbrDecl)
+        {
+            // Normal DIE
+            if (abbrDecl->HasChildren())
+                ++depth;
+        }
+        else
+        {
+            // NULL DIE.
+            if (depth > 0)
+                --depth;
+            else
+                break;  // We are done with this compile unit!
+        }
+
+        assert(offset <= next_cu_offset);
+    }
+    SetDIERelations();
+    return m_die_array.size();
+}
+
+
+dw_offset_t
+DWARFCompileUnit::GetAbbrevOffset() const
+{
+    return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
+}
+
+
+
+bool
+DWARFCompileUnit::Verify(Stream *s) const
+{
+    const DataExtractor& debug_info = m_dwarf2Data->get_debug_info_data();
+    bool valid_offset = debug_info.ValidOffset(m_offset);
+    bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1);
+    bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
+    bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset());
+    bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
+    bool verbose = s->GetVerbose();
+    if (valid_offset && length_OK && version_OK && addr_size_OK && abbr_offset_OK)
+    {
+        if (verbose)
+            s->Printf("    0x%8.8x: OK\n", m_offset);
+        return true;
+    }
+    else
+    {
+        s->Printf("    0x%8.8x: ", m_offset);
+
+        m_dwarf2Data->get_debug_info_data().Dump (s, m_offset, lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0, 0);
+        s->EOL();
+        if (valid_offset)
+        {
+            if (!length_OK)
+                s->Printf("        The length (0x%8.8x) for this compile unit is too large for the .debug_info provided.\n", m_length);
+            if (!version_OK)
+                s->Printf("        The 16 bit compile unit header version is not supported.\n");
+            if (!abbr_offset_OK)
+                s->Printf("        The offset into the .debug_abbrev section (0x%8.8x) is not valid.\n", GetAbbrevOffset());
+            if (!addr_size_OK)
+                s->Printf("        The address size is unsupported: 0x%2.2x\n", m_addr_size);
+        }
+        else
+            s->Printf("        The start offset of the compile unit header in the .debug_info is invalid.\n");
+    }
+    return false;
+}
+
+
+void
+DWARFCompileUnit::Dump(Stream *s) const
+{
+    s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at {0x%8.8x})\n",
+                m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset());
+}
+
+
+static uint8_t g_default_addr_size = 4;
+
+uint8_t
+DWARFCompileUnit::GetAddressByteSize(const DWARFCompileUnit* cu)
+{
+    if (cu)
+        return cu->GetAddressByteSize();
+    return DWARFCompileUnit::GetDefaultAddressSize();
+}
+
+uint8_t
+DWARFCompileUnit::GetDefaultAddressSize()
+{
+    return g_default_addr_size;
+}
+
+void
+DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size)
+{
+    g_default_addr_size = addr_size;
+}
+
+bool
+DWARFCompileUnit::LookupAddress
+(
+    const dw_addr_t address,
+    DWARFDebugInfoEntry** function_die_handle,
+    DWARFDebugInfoEntry** block_die_handle
+)
+{
+    bool success = false;
+
+    if (function_die_handle != NULL && DIE())
+    {
+        if (m_aranges_ap.get() == NULL)
+        {
+            m_aranges_ap.reset(new DWARFDebugAranges());
+            m_die_array.front().BuildFunctionAddressRangeTable(m_dwarf2Data, this, m_aranges_ap.get());
+        }
+
+        // Re-check the aranges auto pointer contents in case it was created above
+        if (m_aranges_ap.get() != NULL)
+        {
+            *function_die_handle = GetDIEPtr(m_aranges_ap->FindAddress(address));
+            if (*function_die_handle != NULL)
+            {
+                success = true;
+                if (block_die_handle != NULL)
+                {
+                    DWARFDebugInfoEntry* child = (*function_die_handle)->GetFirstChild();
+                    while (child)
+                    {
+                        if (child->LookupAddress(address, m_dwarf2Data, this, NULL, block_die_handle))
+                            break;
+                        child = child->GetSibling();
+                    }
+                }
+            }
+        }
+    }
+    return success;
+}
+
+//----------------------------------------------------------------------
+// SetDIERelations()
+//
+// We read in all of the DIE entries into our flat list of DIE entries
+// and now we need to go back through all of them and set the parent,
+// sibling and child pointers for quick DIE navigation.
+//----------------------------------------------------------------------
+void
+DWARFCompileUnit::SetDIERelations()
+{
+#if 0
+    // Compute average bytes per DIE
+    //
+    // We can figure out what the average number of bytes per DIE is
+    // to help us pre-allocate the correct number of m_die_array
+    // entries so we don't end up doing a lot of memory copies as we
+    // are creating our DIE array when parsing
+    //
+    // Enable this code by changing "#if 0" above to "#if 1" and running
+    // the dsymutil or dwarfdump with a bunch of dwarf files and see what
+    // the running average ends up being in the stdout log.
+    static size_t g_total_cu_debug_info_size = 0;
+    static size_t g_total_num_dies = 0;
+    static size_t g_min_bytes_per_die = UINT_MAX;
+    static size_t g_max_bytes_per_die = 0;
+    const size_t num_dies = m_die_array.size();
+    const size_t cu_debug_info_size = GetDebugInfoSize();
+    const size_t bytes_per_die = cu_debug_info_size / num_dies;
+    if (g_min_bytes_per_die > bytes_per_die)
+        g_min_bytes_per_die = bytes_per_die;
+    if (g_max_bytes_per_die < bytes_per_die)
+        g_max_bytes_per_die = bytes_per_die;
+    if (g_total_cu_debug_info_size == 0)
+    {
+        cout << "                    min max avg" << endl
+             << "n dies cu size  bpd bpd bpd bpd" << endl
+             << "------ -------- --- === === ===" << endl;
+    }
+    g_total_cu_debug_info_size += cu_debug_info_size;
+    g_total_num_dies += num_dies;
+    const size_t avg_bytes_per_die = g_total_cu_debug_info_size / g_total_num_dies;
+    cout
+        << DECIMAL_WIDTH(6) << num_dies << ' '
+        << DECIMAL_WIDTH(8) << cu_debug_info_size  << ' '
+        << DECIMAL_WIDTH(3) << bytes_per_die << ' '
+        << DECIMAL_WIDTH(3) << g_min_bytes_per_die << ' '
+        << DECIMAL_WIDTH(3) << g_max_bytes_per_die << ' '
+        << DECIMAL_WIDTH(3) << avg_bytes_per_die
+        << endl;
+#endif
+    if (m_die_array.empty())
+        return;
+    DWARFDebugInfoEntry* die_array_begin = &m_die_array.front();
+    DWARFDebugInfoEntry* die_array_end = &m_die_array.back();
+    DWARFDebugInfoEntry* curr_die;
+    // We purposely are skipping the last element in the array in the loop below
+    // so that we can always have a valid next item
+    for (curr_die = die_array_begin;  curr_die < die_array_end;  ++curr_die)
+    {
+        // Since our loop doesn't include the last element, we can always
+        // safely access the next die in the array.
+        DWARFDebugInfoEntry* next_die = curr_die + 1;
+
+        const DWARFAbbreviationDeclaration* curr_die_abbrev = curr_die->GetAbbreviationDeclarationPtr();
+
+        if (curr_die_abbrev)
+        {
+            // Normal DIE
+            if (curr_die_abbrev->HasChildren())
+                next_die->SetParent(curr_die);
+            else
+                curr_die->SetSibling(next_die);
+        }
+        else
+        {
+            // NULL DIE that terminates a sibling chain
+            DWARFDebugInfoEntry* parent = curr_die->GetParent();
+            if (parent)
+                parent->SetSibling(next_die);
+        }
+    }
+
+    // Since we skipped the last element, we need to fix it up!
+    if (die_array_begin < die_array_end)
+        curr_die->SetParent(die_array_begin);
+
+#if 0
+    // The code below will dump the DIE relations in case any modification
+    // is done to the above code. This dump can be used in a diff to make
+    // sure that no functionality is lost.
+    {
+        DWARFDebugInfoEntry::const_iterator pos;
+        DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+        puts("offset    parent   sibling  child");
+        puts("--------  -------- -------- --------");
+        for (pos = m_die_array.begin(); pos != end; ++pos)
+        {
+            const DWARFDebugInfoEntry& die_ref = *pos;
+            const DWARFDebugInfoEntry* p = die_ref.GetParent();
+            const DWARFDebugInfoEntry* s = die_ref.GetSibling();
+            const DWARFDebugInfoEntry* c = die_ref.GetFirstChild();
+            printf("%.8x: %.8x %.8x %.8x\n", die_ref.GetOffset(),
+                p ? p->GetOffset() : 0,
+                s ? s->GetOffset() : 0,
+                c ? c->GetOffset() : 0);
+        }
+    }
+#endif
+
+}
+//----------------------------------------------------------------------
+// Compare function DWARFDebugAranges::Range structures
+//----------------------------------------------------------------------
+static bool CompareDIEOffset (const DWARFDebugInfoEntry& die1, const DWARFDebugInfoEntry& die2)
+{
+    return die1.GetOffset() < die2.GetOffset();
+}
+
+//----------------------------------------------------------------------
+// GetDIEPtr()
+//
+// Get the DIE (Debug Information Entry) with the specified offset.
+//----------------------------------------------------------------------
+DWARFDebugInfoEntry*
+DWARFCompileUnit::GetDIEPtr(dw_offset_t die_offset)
+{
+    if (die_offset != DW_INVALID_OFFSET)
+    {
+        ExtractDIEsIfNeeded (false);
+        DWARFDebugInfoEntry compare_die;
+        compare_die.SetOffset(die_offset);
+        DWARFDebugInfoEntry::iterator end = m_die_array.end();
+        DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset);
+        if (pos != end)
+        {
+            if (die_offset == (*pos).GetOffset())
+                return &(*pos);
+        }
+    }
+    return NULL;    // Not found in any compile units
+}
+
+//----------------------------------------------------------------------
+// GetDIEPtrContainingOffset()
+//
+// Get the DIE (Debug Information Entry) that contains the specified
+// .debug_info offset.
+//----------------------------------------------------------------------
+const DWARFDebugInfoEntry*
+DWARFCompileUnit::GetDIEPtrContainingOffset(dw_offset_t die_offset)
+{
+    if (die_offset != DW_INVALID_OFFSET)
+    {
+        ExtractDIEsIfNeeded (false);
+        DWARFDebugInfoEntry compare_die;
+        compare_die.SetOffset(die_offset);
+        DWARFDebugInfoEntry::iterator end = m_die_array.end();
+        DWARFDebugInfoEntry::iterator pos = lower_bound(m_die_array.begin(), end, compare_die, CompareDIEOffset);
+        if (pos != end)
+        {
+            if (die_offset >= (*pos).GetOffset())
+            {
+                DWARFDebugInfoEntry::iterator next = pos + 1;
+                if (next != end)
+                {
+                    if (die_offset < (*next).GetOffset())
+                        return &(*pos);
+                }
+            }
+        }
+    }
+    return NULL;    // Not found in any compile units
+}
+
+
+
+size_t
+DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& dies, uint32_t depth) const
+{
+    size_t old_size = dies.Size();
+    DWARFDebugInfoEntry::const_iterator pos;
+    DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+    for (pos = m_die_array.begin(); pos != end; ++pos)
+    {
+        if (pos->Tag() == tag)
+            dies.Insert(&(*pos));
+    }
+
+    // Return the number of DIEs added to the collection
+    return dies.Size() - old_size;
+}
+
+void
+DWARFCompileUnit::AddGlobalDIEByIndex (uint32_t die_idx)
+{
+    m_global_die_indexes.push_back (die_idx);
+}
+
+
+void
+DWARFCompileUnit::AddGlobal (const DWARFDebugInfoEntry* die)
+{
+    // Indexes to all file level global and static variables
+    m_global_die_indexes;
+    
+    if (m_die_array.empty())
+        return;
+    
+    const DWARFDebugInfoEntry* first_die = &m_die_array[0];
+    const DWARFDebugInfoEntry* end = first_die + m_die_array.size();
+    if (first_die <= die && die < end)
+        m_global_die_indexes.push_back (die - first_die);
+}
+
+
+void
+DWARFCompileUnit::Index 
+(
+    lldb_private::UniqueCStringMap<dw_offset_t>& name_to_function_die,
+    lldb_private::UniqueCStringMap<dw_offset_t>& name_to_inlined_die,
+    lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die,
+    lldb_private::UniqueCStringMap<dw_offset_t>& name_to_type_die
+)
+{
+
+    const DataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data();
+
+    DWARFDebugInfoEntry::const_iterator pos;
+    DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin();
+    DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+    for (pos = begin; pos != end; ++pos)
+    {
+        const DWARFDebugInfoEntry &die = *pos;
+        
+        const dw_tag_t tag = die.Tag();
+    
+        switch (tag)
+        {
+        case DW_TAG_subprogram:
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_base_type:
+        case DW_TAG_class_type:
+        case DW_TAG_constant:
+        case DW_TAG_enumeration_type:
+        case DW_TAG_string_type:
+        case DW_TAG_subroutine_type:
+        case DW_TAG_structure_type:
+        case DW_TAG_union_type:
+        case DW_TAG_typedef:
+        case DW_TAG_namespace:
+        case DW_TAG_variable:
+            break;
+            
+        default:
+            continue;
+        }
+
+        DWARFDebugInfoEntry::Attributes attributes;
+        const char *name = NULL;
+        const char *mangled = NULL;
+        bool is_variable = false;
+        bool is_declaration = false;
+        bool is_artificial = false;
+        bool has_address = false;
+        bool has_location = false;
+        bool is_global_or_static_variable = false;
+        const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, attributes);
+        if (num_attributes > 0)
+        {
+            uint32_t i;
+
+            dw_tag_t tag = die.Tag();
+            
+            is_variable = tag == DW_TAG_variable;
+
+            for (i=0; i<num_attributes; ++i)
+            {
+                dw_attr_t attr = attributes.AttributeAtIndex(i);
+                DWARFFormValue form_value;
+                switch (attr)
+                {
+                case DW_AT_name:
+                    if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value))
+                        name = form_value.AsCString(debug_str);
+                    break;
+
+                case DW_AT_declaration:
+                    if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value))
+                        is_declaration = form_value.Unsigned() != 0;
+                    break;
+
+                case DW_AT_artificial:
+                    if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value))
+                        is_artificial = form_value.Unsigned() != 0;
+                    break;
+
+                case DW_AT_MIPS_linkage_name:
+                    if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value))
+                        mangled = form_value.AsCString(debug_str);
+                    break;
+
+                case DW_AT_low_pc:
+                case DW_AT_ranges:
+                case DW_AT_entry_pc:
+                    has_address = true;
+                    break;
+
+                case DW_AT_location:
+                    has_location = true;
+                    if (tag == DW_TAG_variable)
+                    {
+                        const DWARFDebugInfoEntry* parent_die = die.GetParent();
+                        while ( parent_die != NULL )
+                        {
+                            switch (parent_die->Tag())
+                            {
+                            case DW_TAG_subprogram:
+                            case DW_TAG_lexical_block:
+                            case DW_TAG_inlined_subroutine:
+                                // Even if this is a function level static, we don't add it. We could theoretically
+                                // add these if we wanted to by introspecting into the DW_AT_location and seeing
+                                // if the location describes a hard coded address, but we dont want the performance
+                                // penalty of that right now.
+                                is_global_or_static_variable = false;
+//                              if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
+//                              {
+//                                  // If we have valid block data, then we have location expression bytes
+//                                  // that are fixed (not a location list).
+//                                  const uint8_t *block_data = form_value.BlockData();
+//                                  if (block_data)
+//                                  {
+//                                      uint32_t block_length = form_value.Unsigned();
+//                                      if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
+//                                      {
+//                                          if (block_data[0] == DW_OP_addr)
+//                                              add_die = true;
+//                                      }
+//                                  }
+//                              }
+                                parent_die = NULL;  // Terminate the while loop.
+                                break;
+
+                            case DW_TAG_compile_unit:
+                                is_global_or_static_variable = true;
+                                parent_die = NULL;  // Terminate the while loop.
+                                break;
+
+                            default:
+                                parent_die = parent_die->GetParent();   // Keep going in the while loop.
+                                break;
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        switch (tag)
+        {
+        case DW_TAG_subprogram:
+            if (has_address)
+            {
+                if (name && name[0])
+                {
+                    if ((name[0] == '-' || name[0] == '+') && name[1] == '[')
+                    {
+                        int name_len = strlen (name);
+                        // Objective C methods must have at least:
+                        //      "-[" or "+[" prefix
+                        //      One character for a class name
+                        //      One character for the space between the class name
+                        //      One character for the method name
+                        //      "]" suffix
+                        if (name_len >= 6 && name[name_len - 1] == ']')
+                        {
+                            const char *method_name = strchr (name, ' ');
+                            if (method_name)
+                            {
+                                // Skip the space
+                                ++method_name;
+                                // Extract the objective C basename and add it to the
+                                // accelerator tables
+                                size_t method_name_len = name_len - (method_name - name) - 1;
+                                ConstString method_const_str (method_name, method_name_len);
+                                name_to_function_die.Append(method_const_str.AsCString(), die.GetOffset());
+                            }
+                        }
+                    }
+                    name_to_function_die.Append(ConstString(name).AsCString(), die.GetOffset());
+                }
+                if (mangled && mangled[0])
+                    name_to_function_die.Append(ConstString(mangled).AsCString(), die.GetOffset());
+            }
+            break;
+
+        case DW_TAG_inlined_subroutine:
+            if (has_address)
+            {
+                if (name && name[0])
+                    name_to_inlined_die.Append(ConstString(name).AsCString(), die.GetOffset());
+                if (mangled && mangled[0])
+                    name_to_inlined_die.Append(ConstString(mangled).AsCString(), die.GetOffset());
+            }
+            break;
+        
+        case DW_TAG_base_type:
+        case DW_TAG_class_type:
+        case DW_TAG_constant:
+        case DW_TAG_enumeration_type:
+        case DW_TAG_string_type:
+        case DW_TAG_subroutine_type:
+        case DW_TAG_structure_type:
+        case DW_TAG_union_type:
+        case DW_TAG_typedef:
+        case DW_TAG_namespace:
+            if (name && is_declaration == false)
+            {
+                name_to_type_die.Append(ConstString(name).AsCString(), die.GetOffset());
+            }
+            break;
+
+        case DW_TAG_variable:
+            if (name && has_location && is_global_or_static_variable)
+            {
+                AddGlobalDIEByIndex (std::distance (begin, pos));
+                name_to_global_die.Append(ConstString(name).AsCString(), die.GetOffset());
+            }
+            break;
+            
+        default:
+            continue;
+        }
+    }
+}
+
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
new file mode 100644
index 0000000..44bbbfe
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -0,0 +1,168 @@
+//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFCompileUnit_h_
+#define SymbolFileDWARF_DWARFCompileUnit_h_
+
+#include "SymbolFileDWARF.h"
+#include "DWARFDebugInfoEntry.h"
+
+class DWARFCompileUnit
+{
+public:
+    DWARFCompileUnit(SymbolFileDWARF* dwarf2Data);
+
+    bool        Extract(const lldb_private::DataExtractor &debug_info, uint32_t* offset_ptr);
+    dw_offset_t Extract(dw_offset_t offset, const lldb_private::DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs);
+    size_t      ExtractDIEsIfNeeded (bool cu_die_only);
+    bool        LookupAddress(
+                    const dw_addr_t address,
+                    DWARFDebugInfoEntry** function_die,
+                    DWARFDebugInfoEntry** block_die);
+
+    size_t      AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& matching_dies, uint32_t depth = UINT_MAX) const;
+    void        Clear();
+    bool        Verify(lldb_private::Stream *s) const;
+    void        Dump(lldb_private::Stream *s) const;
+    dw_offset_t GetOffset() const { return m_offset; }
+    uint32_t    Size() const { return 11; /* Size in bytes of the compile unit header */ }
+    bool        ContainsDIEOffset(dw_offset_t die_offset) const { return die_offset >= GetFirstDIEOffset() && die_offset < GetNextCompileUnitOffset(); }
+    dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
+    dw_offset_t GetNextCompileUnitOffset() const { return m_offset + m_length + 4; }
+    size_t      GetDebugInfoSize() const { return m_length + 4 - Size(); /* Size in bytes of the .debug_info data associated with this compile unit. */ }
+    uint32_t    GetLength() const { return m_length; }
+    uint16_t    GetVersion() const { return m_version; }
+    const DWARFAbbreviationDeclarationSet*  GetAbbreviations() const { return m_abbrevs; }
+    dw_offset_t GetAbbrevOffset() const;
+    uint8_t     GetAddressByteSize() const { return m_addr_size; }
+    dw_addr_t   GetBaseAddress() const { return m_base_addr; }
+    void        ClearDIEs(bool keep_compile_unit_die);
+
+    void
+    SetBaseAddress(dw_addr_t base_addr)
+    {
+        m_base_addr = base_addr;
+    }
+
+    void
+    SetDIERelations();
+
+    const DWARFDebugInfoEntry*
+    GetCompileUnitDIEOnly()
+    {
+        ExtractDIEsIfNeeded (true);
+        if (m_die_array.empty())
+            return NULL;
+        return &m_die_array[0];
+    }
+
+    const DWARFDebugInfoEntry*
+    DIE()
+    {
+        ExtractDIEsIfNeeded (false);
+        if (m_die_array.empty())
+            return NULL;
+        return &m_die_array[0];
+    }
+
+    void
+    AddDIE(DWARFDebugInfoEntry& die)
+    {
+        // The average bytes per DIE entry has been seen to be
+        // around 14-20 so lets pre-reserve the needed memory for
+        // our DIE entries accordingly. Search forward for "Compute
+        // average bytes per DIE" to see #if'ed out code that does
+        // that determination.
+
+        // Only reserve the memory if we are adding children of
+        // the main compile unit DIE. The compile unit DIE is always
+        // the first entry, so if our size is 1, then we are adding
+        // the first compile unit child DIE and should reserve
+        // the memory.
+        if (m_die_array.empty())
+            m_die_array.reserve(GetDebugInfoSize() / 14);
+        m_die_array.push_back(die);
+    }
+
+    DWARFDebugInfoEntry*
+    GetDIEPtr (dw_offset_t die_offset);
+
+    const DWARFDebugInfoEntry*
+    GetDIEPtrContainingOffset (dw_offset_t die_offset);
+
+    static uint8_t
+    GetAddressByteSize(const DWARFCompileUnit* cu);
+
+    static uint8_t
+    GetDefaultAddressSize();
+    static void
+    SetDefaultAddressSize(uint8_t addr_size);
+
+    void *
+    GetUserData() const
+    {
+        return m_user_data;
+    }
+
+    void
+    SetUserData(void *d)
+    {
+        m_user_data = d;
+    }
+
+
+    void
+    AddGlobalDIEByIndex (uint32_t die_idx);
+
+    void
+    AddGlobal (const DWARFDebugInfoEntry* die);
+
+    size_t
+    GetNumGlobals () const
+    {
+        return m_global_die_indexes.size();
+    }
+    
+    const DWARFDebugInfoEntry *
+    GetGlobalDIEAtIndex (uint32_t idx)
+    {
+        if (idx < m_global_die_indexes.size())
+        {
+            uint32_t die_idx = m_global_die_indexes[idx];
+            if (die_idx < m_die_array.size())
+                return &m_die_array[die_idx];
+        }
+        return NULL;
+    }
+
+    void
+    Index (lldb_private::UniqueCStringMap<dw_offset_t>& name_to_function_die,
+           lldb_private::UniqueCStringMap<dw_offset_t>& name_to_inlined_die,
+           lldb_private::UniqueCStringMap<dw_offset_t>& name_to_global_die,
+           lldb_private::UniqueCStringMap<dw_offset_t>& name_to_type_die);
+
+protected:
+    SymbolFileDWARF*    m_dwarf2Data;
+    dw_offset_t         m_offset;
+    uint32_t            m_length;
+    uint16_t            m_version;
+    const DWARFAbbreviationDeclarationSet*
+                        m_abbrevs;
+    uint8_t             m_addr_size;
+    dw_addr_t           m_base_addr;
+    DWARFDebugInfoEntry::collection
+                        m_die_array;    // The compile unit debug information entry item
+    std::auto_ptr<DWARFDebugAranges>    m_aranges_ap;   // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs
+    std::vector<uint32_t> m_global_die_indexes; // Indexes to all file level global and static variables
+    void *              m_user_data;
+private:
+    DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit);
+};
+
+#endif  // SymbolFileDWARF_DWARFCompileUnit_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
new file mode 100644
index 0000000..60aac74
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.cpp
@@ -0,0 +1,56 @@
+//===-- DWARFDIECollection.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDIECollection.h"
+
+#include <algorithm>
+
+#include "lldb/Core/Stream.h"
+
+#include "DWARFDebugInfoEntry.h"
+
+using namespace lldb_private;
+using namespace std;
+
+bool
+DWARFDIECollection::Insert(const DWARFDebugInfoEntry *die)
+{
+    iterator end_pos = m_dies.end();
+    iterator insert_pos = upper_bound(m_dies.begin(), end_pos, die);
+    if (insert_pos != end_pos && (*insert_pos == die))
+        return false;
+    m_dies.insert(insert_pos, die);
+    return true;
+}
+
+const DWARFDebugInfoEntry *
+DWARFDIECollection::GetDIEPtrAtIndex(uint32_t idx) const
+{
+    if (idx < m_dies.size())
+        return m_dies[idx];
+    return NULL;
+}
+
+
+size_t
+DWARFDIECollection::Size() const
+{
+    return m_dies.size();
+}
+
+void
+DWARFDIECollection::Dump(Stream *s, const char* title) const
+{
+    if (title && title[0] != '\0')
+        s->Printf( "%s\n", title);
+    const_iterator end_pos = m_dies.end();
+    const_iterator pos;
+    for (pos = m_dies.begin(); pos != end_pos; ++pos)
+        s->Printf( "0x%8.8x\n", (*pos)->GetOffset());
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
new file mode 100644
index 0000000..c374a14
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h
@@ -0,0 +1,48 @@
+//===-- DWARFDIECollection.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDIECollection_h_
+#define SymbolFileDWARF_DWARFDIECollection_h_
+
+#include "SymbolFileDWARF.h"
+#include <vector>
+
+class DWARFDIECollection
+{
+public:
+    DWARFDIECollection() :
+        m_dies()
+    {
+    }
+    ~DWARFDIECollection()
+    {
+    }
+
+    void
+    Dump(lldb_private::Stream *s, const char* title) const;
+
+    const DWARFDebugInfoEntry*
+    GetDIEPtrAtIndex(uint32_t idx) const;
+
+    bool
+    Insert(const DWARFDebugInfoEntry *die);
+
+    size_t
+    Size() const;
+
+protected:
+    typedef std::vector<const DWARFDebugInfoEntry *>    collection;
+    typedef collection::iterator                iterator;
+    typedef collection::const_iterator          const_iterator;
+
+    collection m_dies;  // Ordered list of die offsets
+};
+
+
+#endif  // SymbolFileDWARF_DWARFDIECollection_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
new file mode 100644
index 0000000..af6fc8e
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -0,0 +1,202 @@
+//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugAbbrev.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace std;
+
+//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::Clear()
+//----------------------------------------------------------------------
+void
+DWARFAbbreviationDeclarationSet::Clear()
+{
+    m_idx_offset = 0;
+    m_decls.clear();
+}
+
+
+//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::Extract()
+//----------------------------------------------------------------------
+bool
+DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+{
+    const uint32_t begin_offset = *offset_ptr;
+    m_offset = begin_offset;
+    Clear();
+    DWARFAbbreviationDeclaration abbrevDeclaration;
+    dw_uleb128_t prev_abbr_code = 0;
+    while (abbrevDeclaration.Extract(data, offset_ptr))
+    {
+        m_decls.push_back(abbrevDeclaration);
+        if (m_idx_offset == 0)
+            m_idx_offset = abbrevDeclaration.Code();
+        else
+        {
+            if (prev_abbr_code + 1 != abbrevDeclaration.Code())
+                m_idx_offset = UINT_MAX;    // Out of order indexes, we can't do O(1) lookups...
+        }
+        prev_abbr_code = abbrevDeclaration.Code();
+    }
+    return begin_offset != *offset_ptr;
+}
+
+
+//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::Dump()
+//----------------------------------------------------------------------
+void
+DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
+{
+    std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
+}
+
+
+//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
+//----------------------------------------------------------------------
+const DWARFAbbreviationDeclaration*
+DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
+{
+    if (m_idx_offset == UINT_MAX)
+    {
+        DWARFAbbreviationDeclarationCollConstIter pos;
+        DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
+        for (pos = m_decls.begin(); pos != end; ++pos)
+        {
+            if (pos->Code() == abbrCode)
+                return &(*pos);
+        }
+    }
+    else
+    {
+        uint32_t idx = abbrCode - m_idx_offset;
+        if (idx < m_decls.size())
+            return &m_decls[idx];
+    }
+    return NULL;
+}
+
+//----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
+//
+// Append an abbreviation declaration with a sequential code for O(n)
+// lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
+//----------------------------------------------------------------------
+dw_uleb128_t
+DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
+{
+    // Get the next abbreviation code based on our current array size
+    dw_uleb128_t code = m_decls.size()+1;
+
+    // Push the new declaration on the back
+    m_decls.push_back(abbrevDecl);
+
+    // Update the code for this new declaration
+    m_decls.back().SetCode(code);
+
+    return code;    // return the new abbreviation code!
+}
+
+
+//----------------------------------------------------------------------
+// Encode
+//
+// Encode the abbreviation table onto the end of the buffer provided
+// into a byte represenation as would be found in a ".debug_abbrev"
+// debug information section.
+//----------------------------------------------------------------------
+//void
+//DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
+//{
+//  DWARFAbbreviationDeclarationCollConstIter pos;
+//  DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
+//  for (pos = m_decls.begin(); pos != end; ++pos)
+//      pos->Append(debug_abbrev_buf);
+//  debug_abbrev_buf.Append8(0);
+//}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev constructor
+//----------------------------------------------------------------------
+DWARFDebugAbbrev::DWARFDebugAbbrev() :
+    m_abbrevCollMap(),
+    m_prev_abbr_offset_pos(m_abbrevCollMap.end())
+{
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev::Parse()
+//----------------------------------------------------------------------
+void
+DWARFDebugAbbrev::Parse(const DataExtractor& data)
+{
+    uint32_t offset = 0;
+
+    while (data.ValidOffset(offset))
+    {
+        uint32_t initial_cu_offset = offset;
+        DWARFAbbreviationDeclarationSet abbrevDeclSet;
+
+        if (abbrevDeclSet.Extract(data, &offset))
+            m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
+        else
+            break;
+    }
+    m_prev_abbr_offset_pos = m_abbrevCollMap.end();
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev::Dump()
+//----------------------------------------------------------------------
+void
+DWARFDebugAbbrev::Dump(Stream *s) const
+{
+    if (m_abbrevCollMap.empty())
+    {
+        s->PutCString("< EMPTY >\n");
+        return;
+    }
+
+    DWARFAbbreviationDeclarationCollMapConstIter pos;
+    for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
+    {
+        s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
+        pos->second.Dump(s);
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
+//----------------------------------------------------------------------
+const DWARFAbbreviationDeclarationSet*
+DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
+{
+    DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
+    DWARFAbbreviationDeclarationCollMapConstIter pos;
+    if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
+        return &(m_prev_abbr_offset_pos->second);
+    else
+    {
+        pos = m_abbrevCollMap.find(cu_abbr_offset);
+        m_prev_abbr_offset_pos = pos;
+    }
+
+    if (pos != m_abbrevCollMap.end());
+        return &(pos->second);
+    return NULL;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
new file mode 100644
index 0000000..3185d98
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -0,0 +1,74 @@
+//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugAbbrev_h_
+#define SymbolFileDWARF_DWARFDebugAbbrev_h_
+
+#include <list>
+#include <map>
+
+#include "lldb/lldb-private.h"
+
+#include "DWARFDefines.h"
+#include "DWARFAbbreviationDeclaration.h"
+
+typedef std::vector<DWARFAbbreviationDeclaration>               DWARFAbbreviationDeclarationColl;
+typedef DWARFAbbreviationDeclarationColl::iterator              DWARFAbbreviationDeclarationCollIter;
+typedef DWARFAbbreviationDeclarationColl::const_iterator        DWARFAbbreviationDeclarationCollConstIter;
+
+
+class DWARFAbbreviationDeclarationSet
+{
+public:
+    DWARFAbbreviationDeclarationSet() :
+        m_offset(DW_INVALID_OFFSET),
+        m_idx_offset(0),
+        m_decls()
+        {
+        }
+
+    DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset) :
+        m_offset(offset),
+        m_idx_offset(idx_offset),
+        m_decls()
+        {
+        }
+
+    void Clear();
+    dw_offset_t GetOffset() const { return m_offset; }
+    void Dump(lldb_private::Stream *s) const;
+    bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
+    //void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
+    dw_uleb128_t AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl);
+
+    const DWARFAbbreviationDeclaration* GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
+private:
+    dw_offset_t m_offset;
+    uint32_t m_idx_offset;
+    std::vector<DWARFAbbreviationDeclaration> m_decls;
+};
+
+typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet> DWARFAbbreviationDeclarationCollMap;
+typedef DWARFAbbreviationDeclarationCollMap::iterator DWARFAbbreviationDeclarationCollMapIter;
+typedef DWARFAbbreviationDeclarationCollMap::const_iterator DWARFAbbreviationDeclarationCollMapConstIter;
+
+
+class DWARFDebugAbbrev
+{
+public:
+    DWARFDebugAbbrev();
+    const DWARFAbbreviationDeclarationSet*  GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
+    void Dump(lldb_private::Stream *s) const;
+    void Parse(const lldb_private::DataExtractor& data);
+protected:
+    DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;
+    mutable DWARFAbbreviationDeclarationCollMapConstIter m_prev_abbr_offset_pos;
+};
+
+#endif  // SymbolFileDWARF_DWARFDebugAbbrev_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
new file mode 100644
index 0000000..57ef6ba
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -0,0 +1,274 @@
+//===-- DWARFDebugArangeSet.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugArangeSet.h"
+
+#include <assert.h>
+#include "lldb/Core/Stream.h"
+#include "SymbolFileDWARF.h"
+
+using namespace lldb_private;
+
+DWARFDebugArangeSet::DWARFDebugArangeSet() :
+    m_offset(DW_INVALID_OFFSET),
+    m_header(),
+    m_arange_descriptors()
+{
+    m_header.length     = 0;
+    m_header.version    = 0;
+    m_header.cu_offset  = 0;
+    m_header.addr_size  = 0;
+    m_header.seg_size   = 0;
+}
+
+void
+DWARFDebugArangeSet::Clear()
+{
+    m_offset = DW_INVALID_OFFSET;
+    m_header.length     = 0;
+    m_header.version    = 0;
+    m_header.cu_offset  = 0;
+    m_header.addr_size  = 0;
+    m_header.seg_size   = 0;
+    m_arange_descriptors.clear();
+}
+
+void
+DWARFDebugArangeSet::SetHeader
+(
+    uint16_t version,
+    uint32_t cu_offset,
+    uint8_t addr_size,
+    uint8_t seg_size
+)
+{
+    m_header.version    = version;
+    m_header.cu_offset  = cu_offset;
+    m_header.addr_size  = addr_size;
+    m_header.seg_size   = seg_size;
+}
+
+void
+DWARFDebugArangeSet::Compact()
+{
+    if (m_arange_descriptors.empty())
+        return;
+
+    // Iterate through all arange descriptors and combine any ranges that
+    // overlap or have matching boundaries. The m_arange_descriptors are assumed
+    // to be in ascending order after being built by adding descriptors
+    // using the AddDescriptor method.
+    uint32_t i = 0;
+    while (i + 1 < m_arange_descriptors.size())
+    {
+        if (m_arange_descriptors[i].end_address() >= m_arange_descriptors[i+1].address)
+        {
+            // The current range ends at or exceeds the start of the next address range.
+            // Compute the max end address between the two and use that to make the new
+            // length.
+            const dw_addr_t max_end_addr = std::max(m_arange_descriptors[i].end_address(), m_arange_descriptors[i+1].end_address());
+            m_arange_descriptors[i].length = max_end_addr - m_arange_descriptors[i].address;
+            // Now remove the next entry as it was just combined with the previous one.
+            m_arange_descriptors.erase(m_arange_descriptors.begin()+i+1);
+        }
+        else
+        {
+            // Discontiguous address range, just proceed to the next one.
+            ++i;
+        }
+    }
+}
+//----------------------------------------------------------------------
+// Compare function DWARFDebugArangeSet::Descriptor structures
+//----------------------------------------------------------------------
+static bool DescriptorLessThan (const DWARFDebugArangeSet::Descriptor& range1, const DWARFDebugArangeSet::Descriptor& range2)
+{
+    return range1.address < range2.address;
+}
+
+//----------------------------------------------------------------------
+// Add a range descriptor and keep things sorted so we can easily
+// compact the ranges before being saved or used.
+//----------------------------------------------------------------------
+void
+DWARFDebugArangeSet::AddDescriptor(const DWARFDebugArangeSet::Descriptor& range)
+{
+    if (m_arange_descriptors.empty())
+    {
+        m_arange_descriptors.push_back(range);
+        return;
+    }
+
+    DescriptorIter end = m_arange_descriptors.end();
+    DescriptorIter pos = lower_bound(m_arange_descriptors.begin(), end, range, DescriptorLessThan);
+    const dw_addr_t range_end_addr = range.end_address();
+    if (pos != end)
+    {
+        const dw_addr_t found_end_addr = pos->end_address();
+        if (range.address < pos->address)
+        {
+            if (range_end_addr < pos->address)
+            {
+                // Non-contiguous entries, add this one before the found entry
+                m_arange_descriptors.insert(pos, range);
+            }
+            else if (range_end_addr == pos->address)
+            {
+                // The top end of 'range' is the lower end of the entry
+                // pointed to by 'pos'. We can combine range with the
+                // entry we found by setting the starting address and
+                // increasing the length since they don't overlap.
+                pos->address = range.address;
+                pos->length += range.length;
+            }
+            else
+            {
+                // We can combine these two and make sure the largest end
+                // address is used to make end address.
+                pos->address = range.address;
+                pos->length = std::max(found_end_addr, range_end_addr) - pos->address;
+            }
+        }
+        else if (range.address == pos->address)
+        {
+            pos->length = std::max(pos->length, range.length);
+        }
+    }
+    else
+    {
+        // NOTE: 'pos' points to entry past the end which is ok for insert,
+        // don't use otherwise!!!
+        const dw_addr_t max_addr = m_arange_descriptors.back().end_address();
+        if (max_addr < range.address)
+        {
+            // Non-contiguous entries, add this one before the found entry
+            m_arange_descriptors.insert(pos, range);
+        }
+        else if (max_addr == range.address)
+        {
+            m_arange_descriptors.back().length += range.length;
+        }
+        else
+        {
+            m_arange_descriptors.back().length = std::max(max_addr, range_end_addr) - m_arange_descriptors.back().address;
+        }
+    }
+}
+
+bool
+DWARFDebugArangeSet::Extract(const DataExtractor &data, uint32_t* offset_ptr)
+{
+    if (data.ValidOffset(*offset_ptr))
+    {
+        m_arange_descriptors.clear();
+        m_offset = *offset_ptr;
+
+        // 7.20 Address Range Table
+        //
+        // Each set of entries in the table of address ranges contained in
+        // the .debug_aranges section begins with a header consisting of: a
+        // 4-byte length containing the length of the set of entries for this
+        // compilation unit, not including the length field itself; a 2-byte
+        // version identifier containing the value 2 for DWARF Version 2; a
+        // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
+        // containing the size in bytes of an address (or the offset portion of
+        // an address for segmented addressing) on the target system; and a
+        // 1-byte unsigned integer containing the size in bytes of a segment
+        // descriptor on the target system. This header is followed by a series
+        // of tuples. Each tuple consists of an address and a length, each in
+        // the size appropriate for an address on the target architecture.
+        m_header.length     = data.GetU32(offset_ptr);
+        m_header.version    = data.GetU16(offset_ptr);
+        m_header.cu_offset  = data.GetU32(offset_ptr);
+        m_header.addr_size  = data.GetU8(offset_ptr);
+        m_header.seg_size   = data.GetU8(offset_ptr);
+
+
+        // The first tuple following the header in each set begins at an offset
+        // that is a multiple of the size of a single tuple (that is, twice the
+        // size of an address). The header is padded, if necessary, to the
+        // appropriate boundary.
+        const uint32_t header_size = *offset_ptr - m_offset;
+        const uint32_t tuple_size = m_header.addr_size << 1;
+        uint32_t first_tuple_offset = 0;
+        while (first_tuple_offset < header_size)
+            first_tuple_offset += tuple_size;
+
+        *offset_ptr = m_offset + first_tuple_offset;
+
+        Descriptor arangeDescriptor;
+
+        assert(sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length));
+        assert(sizeof(arangeDescriptor.address) >= m_header.addr_size);
+
+        while (data.ValidOffset(*offset_ptr))
+        {
+            arangeDescriptor.address    = data.GetMaxU64(offset_ptr, m_header.addr_size);
+            arangeDescriptor.length     = data.GetMaxU64(offset_ptr, m_header.addr_size);
+
+            // Each set of tuples is terminated by a 0 for the address and 0
+            // for the length.
+            if (arangeDescriptor.address || arangeDescriptor.length)
+                m_arange_descriptors.push_back(arangeDescriptor);
+            else
+                break;  // We are done if we get a zero address and length
+        }
+
+        return !m_arange_descriptors.empty();
+    }
+    return false;
+}
+
+
+dw_offset_t
+DWARFDebugArangeSet::GetOffsetOfNextEntry() const
+{
+    return m_offset + m_header.length + 4;
+}
+
+
+void
+DWARFDebugArangeSet::Dump(Stream *s) const
+{
+    s->Printf("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
+        m_header.length ,m_header.version, m_header.cu_offset, m_header.addr_size, m_header.seg_size);
+
+    const uint32_t hex_width = m_header.addr_size * 2;
+    DescriptorConstIter pos;
+    DescriptorConstIter end = m_arange_descriptors.end();
+    for (pos = m_arange_descriptors.begin(); pos != end; ++pos)
+        s->Printf("[0x%*.*llx - 0x%*.*llx)\n",
+            hex_width, hex_width, pos->address,
+            hex_width, hex_width, pos->end_address());
+}
+
+
+class DescriptorContainsAddress
+{
+public:
+    DescriptorContainsAddress (dw_addr_t address) : m_address(address) {}
+    bool operator() (const DWARFDebugArangeSet::Descriptor& desc) const
+    {
+        return (m_address >= desc.address) && (m_address < (desc.address + desc.length));
+    }
+ private:
+   const dw_addr_t m_address;
+};
+
+dw_offset_t
+DWARFDebugArangeSet::FindAddress(dw_addr_t address) const
+{
+    DescriptorConstIter end = m_arange_descriptors.end();
+    DescriptorConstIter pos = std::find_if( m_arange_descriptors.begin(), end,  // Range
+                                            DescriptorContainsAddress(address));// Predicate
+    if (pos != end)
+        return m_header.cu_offset;
+
+    return DW_INVALID_OFFSET;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
new file mode 100644
index 0000000..fc1e391
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -0,0 +1,70 @@
+//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugArangeSet_h_
+#define SymbolFileDWARF_DWARFDebugArangeSet_h_
+
+#include "SymbolFileDWARF.h"
+#include <vector>
+
+class SymbolFileDWARF;
+
+class DWARFDebugArangeSet
+{
+public:
+    typedef struct HeaderTag
+    {
+        uint32_t    length;     // The total length of the entries for that set, not including the length field itself.
+        uint16_t    version;    // The DWARF version number
+        uint32_t    cu_offset;  // The offset from the beginning of the .debug_info section of the compilation unit entry referenced by the table.
+        uint8_t     addr_size;  // The size in bytes of an address on the target architecture. For segmented addressing, this is the size of the offset portion of the address
+        uint8_t     seg_size;   // The size in bytes of a segment descriptor on the target architecture. If the target system uses a flat address space, this value is 0.
+    } Header;
+
+    typedef struct DescriptorTag
+    {
+        dw_addr_t   address;
+        dw_addr_t   length;
+        dw_addr_t end_address() const { return address + length; }
+    } Descriptor;
+
+
+                    DWARFDebugArangeSet();
+        void        Clear();
+        void        SetOffset(uint32_t offset) { m_offset = offset; }
+        void        SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size, uint8_t seg_size);
+        void        AddDescriptor(const DWARFDebugArangeSet::Descriptor& range);
+        void        Compact();
+        bool        Extract(const lldb_private::DataExtractor &data, uint32_t* offset_ptr);
+        void        Dump(lldb_private::Stream *s) const;
+        dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
+        dw_offset_t GetOffsetOfNextEntry() const;
+        dw_offset_t FindAddress(dw_addr_t address) const;
+        uint32_t    NumDescriptors() const { return m_arange_descriptors.size(); }
+        const Header&       GetHeader() const { return m_header; }
+        const Descriptor*   GetDescriptor(uint32_t i) const
+        {
+            if (i < m_arange_descriptors.size())
+                return &m_arange_descriptors[i];
+            return NULL;
+        }
+
+
+protected:
+    typedef std::vector<Descriptor>         DescriptorColl;
+    typedef DescriptorColl::iterator        DescriptorIter;
+    typedef DescriptorColl::const_iterator  DescriptorConstIter;
+
+
+    uint32_t        m_offset;
+    Header          m_header;
+    DescriptorColl  m_arange_descriptors;
+};
+
+#endif  // SymbolFileDWARF_DWARFDebugArangeSet_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
new file mode 100644
index 0000000..a3213e0
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -0,0 +1,343 @@
+//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugAranges.h"
+
+#include <assert.h>
+
+#include <algorithm>
+
+#include "lldb/Core/Stream.h"
+
+#include "SymbolFileDWARF.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFCompileUnit.h"
+
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Constructor
+//----------------------------------------------------------------------
+DWARFDebugAranges::DWARFDebugAranges() :
+    m_aranges()
+{
+}
+
+
+//----------------------------------------------------------------------
+// Compare function DWARFDebugAranges::Range structures
+//----------------------------------------------------------------------
+static bool RangeLessThan (const DWARFDebugAranges::Range& range1, const DWARFDebugAranges::Range& range2)
+{
+//  printf("RangeLessThan -- 0x%8.8x < 0x%8.8x ? %d\n", range1.lo_pc, range1.lo_pc, range1.lo_pc < range2.lo_pc);
+    return range1.lo_pc < range2.lo_pc;
+}
+
+//----------------------------------------------------------------------
+// CountArangeDescriptors
+//----------------------------------------------------------------------
+class CountArangeDescriptors
+{
+public:
+    CountArangeDescriptors (uint32_t& count_ref) : count(count_ref)
+    {
+//      printf("constructor CountArangeDescriptors()\n");
+    }
+    void operator() (const DWARFDebugArangeSet& set)
+    {
+        count += set.NumDescriptors();
+    }
+    uint32_t& count;
+};
+
+//----------------------------------------------------------------------
+// AddArangeDescriptors
+//----------------------------------------------------------------------
+class AddArangeDescriptors
+{
+public:
+    AddArangeDescriptors (DWARFDebugAranges::RangeColl& ranges) : range_collection(ranges) {}
+    void operator() (const DWARFDebugArangeSet& set)
+    {
+        const DWARFDebugArangeSet::Descriptor* arange_desc_ptr;
+        DWARFDebugAranges::Range range;
+        range.offset = set.GetCompileUnitDIEOffset();
+
+        for (uint32_t i=0; arange_desc_ptr = set.GetDescriptor(i); ++i)
+        {
+            range.lo_pc = arange_desc_ptr->address;
+            range.hi_pc = arange_desc_ptr->address + arange_desc_ptr->length;
+
+            // Insert each item in increasing address order so binary searching
+            // can later be done!
+            DWARFDebugAranges::RangeColl::iterator insert_pos = lower_bound(range_collection.begin(), range_collection.end(), range, RangeLessThan);
+            range_collection.insert(insert_pos, range);
+        }
+    }
+    DWARFDebugAranges::RangeColl& range_collection;
+};
+
+//----------------------------------------------------------------------
+// PrintRange
+//----------------------------------------------------------------------
+static void PrintRange(const DWARFDebugAranges::Range& range)
+{
+    // Cast the address values in case the address type is compiled as 32 bit
+    printf("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.offset, (uint64_t)range.lo_pc, (uint64_t)range.hi_pc);
+}
+
+//----------------------------------------------------------------------
+// Extract
+//----------------------------------------------------------------------
+bool
+DWARFDebugAranges::Extract(const DataExtractor &debug_aranges_data)
+{
+    if (debug_aranges_data.ValidOffset(0))
+    {
+        uint32_t offset = 0;
+
+        typedef std::vector<DWARFDebugArangeSet>    SetCollection;
+        typedef SetCollection::const_iterator       SetCollectionIter;
+        SetCollection sets;
+
+        DWARFDebugArangeSet set;
+        Range range;
+        while (set.Extract(debug_aranges_data, &offset))
+            sets.push_back(set);
+
+        uint32_t count = 0;
+
+        for_each(sets.begin(), sets.end(), CountArangeDescriptors(count));
+
+        if (count > 0)
+        {
+            m_aranges.reserve(count);
+            AddArangeDescriptors range_adder(m_aranges);
+            for_each(sets.begin(), sets.end(), range_adder);
+        }
+
+    //  puts("\n\nDWARFDebugAranges list is:\n");
+    //  for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
+    }
+    return false;
+}
+
+//----------------------------------------------------------------------
+// Generate
+//----------------------------------------------------------------------
+bool
+DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
+{
+    Clear();
+    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
+    if (debug_info)
+    {
+        uint32_t cu_idx = 0;
+        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+        {
+            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+            if (cu)
+                cu->DIE()->BuildAddressRangeTable(dwarf2Data, cu, this);
+        }
+    }
+    return !IsEmpty();
+}
+
+
+void
+DWARFDebugAranges::Print() const
+{
+    puts("\n\nDWARFDebugAranges address range list is:\n");
+    for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
+}
+
+
+void
+DWARFDebugAranges::Range::Dump(Stream *s) const
+{
+    s->Printf("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", offset, lo_pc, hi_pc);
+}
+
+//----------------------------------------------------------------------
+// Dump
+//----------------------------------------------------------------------
+void
+DWARFDebugAranges::Dump(SymbolFileDWARF* dwarf2Data, Stream *s)
+{
+    const DataExtractor &debug_aranges_data = dwarf2Data->get_debug_aranges_data();
+    if (debug_aranges_data.ValidOffset(0))
+    {
+        uint32_t offset = 0;
+
+        DWARFDebugArangeSet set;
+        while (set.Extract(debug_aranges_data, &offset))
+            set.Dump(s);
+    }
+    else
+        s->PutCString("< EMPTY >\n");
+}
+
+
+//----------------------------------------------------------------------
+// AppendDebugRanges
+//----------------------------------------------------------------------
+//void
+//DWARFDebugAranges::AppendDebugRanges(BinaryStreamBuf& debug_ranges, dw_addr_t cu_base_addr, uint32_t addr_size) const
+//{
+//  if (!m_aranges.empty())
+//  {
+//      RangeCollIterator end = m_aranges.end();
+//      RangeCollIterator pos;
+//      RangeCollIterator lo_pos = end;
+//      for (pos = m_aranges.begin(); pos != end; ++pos)
+//      {
+//          if (lo_pos == end)
+//              lo_pos = pos;
+//
+//          RangeCollIterator next = pos + 1;
+//          if (next != end)
+//          {
+//              // Check to see if we can combine two consecutive ranges?
+//              if (pos->hi_pc == next->lo_pc)
+//                  continue;   // We can combine them!
+//          }
+//
+//          if (cu_base_addr == 0 || cu_base_addr == DW_INVALID_ADDRESS)
+//          {
+//              debug_ranges.AppendMax64(lo_pos->lo_pc, addr_size);
+//              debug_ranges.AppendMax64(pos->hi_pc, addr_size);
+//          }
+//          else
+//          {
+//              assert(lo_pos->lo_pc >= cu_base_addr);
+//              assert(pos->hi_pc >= cu_base_addr);
+//              debug_ranges.AppendMax64(lo_pos->lo_pc - cu_base_addr, addr_size);
+//              debug_ranges.AppendMax64(pos->hi_pc - cu_base_addr, addr_size);
+//          }
+//
+//          // Reset the low part of the next address range
+//          lo_pos = end;
+//      }
+//  }
+//  // Terminate the .debug_ranges with two zero addresses
+//  debug_ranges.AppendMax64(0, addr_size);
+//  debug_ranges.AppendMax64(0, addr_size);
+//
+//}
+//
+//----------------------------------------------------------------------
+// ArangeSetContainsAddress
+//----------------------------------------------------------------------
+class ArangeSetContainsAddress
+{
+public:
+    ArangeSetContainsAddress (dw_addr_t the_address) : address(the_address), offset(DW_INVALID_OFFSET) {}
+    bool operator() (const DWARFDebugArangeSet& set)
+    {
+        offset = set.FindAddress(address);
+        return (offset != DW_INVALID_OFFSET);
+    }
+    const dw_addr_t address;
+    dw_offset_t offset;
+};
+
+
+//----------------------------------------------------------------------
+// InsertRange
+//----------------------------------------------------------------------
+void
+DWARFDebugAranges::InsertRange(dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
+{
+    // Insert each item in increasing address order so binary searching
+    // can later be done!
+    DWARFDebugAranges::Range range(low_pc, high_pc, offset);
+    InsertRange(range);
+}
+
+//----------------------------------------------------------------------
+// InsertRange
+//----------------------------------------------------------------------
+void
+DWARFDebugAranges::InsertRange(const DWARFDebugAranges::Range& range)
+{
+    // Insert each item in increasing address order so binary searching
+    // can later be done!
+    RangeColl::iterator insert_pos = lower_bound(m_aranges.begin(), m_aranges.end(), range, RangeLessThan);
+    m_aranges.insert(insert_pos, range);
+}
+
+
+//----------------------------------------------------------------------
+// FindAddress
+//----------------------------------------------------------------------
+dw_offset_t
+DWARFDebugAranges::FindAddress(dw_addr_t address) const
+{
+    if ( !m_aranges.empty() )
+    {
+        DWARFDebugAranges::Range range(address);
+        DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
+        DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
+        DWARFDebugAranges::RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan);
+
+        if ((pos != end) && (pos->lo_pc <= address && address < pos->hi_pc))
+        {
+        //  printf("FindAddress(1) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
+            return pos->offset;
+        }
+        else if (pos != begin)
+        {
+            --pos;
+            if ((pos->lo_pc <= address) && (address < pos->hi_pc))
+            {
+            //  printf("FindAddress(2) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
+                return (*pos).offset;
+            }
+        }
+    }
+    return DW_INVALID_OFFSET;
+}
+
+//----------------------------------------------------------------------
+// AllRangesAreContiguous
+//----------------------------------------------------------------------
+bool
+DWARFDebugAranges::AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
+{
+    if (m_aranges.empty())
+        return false;
+
+    DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
+    DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
+    DWARFDebugAranges::RangeCollIterator pos;
+    dw_addr_t next_addr = 0;
+
+    for (pos = begin; pos != end; ++pos)
+    {
+        if ((pos != begin) && (pos->lo_pc != next_addr))
+            return false;
+        next_addr = pos->hi_pc;
+    }
+    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
+    hi_pc = m_aranges.back().hi_pc;     // We checked for empty at the start of function so back() will be valid
+    return true;
+}
+
+bool
+DWARFDebugAranges::GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
+{
+    if (m_aranges.empty())
+        return false;
+
+    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
+    hi_pc = m_aranges.back().hi_pc;     // We checked for empty at the start of function so back() will be valid
+    return true;
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
new file mode 100644
index 0000000..f3db949
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -0,0 +1,98 @@
+//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugAranges_h_
+#define SymbolFileDWARF_DWARFDebugAranges_h_
+
+#include "DWARFDebugArangeSet.h"
+#include <list>
+
+class SymbolFileDWARF;
+
+class DWARFDebugAranges
+{
+public:
+    struct Range
+    {
+        Range(
+            dw_addr_t   _lo_pc = DW_INVALID_ADDRESS,
+            dw_addr_t   _hi_pc = DW_INVALID_ADDRESS,
+            dw_offset_t _offset = DW_INVALID_OFFSET) :
+                lo_pc(_lo_pc),
+                hi_pc(_hi_pc),
+                offset(_offset)
+        {
+        }
+
+        void Clear()
+        {
+            lo_pc = hi_pc = DW_INVALID_ADDRESS;
+            offset = DW_INVALID_OFFSET;
+        }
+
+        bool ValidRange() const
+        {
+            return hi_pc > lo_pc;
+        }
+
+        bool Contains(const Range& range) const
+        {
+            return lo_pc <= range.lo_pc && range.hi_pc <= hi_pc;
+        }
+
+        void Dump(lldb_private::Stream *s) const;
+        dw_addr_t   lo_pc;      // Start of address range
+        dw_addr_t   hi_pc;      // End of address range (not including this address)
+        dw_offset_t offset;     // Offset of the compile unit or die
+    };
+
+                DWARFDebugAranges();
+
+    void        Clear() { m_aranges.clear(); }
+    bool        AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const;
+    bool        GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const;
+    bool        Extract(const lldb_private::DataExtractor &debug_aranges_data);
+    bool        Generate(SymbolFileDWARF* dwarf2Data);
+    void        InsertRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc);
+    void        InsertRange(const DWARFDebugAranges::Range& range);
+    const Range* RangeAtIndex(uint32_t idx) const
+                {
+                    if (idx < m_aranges.size())
+                        return &m_aranges[idx];
+                    return NULL;
+                }
+    void        Print() const;
+    dw_offset_t FindAddress(dw_addr_t address) const;
+    bool        IsEmpty() const { return m_aranges.empty(); }
+    void        Dump(lldb_private::Stream *s);
+    uint32_t    NumRanges() const
+                {
+                    return m_aranges.size();
+                }
+
+    dw_offset_t OffsetAtIndex(uint32_t idx) const
+                {
+                    if (idx < m_aranges.size())
+                        return m_aranges[idx].offset;
+                    return DW_INVALID_OFFSET;
+                }
+//  void    AppendDebugRanges(BinaryStreamBuf& debug_ranges, dw_addr_t cu_base_addr, uint32_t addr_size) const;
+
+    static void Dump(SymbolFileDWARF* dwarf2Data, lldb_private::Stream *s);
+
+    typedef std::vector<Range>              RangeColl;
+    typedef RangeColl::const_iterator       RangeCollIterator;
+
+protected:
+
+    RangeColl m_aranges;
+};
+
+
+#endif  // SymbolFileDWARF_DWARFDebugAranges_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
new file mode 100644
index 0000000..fcb0ccf
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -0,0 +1,1206 @@
+//===-- DWARFDebugInfo.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARF.h"
+
+#include <algorithm>
+#include <set>
+
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Stream.h"
+
+#include "DWARFDebugInfo.h"
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFFormValue.h"
+
+using namespace lldb_private;
+using namespace std;
+
+//----------------------------------------------------------------------
+// Constructor
+//----------------------------------------------------------------------
+DWARFDebugInfo::DWARFDebugInfo() :
+    m_dwarf2Data(NULL),
+    m_compile_units()
+{
+}
+
+//----------------------------------------------------------------------
+// SetDwarfData
+//----------------------------------------------------------------------
+void
+DWARFDebugInfo::SetDwarfData(SymbolFileDWARF* dwarf2Data)
+{
+    m_dwarf2Data = dwarf2Data;
+    m_compile_units.clear();
+}
+
+//----------------------------------------------------------------------
+// BuildDIEAddressRangeTable
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfo::BuildFunctionAddressRangeTable(DWARFDebugAranges* debug_aranges)
+{
+    const uint32_t num_compile_units = GetNumCompileUnits();
+    uint32_t idx;
+    for (idx = 0; idx < num_compile_units; ++idx)
+    {
+        DWARFCompileUnit* cu = GetCompileUnitAtIndex (idx);
+        if (cu)
+        {
+            cu->DIE()->BuildFunctionAddressRangeTable(m_dwarf2Data, cu, debug_aranges);
+        }
+    }
+    return !debug_aranges->IsEmpty();
+}
+
+//----------------------------------------------------------------------
+// LookupAddress
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfo::LookupAddress
+(
+    const dw_addr_t address,
+    const dw_offset_t hint_die_offset,
+    DWARFCompileUnitSP& cu_sp,
+    DWARFDebugInfoEntry** function_die,
+    DWARFDebugInfoEntry** block_die
+)
+{
+
+    if (hint_die_offset != DW_INVALID_OFFSET)
+        cu_sp = GetCompileUnit(hint_die_offset);
+    else
+    {
+        // Get a non const version of the address ranges
+        DWARFDebugAranges* debug_aranges = ((SymbolFileDWARF*)m_dwarf2Data)->DebugAranges();
+
+        if (debug_aranges != NULL)
+        {
+            // If we have an empty address ranges section, lets build a sorted
+            // table ourselves by going through all of the debug information so we
+            // can do quick subsequent searches.
+
+            if (debug_aranges->IsEmpty())
+            {
+                const uint32_t num_compile_units = GetNumCompileUnits();
+                uint32_t idx;
+                for (idx = 0; idx < num_compile_units; ++idx)
+                {
+                    DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx);
+                    if (cu)
+                        cu->DIE()->BuildAddressRangeTable(m_dwarf2Data, cu, debug_aranges);
+                }
+            }
+            cu_sp = GetCompileUnit(debug_aranges->FindAddress(address));
+        }
+    }
+
+    if (cu_sp.get())
+    {
+        if (cu_sp->LookupAddress(address, function_die, block_die))
+            return true;
+        cu_sp.reset();
+    }
+    else
+    {
+        // The hint_die_offset may have been a pointer to the actual item that
+        // we are looking for
+        DWARFDebugInfoEntry* die_ptr = GetDIEPtr(hint_die_offset, &cu_sp);
+        if (die_ptr)
+        {
+            if (cu_sp.get())
+            {
+                if (function_die || block_die)
+                    return die_ptr->LookupAddress(address, m_dwarf2Data, cu_sp.get(), function_die, block_die);
+
+                // We only wanted the compile unit that contained this address
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+void
+DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded()
+{
+    if (m_compile_units.empty())
+    {
+        if (m_dwarf2Data != NULL)
+        {
+            uint32_t offset = 0;
+            const DataExtractor &debug_info_data = m_dwarf2Data->get_debug_info_data();
+            while (debug_info_data.ValidOffset(offset))
+            {
+                DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(m_dwarf2Data));
+                // Out of memory?
+                if (cu_sp.get() == NULL)
+                    break;
+
+                if (cu_sp->Extract(debug_info_data, &offset) == false)
+                    break;
+
+                m_compile_units.push_back(cu_sp);
+
+                offset = cu_sp->GetNextCompileUnitOffset();
+            }
+        }
+    }
+}
+
+uint32_t
+DWARFDebugInfo::GetNumCompileUnits()
+{
+    ParseCompileUnitHeadersIfNeeded();
+    return m_compile_units.size();
+}
+
+DWARFCompileUnit*
+DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx)
+{
+    DWARFCompileUnit* cu = NULL;
+    if (idx < GetNumCompileUnits())
+        cu = m_compile_units[idx].get();
+    return cu;
+}
+
+static bool CompileUnitOffsetLessThan (const DWARFCompileUnitSP& a, const DWARFCompileUnitSP& b)
+{
+    return a->GetOffset() < b->GetOffset();
+}
+
+
+static int
+CompareDWARFCompileUnitSPOffset (const void *key, const void *arrmem)
+{
+    const dw_offset_t key_cu_offset = *(dw_offset_t*) key;
+    const dw_offset_t cu_offset = ((DWARFCompileUnitSP *)arrmem)->get()->GetOffset();
+    if (key_cu_offset < cu_offset)
+        return -1;
+    if (key_cu_offset > cu_offset)
+        return 1;
+    return 0;
+}
+
+DWARFCompileUnitSP
+DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr)
+{
+    DWARFCompileUnitSP cu_sp;
+    uint32_t cu_idx = DW_INVALID_INDEX;
+    if (cu_offset != DW_INVALID_OFFSET)
+    {
+        ParseCompileUnitHeadersIfNeeded();
+
+        DWARFCompileUnitSP* match = (DWARFCompileUnitSP*)bsearch(&cu_offset, &m_compile_units[0], m_compile_units.size(), sizeof(DWARFCompileUnitSP), CompareDWARFCompileUnitSPOffset);
+        if (match)
+        {
+            cu_sp = *match;
+            cu_idx = match - &m_compile_units[0];
+        }
+    }
+    if (idx_ptr)
+        *idx_ptr = cu_idx;
+    return cu_sp;
+}
+
+DWARFCompileUnitSP
+DWARFDebugInfo::GetCompileUnitContainingDIE(dw_offset_t die_offset)
+{
+    DWARFCompileUnitSP cu_sp;
+    if (die_offset != DW_INVALID_OFFSET)
+    {
+        ParseCompileUnitHeadersIfNeeded();
+
+        CompileUnitColl::const_iterator end_pos = m_compile_units.end();
+        CompileUnitColl::const_iterator pos;
+
+        for (pos = m_compile_units.begin(); pos != end_pos; ++pos)
+        {
+            dw_offset_t cu_start_offset = (*pos)->GetOffset();
+            dw_offset_t cu_end_offset = (*pos)->GetNextCompileUnitOffset();
+            if (cu_start_offset <= die_offset && die_offset < cu_end_offset)
+            {
+                cu_sp = *pos;
+                break;
+            }
+        }
+    }
+    return cu_sp;
+}
+
+//----------------------------------------------------------------------
+// Compare function DWARFDebugAranges::Range structures
+//----------------------------------------------------------------------
+static bool CompareDIEOffset (const DWARFDebugInfoEntry& die1, const DWARFDebugInfoEntry& die2)
+{
+    return die1.GetOffset() < die2.GetOffset();
+}
+
+
+//----------------------------------------------------------------------
+// GetDIE()
+//
+// Get the DIE (Debug Information Entry) with the specified offset.
+//----------------------------------------------------------------------
+DWARFDebugInfoEntry*
+DWARFDebugInfo::GetDIEPtr(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr)
+{
+    DWARFCompileUnitSP cu_sp(GetCompileUnitContainingDIE(die_offset));
+    if (cu_sp_ptr)
+        *cu_sp_ptr = cu_sp;
+    if (cu_sp.get())
+        return cu_sp->GetDIEPtr(die_offset);
+    return NULL;    // Not found in any compile units
+}
+
+const DWARFDebugInfoEntry*
+DWARFDebugInfo::GetDIEPtrContainingOffset(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr)
+{
+    DWARFCompileUnitSP cu_sp(GetCompileUnitContainingDIE(die_offset));
+    if (cu_sp_ptr)
+        *cu_sp_ptr = cu_sp;
+    if (cu_sp.get())
+        return cu_sp->GetDIEPtrContainingOffset(die_offset);
+
+    return NULL;    // Not found in any compile units
+
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugInfo_ParseCallback
+//
+// A callback function for the static DWARFDebugInfo::Parse() function
+// that gets parses all compile units and DIE's into an internate
+// representation for further modification.
+//----------------------------------------------------------------------
+
+static dw_offset_t
+DWARFDebugInfo_ParseCallback
+(
+    SymbolFileDWARF* dwarf2Data,
+    DWARFCompileUnitSP& cu_sp,
+    DWARFDebugInfoEntry* die,
+    const dw_offset_t next_offset,
+    const uint32_t curr_depth,
+    void* userData
+)
+{
+    DWARFDebugInfo* debug_info = (DWARFDebugInfo*)userData;
+    DWARFCompileUnit* cu = cu_sp.get();
+    if (die)
+    {
+        cu->AddDIE(*die);
+    }
+    else if (cu)
+    {
+        debug_info->AddCompileUnit(cu_sp);
+    }
+
+    // Just return the current offset to parse the next CU or DIE entry
+    return next_offset;
+}
+
+//----------------------------------------------------------------------
+// AddCompileUnit
+//----------------------------------------------------------------------
+void
+DWARFDebugInfo::AddCompileUnit(DWARFCompileUnitSP& cu)
+{
+    m_compile_units.push_back(cu);
+}
+
+/*
+void
+DWARFDebugInfo::AddDIE(DWARFDebugInfoEntry& die)
+{
+    m_die_array.push_back(die);
+}
+*/
+
+
+
+
+//----------------------------------------------------------------------
+// Parse
+//
+// Parses the .debug_info section and uses the .debug_abbrev section
+// and various other sections in the SymbolFileDWARF class and calls the
+// supplied callback function each time a compile unit header, or debug
+// information entry is successfully parsed. This function can be used
+// for different tasks such as parsing the file contents into a
+// structured data, dumping, verifying and much more.
+//----------------------------------------------------------------------
+void
+DWARFDebugInfo::Parse(SymbolFileDWARF* dwarf2Data, Callback callback, void* userData)
+{
+    if (dwarf2Data)
+    {
+        uint32_t offset = 0;
+        uint32_t depth = 0;
+        DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
+        if (cu.get() == NULL)
+            return;
+        DWARFDebugInfoEntry die;
+
+        while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset))
+        {
+            const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
+
+            depth = 0;
+            // Call the callback funtion with no DIE pointer for the compile unit
+            // and get the offset that we are to continue to parse from
+            offset = callback(dwarf2Data, cu, NULL, offset, depth, userData);
+
+            // Make sure we are within our compile unit
+            if (offset < next_cu_offset)
+            {
+                // We are in our compile unit, parse starting at the offset
+                // we were told to parse
+                bool done = false;
+                while (!done && die.Extract(dwarf2Data, cu.get(), &offset))
+                {
+                    // Call the callback funtion with DIE pointer that falls within the compile unit
+                    offset = callback(dwarf2Data, cu, &die, offset, depth, userData);
+
+                    if (die.IsNULL())
+                    {
+                        if (depth)
+                            --depth;
+                        else
+                            done = true;    // We are done with this compile unit!
+                    }
+                    else if (die.HasChildren())
+                        ++depth;
+                }
+            }
+
+            // Make sure the offset returned is valid, and if not stop parsing.
+            // Returning DW_INVALID_OFFSET from this callback is a good way to end
+            // all parsing
+            if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
+                break;
+
+            // See if during the callback anyone retained a copy of the compile
+            // unit other than ourselves and if so, let whomever did own the object
+            // and create a new one for our own use!
+            if (!cu.unique())
+                cu.reset(new DWARFCompileUnit(dwarf2Data));
+
+
+            // Make sure we start on a propper
+            offset = next_cu_offset;
+        }
+    }
+}
+
+/*
+typedef struct AddressRangeTag
+{
+    dw_addr_t   lo_pc;
+    dw_addr_t   hi_pc;
+    dw_offset_t die_offset;
+} AddressRange;
+*/
+struct DIERange
+{
+    DIERange() :
+        range(),
+        lo_die_offset(),
+        hi_die_offset()
+    {
+    }
+
+    DWARFDebugAranges::Range range;
+    dw_offset_t lo_die_offset;
+    dw_offset_t hi_die_offset;
+};
+
+typedef struct DwarfStat
+{
+    DwarfStat() : count(0), byte_size(0) {}
+    uint32_t count;
+    uint32_t byte_size;
+} DwarfStat;
+
+typedef map<dw_attr_t, DwarfStat> DwarfAttrStatMap;
+
+typedef struct DIEStat
+{
+    DIEStat() : count(0), byte_size(0), attr_stats() {}
+    uint32_t count;
+    uint32_t byte_size;
+    DwarfAttrStatMap attr_stats;
+} DIEStat;
+
+typedef map<dw_tag_t, DIEStat> DIEStatMap;
+struct VerifyInfo
+{
+    VerifyInfo(Stream* the_strm) :
+        strm(the_strm),
+        die_ranges(),
+        addr_range_errors(0),
+        sibling_errors(0),
+        die_stats()
+    {
+    }
+
+    Stream* strm;
+    vector<DIERange> die_ranges;
+    uint32_t addr_range_errors;
+    uint32_t sibling_errors;
+    DIEStatMap die_stats;
+
+    DISALLOW_COPY_AND_ASSIGN(VerifyInfo);
+
+};
+
+
+//----------------------------------------------------------------------
+// VerifyCallback
+//
+// A callback function for the static DWARFDebugInfo::Parse() function
+// that gets called each time a compile unit header or debug information
+// entry is successfully parsed.
+//
+// This function will verify the DWARF information is well formed by
+// making sure that any DW_TAG_compile_unit tags that have valid address
+// ranges (DW_AT_low_pc and DW_AT_high_pc) have no gaps in the address
+// ranges of it contained DW_TAG_subprogram tags. Also the sibling chain
+// and relationships are verified to make sure nothing gets hosed up
+// when dead stripping occurs.
+//----------------------------------------------------------------------
+
+static dw_offset_t
+VerifyCallback
+(
+    SymbolFileDWARF* dwarf2Data,
+    DWARFCompileUnitSP& cu_sp,
+    DWARFDebugInfoEntry* die,
+    const dw_offset_t next_offset,
+    const uint32_t curr_depth,
+    void* userData
+)
+{
+    VerifyInfo* verifyInfo = (VerifyInfo*)userData;
+
+    const DWARFCompileUnit* cu = cu_sp.get();
+    Stream *s = verifyInfo->strm;
+    bool verbose = s->GetVerbose();
+    if (die)
+    {
+    //  die->Dump(dwarf2Data, cu, f);
+        const DWARFAbbreviationDeclaration* abbrevDecl = die->GetAbbreviationDeclarationPtr();
+        // We have a DIE entry
+        if (abbrevDecl)
+        {
+            const dw_offset_t die_offset = die->GetOffset();
+            const dw_offset_t sibling = die->GetAttributeValueAsReference(dwarf2Data, cu, DW_AT_sibling, DW_INVALID_OFFSET);
+
+            if (sibling != DW_INVALID_OFFSET)
+            {
+                if (sibling <= next_offset)
+                {
+                    if (verifyInfo->sibling_errors++ == 0)
+                        s->Printf("ERROR\n");
+                    s->Printf("    0x%8.8x: sibling attribyte (0x%8.8x) in this die is not valid: it is less than this DIE or some of its contents.\n", die->GetOffset(), sibling);
+                }
+                else if (sibling > verifyInfo->die_ranges.back().hi_die_offset)
+                {
+                    if (verifyInfo->sibling_errors++ == 0)
+                        s->Printf("ERROR\n");
+                    s->Printf("    0x%8.8x: sibling attribute (0x%8.8x) in this DIE is not valid: it is greater than the end of the parent scope.\n", die->GetOffset(), sibling);
+                }
+            }
+
+            if ((die_offset < verifyInfo->die_ranges.back().lo_die_offset) || (die_offset >= verifyInfo->die_ranges.back().hi_die_offset))
+            {
+                if (verifyInfo->sibling_errors++ == 0)
+                    s->Printf("ERROR\n");
+                s->Printf("    0x%8.8x: DIE offset is not within the parent DIE range {0x%8.8x}: (0x%8.8x - 0x%8.8x)\n",
+                        die->GetOffset(),
+                        verifyInfo->die_ranges.back().range.offset,
+                        verifyInfo->die_ranges.back().lo_die_offset,
+                        verifyInfo->die_ranges.back().hi_die_offset);
+
+            }
+
+            dw_tag_t tag = abbrevDecl->Tag();
+
+            // Keep some stats on this DWARF file
+            verifyInfo->die_stats[tag].count++;
+            verifyInfo->die_stats[tag].byte_size += (next_offset - die->GetOffset());
+
+            if (verbose)
+            {
+                DIEStat& tag_stat = verifyInfo->die_stats[tag];
+
+                const DataExtractor& debug_info = dwarf2Data->get_debug_info_data();
+
+                dw_offset_t offset = die->GetOffset();
+                // Skip the abbreviation code so we are at the data for the attributes
+                debug_info.Skip_LEB128(&offset);
+
+                const uint32_t numAttributes = abbrevDecl->NumAttributes();
+                dw_attr_t attr;
+                dw_form_t form;
+                for (uint32_t idx = 0; idx < numAttributes; ++idx)
+                {
+                    dw_offset_t start_offset = offset;
+                    abbrevDecl->GetAttrAndFormByIndexUnchecked(idx, attr, form);
+                    DWARFFormValue::SkipValue(form, debug_info, &offset, cu);
+
+                    if (tag_stat.attr_stats.find(attr) == tag_stat.attr_stats.end())
+                    {
+                        tag_stat.attr_stats[attr].count = 0;
+                        tag_stat.attr_stats[attr].byte_size = 0;
+                    }
+
+                    tag_stat.attr_stats[attr].count++;
+                    tag_stat.attr_stats[attr].byte_size += offset - start_offset;
+                }
+            }
+
+            DWARFDebugAranges::Range range;
+            range.offset = die->GetOffset();
+
+            switch (tag)
+            {
+            case DW_TAG_compile_unit:
+                // Check for previous subroutines that were within a previous
+                //
+            //  VerifyAddressRangesForCU(verifyInfo);
+                // Remember which compile unit we are dealing with so we can verify
+                // the address ranges within it (if any) are contiguous. The DWARF
+                // spec states that if a compile unit TAG has high and low PC
+                // attributes, there must be no gaps in the address ranges of it's
+                // contained subtroutines. If there are gaps, the high and low PC
+                // must not be in the DW_TAG_compile_unit's attributes. Errors like
+                // this can crop up when optimized code is dead stripped and the debug
+                // information isn't properly fixed up for output.
+                range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+                if (range.lo_pc != DW_INVALID_ADDRESS)
+                {
+                    range.hi_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
+                    if (s->GetVerbose())
+                    {
+                        s->Printf("\n    CU ");
+                        range.Dump(s);
+                    }
+                }
+                else
+                {
+                    range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_entry_pc, DW_INVALID_ADDRESS);
+                }
+                break;
+
+            case DW_TAG_subprogram:
+                // If the DW_TAG_compile_unit that contained this function had a
+                // valid address range, add all of the valid subroutine address
+                // ranges to a collection of addresses which will be sorted
+                // and verified right before the next DW_TAG_compile_unit is
+                // processed to make sure that there are no gaps in the address
+                // range.
+                range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+                if (range.lo_pc != DW_INVALID_ADDRESS)
+                {
+                    range.hi_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
+                    if (range.hi_pc != DW_INVALID_ADDRESS)
+                    {
+                        range.offset = die->GetOffset();
+                        bool valid = range.ValidRange();
+                        if (!valid || s->GetVerbose())
+                        {
+                            s->Printf("\n  FUNC ");
+                            range.Dump(s);
+                            if (!valid)
+                            {
+                                ++verifyInfo->addr_range_errors;
+                                s->Printf(" ERROR: Invalid address range for function.");
+                            }
+                        }
+
+                        // Only add to our subroutine ranges if our compile unit has a valid address range
+                    //  if (valid && verifyInfo->die_ranges.size() >= 2 && verifyInfo->die_ranges[1].range.ValidRange())
+                    //      verifyInfo->subroutine_ranges.InsertRange(range);
+                    }
+                }
+                break;
+
+            case DW_TAG_lexical_block:
+            case DW_TAG_inlined_subroutine:
+                {
+                    range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+                    if (range.lo_pc != DW_INVALID_ADDRESS)
+                    {
+                        range.hi_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
+                        if (range.hi_pc != DW_INVALID_ADDRESS)
+                        {
+                            range.offset = die->GetOffset();
+                            bool valid = range.ValidRange();
+                            if (!valid || s->GetVerbose())
+                            {
+                                s->Printf("\n  BLCK ");
+                                range.Dump(s);
+                                if (!valid)
+                                {
+                                    ++verifyInfo->addr_range_errors;
+                                    s->Printf(" ERROR: Invalid address range for block or inlined subroutine.");
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+
+            if (range.ValidRange() && verifyInfo->die_ranges.back().range.ValidRange())
+            {
+                if (!verifyInfo->die_ranges.back().range.Contains(range))
+                {
+                    ++verifyInfo->addr_range_errors;
+                    s->Printf("\n       ");
+                    range.Dump(s);
+                    s->Printf(" ERROR: Range is not in parent");
+                    verifyInfo->die_ranges.back().range.Dump(s);
+                }
+            }
+
+            if (die->HasChildren())
+            {
+                // Keep tabs on the valid address ranges for the current item to make
+                // sure that it all fits (make sure the sibling offsets got fixed up
+                // correctly if any functions were dead stripped).
+                DIERange die_range;
+                die_range.range = range;
+                die_range.lo_die_offset = next_offset;
+                die_range.hi_die_offset = sibling;
+                if (die_range.hi_die_offset == DW_INVALID_OFFSET)
+                    die_range.hi_die_offset = verifyInfo->die_ranges.back().hi_die_offset;
+                verifyInfo->die_ranges.push_back(die_range);
+            }
+        }
+        else
+        {
+            // NULL entry
+            verifyInfo->die_ranges.pop_back();
+        }
+    }
+    else
+    {
+    //  cu->Dump(ostrm_ptr); // Dump the compile unit for the DIE
+        // We have a new comile unit header
+        verifyInfo->die_ranges.clear();
+        DIERange die_range;
+        die_range.range.offset  = cu->GetOffset();
+        die_range.lo_die_offset = next_offset;
+        die_range.hi_die_offset = cu->GetNextCompileUnitOffset();
+        verifyInfo->die_ranges.push_back(die_range);
+    }
+
+    // Just return the current offset to parse the next CU or DIE entry
+    return next_offset;
+}
+
+
+class CompareDIEStatSizes
+{
+public:
+    bool operator() (const DIEStatMap::const_iterator& pos1, const DIEStatMap::const_iterator& pos2) const
+    {
+        return pos1->second.byte_size <= pos2->second.byte_size;
+    }
+};
+
+class CompareAttrDIEStatSizes
+{
+public:
+    bool operator() (const DwarfAttrStatMap::const_iterator& pos1, const DwarfAttrStatMap::const_iterator& pos2) const
+    {
+        return pos1->second.byte_size <= pos2->second.byte_size;
+    }
+};
+
+//----------------------------------------------------------------------
+// Verify
+//
+// Verifies the DWARF information is valid.
+//----------------------------------------------------------------------
+void
+DWARFDebugInfo::Verify(Stream *s, SymbolFileDWARF* dwarf2Data)
+{
+    s->Printf("Verifying Compile Unit Header chain.....");
+    VerifyInfo verifyInfo(s);
+    verifyInfo.addr_range_errors = 0;
+    verifyInfo.sibling_errors = 0;
+
+    bool verbose = s->GetVerbose();
+
+    uint32_t offset = 0;
+    if (verbose)
+        s->EOL();
+//  vector<dw_offset_t> valid_cu_offsets;
+    DWARFCompileUnit cu (dwarf2Data);
+    bool success = true;
+    while ( success && dwarf2Data->get_debug_info_data().ValidOffset(offset+cu.Size()) )
+    {
+        success = cu.Extract (dwarf2Data->get_debug_info_data(), &offset);
+        if (!success)
+            s->Printf("ERROR\n");
+    //  else
+    //      valid_cu_offsets.push_back(cu.GetOffset());
+
+        cu.Verify(verifyInfo.strm);
+        offset = cu.GetNextCompileUnitOffset();
+    }
+
+    if (success)
+        s->Printf("OK\n");
+
+    s->Printf("Verifying address ranges and siblings...");
+    if (verbose)
+        s->EOL();
+    DWARFDebugInfo::Parse(dwarf2Data, VerifyCallback, &verifyInfo);
+
+//  VerifyAddressRangesForCU(&verifyInfo);
+
+    if (verifyInfo.addr_range_errors > 0)
+        s->Printf("\nERRORS - %u error(s) were found.\n", verifyInfo.addr_range_errors);
+    else
+        s->Printf("OK\n");
+
+    uint32_t total_category_sizes[kNumTagCategories] = {0};
+    uint32_t total_category_count[kNumTagCategories] = {0};
+    uint32_t total_die_count = 0;
+    uint32_t total_die_size = 0;
+
+    typedef set<DIEStatMap::const_iterator, CompareDIEStatSizes> DIEStatBySizeMap;
+
+    s->PutCString(  "\n"
+                "DWARF Statistics\n"
+                "Count    Size     Size %   Tag\n"
+                "-------- -------- -------- -------------------------------------------\n");
+    DIEStatBySizeMap statBySizeMap;
+    DIEStatMap::const_iterator pos;
+    DIEStatMap::const_iterator end_pos = verifyInfo.die_stats.end();
+    for (pos = verifyInfo.die_stats.begin(); pos != end_pos; ++pos)
+    {
+        const uint32_t die_count = pos->second.count;
+        const uint32_t die_size = pos->second.byte_size;
+
+        statBySizeMap.insert(pos);
+        total_die_count += die_count;
+        total_die_size += die_size;
+        DW_TAG_CategoryEnum category = get_tag_category(pos->first);
+        total_category_sizes[category] += die_size;
+        total_category_count[category] += die_count;
+    }
+
+    float total_die_size_float = total_die_size;
+
+    DIEStatBySizeMap::const_reverse_iterator size_pos;
+    DIEStatBySizeMap::const_reverse_iterator size_pos_end = statBySizeMap.rend();
+    float percentage;
+    for (size_pos = statBySizeMap.rbegin(); size_pos != size_pos_end; ++size_pos)
+    {
+        pos = *size_pos;
+
+        const DIEStat& tag_stat = pos->second;
+
+        const uint32_t die_count = tag_stat.count;
+        const uint32_t die_size = tag_stat.byte_size;
+        percentage = ((float)die_size/total_die_size_float)*100.0;
+        s->Printf("%7u %8u %2.2f%%     %s\n", die_count, die_size, percentage, DW_TAG_value_to_name(pos->first));
+
+        const DwarfAttrStatMap& attr_stats = tag_stat.attr_stats;
+        if (!attr_stats.empty())
+        {
+            typedef set<DwarfAttrStatMap::const_iterator, CompareAttrDIEStatSizes> DwarfAttrStatBySizeMap;
+            DwarfAttrStatBySizeMap attrStatBySizeMap;
+            DwarfAttrStatMap::const_iterator attr_stat_pos;
+            DwarfAttrStatMap::const_iterator attr_stat_pos_end = attr_stats.end();
+            for (attr_stat_pos = attr_stats.begin(); attr_stat_pos != attr_stat_pos_end; ++attr_stat_pos)
+            {
+                attrStatBySizeMap.insert(attr_stat_pos);
+            }
+
+            DwarfAttrStatBySizeMap::const_reverse_iterator attr_size_pos;
+            DwarfAttrStatBySizeMap::const_reverse_iterator attr_size_pos_end = attrStatBySizeMap.rend();
+            for (attr_size_pos = attrStatBySizeMap.rbegin(); attr_size_pos != attr_size_pos_end; ++attr_size_pos)
+            {
+                attr_stat_pos = *attr_size_pos;
+                percentage = ((float)attr_stat_pos->second.byte_size/die_size)*100.0;
+                s->Printf("%7u %8u %2.2f%%    %s\n", attr_stat_pos->second.count, attr_stat_pos->second.byte_size, percentage, DW_AT_value_to_name(attr_stat_pos->first));
+            }
+            s->EOL();
+        }
+    }
+
+    s->Printf("-------- -------- -------- -------------------------------------------\n");
+    s->Printf("%7u %8u 100.00% Total for all DIEs\n", total_die_count, total_die_size);
+
+    float total_category_percentages[kNumTagCategories] =
+    {
+        ((float)total_category_sizes[TagCategoryVariable]/total_die_size_float)*100.0,
+        ((float)total_category_sizes[TagCategoryType]/total_die_size_float)*100.0,
+        ((float)total_category_sizes[TagCategoryProgram]/total_die_size_float)*100.0
+    };
+
+    s->EOL();
+    s->Printf("%7u %8u %2.2f%%    %s\n", total_category_count[TagCategoryVariable], total_category_sizes[TagCategoryVariable],  total_category_percentages[TagCategoryVariable],    "Total for variable related DIEs");
+    s->Printf("%7u %8u %2.2f%%    %s\n", total_category_count[TagCategoryType],     total_category_sizes[TagCategoryType],      total_category_percentages[TagCategoryType],        "Total for type related DIEs");
+    s->Printf("%7u %8u %2.2f%%    %s\n", total_category_count[TagCategoryProgram],      total_category_sizes[TagCategoryProgram],   total_category_percentages[TagCategoryProgram],     "Total for program related DIEs");
+    s->Printf("\n\n");
+}
+
+typedef struct DumpInfo
+{
+    DumpInfo(Stream* init_strm, uint32_t off, uint32_t depth) :
+        strm(init_strm),
+        die_offset(off),
+        recurse_depth(depth),
+        found_depth(UINT_MAX),
+        found_die(false),
+        ancestors()
+    {
+    }
+    Stream* strm;
+    const uint32_t die_offset;
+    const uint32_t recurse_depth;
+    uint32_t found_depth;
+    bool found_die;
+    std::vector<DWARFDebugInfoEntry> ancestors;
+
+    DISALLOW_COPY_AND_ASSIGN(DumpInfo);
+} DumpInfo;
+
+//----------------------------------------------------------------------
+// DumpCallback
+//
+// A callback function for the static DWARFDebugInfo::Parse() function
+// that gets called each time a compile unit header or debug information
+// entry is successfully parsed.
+//
+// This function dump DWARF information and obey recurse depth and
+// wether a single DIE is to be dumped (or all of the data).
+//----------------------------------------------------------------------
+static dw_offset_t DumpCallback
+(
+    SymbolFileDWARF* dwarf2Data,
+    DWARFCompileUnitSP& cu_sp,
+    DWARFDebugInfoEntry* die,
+    const dw_offset_t next_offset,
+    const uint32_t curr_depth,
+    void* userData
+)
+{
+    DumpInfo* dumpInfo = (DumpInfo*)userData;
+
+    const DWARFCompileUnit* cu = cu_sp.get();
+
+    Stream *s = dumpInfo->strm;
+    bool show_parents = s->GetFlags().IsSet(DWARFDebugInfo::eDumpFlag_ShowAncestors);
+
+    if (die)
+    {
+        // Are we dumping everything?
+        if (dumpInfo->die_offset == DW_INVALID_OFFSET)
+        {
+            // Yes we are dumping everything. Obey our recurse level though
+            if (curr_depth < dumpInfo->recurse_depth)
+                die->Dump(dwarf2Data, cu, s, 0);
+        }
+        else
+        {
+            // We are dumping a specific DIE entry by offset
+            if (dumpInfo->die_offset == die->GetOffset())
+            {
+                // We found the DIE we were looking for, dump it!
+                if (show_parents)
+                {
+                    s->SetIndentLevel(0);
+                    const uint32_t num_ancestors = dumpInfo->ancestors.size();
+                    if (num_ancestors > 0)
+                    {
+                        for (uint32_t i=0; i<num_ancestors-1; ++i)
+                        {
+                            dumpInfo->ancestors[i].Dump(dwarf2Data, cu, s, 0);
+                            s->IndentMore();
+                        }
+                    }
+                }
+
+                dumpInfo->found_depth = curr_depth;
+
+                die->Dump(dwarf2Data, cu, s, 0);
+
+                // Note that we found the DIE we were looking for
+                dumpInfo->found_die = true;
+
+                // Since we are dumping a single DIE, if there are no children we are done!
+                if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
+                    return DW_INVALID_OFFSET;   // Return an invalid address to end parsing
+            }
+            else if (dumpInfo->found_die)
+            {
+                // Are we done with all the children?
+                if (curr_depth <= dumpInfo->found_depth)
+                    return DW_INVALID_OFFSET;
+
+                // We have already found our DIE and are printing it's children. Obey
+                // our recurse depth and return an invalid offset if we get done
+                // dumping all the the children
+                if (dumpInfo->recurse_depth == UINT_MAX || curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
+                    die->Dump(dwarf2Data, cu, s, 0);
+            }
+            else if (dumpInfo->die_offset > die->GetOffset())
+            {
+                if (show_parents)
+                    dumpInfo->ancestors.back() = *die;
+            }
+        }
+
+        // Keep up with our indent level
+        if (die->IsNULL())
+        {
+            if (show_parents)
+                dumpInfo->ancestors.pop_back();
+
+            if (curr_depth <= 1)
+                return cu->GetNextCompileUnitOffset();
+            else
+                s->IndentLess();
+        }
+        else if (die->HasChildren())
+        {
+            if (show_parents)
+            {
+                DWARFDebugInfoEntry null_die;
+                dumpInfo->ancestors.push_back(null_die);
+            }
+            s->IndentMore();
+        }
+    }
+    else
+    {
+        if (cu == NULL)
+            s->PutCString("NULL - cu");
+        // We have a compile unit, reset our indent level to zero just in case
+        s->SetIndentLevel(0);
+
+        // See if we are dumping everything?
+        if (dumpInfo->die_offset == DW_INVALID_OFFSET)
+        {
+            // We are dumping everything
+            cu->Dump(s);
+            return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this Compile Unit
+        }
+        else
+        {
+            if (show_parents)
+            {
+                dumpInfo->ancestors.clear();
+                dumpInfo->ancestors.resize(1);
+            }
+
+            // We are dumping only a single DIE possibly with it's children and
+            // we must find it's compile unit before we can dump it properly
+            if (dumpInfo->die_offset < cu->GetFirstDIEOffset())
+            {
+                // Not found, maybe the DIE offset provided wasn't correct?
+            //  *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << " was not found." << endl;
+                return DW_INVALID_OFFSET;
+            }
+            else
+            {
+                // See if the DIE is in this compile unit?
+                if (dumpInfo->die_offset < cu->GetNextCompileUnitOffset())
+                {
+                    // This DIE is in this compile unit!
+                    if (s->GetVerbose())
+                        cu->Dump(s); // Dump the compile unit for the DIE in verbose mode
+
+                    return next_offset;
+                //  // We found our compile unit that contains our DIE, just skip to dumping the requested DIE...
+                //  return dumpInfo->die_offset;
+                }
+                else
+                {
+                    // Skip to the next compile unit as the DIE isn't in the current one!
+                    return cu->GetNextCompileUnitOffset();
+                }
+            }
+        }
+    }
+
+    // Just return the current offset to parse the next CU or DIE entry
+    return next_offset;
+}
+
+//----------------------------------------------------------------------
+// Dump
+//
+// Dump the information in the .debug_info section to the specified
+// ostream. If die_offset is valid, a single DIE will be dumped. If the
+// die_offset is invalid, all the DWARF information will be dumped. Both
+// cases will obey a "recurse_depth" or how deep to traverse into the
+// children of each DIE entry. A recurse_depth of zero will dump all
+// compile unit headers. A recurse_depth of 1 will dump all compile unit
+// headers and the DW_TAG_compile unit tags. A depth of 2 will also
+// dump all types and functions.
+//----------------------------------------------------------------------
+void
+DWARFDebugInfo::Dump
+(
+    Stream *s,
+    SymbolFileDWARF* dwarf2Data,
+    const uint32_t die_offset,
+    const uint32_t recurse_depth
+)
+{
+    DumpInfo dumpInfo(s, die_offset, recurse_depth);
+    s->PutCString(".debug_info contents");
+    if (dwarf2Data->get_debug_info_data().GetByteSize() > 0)
+    {
+        if (die_offset == DW_INVALID_OFFSET)
+            s->PutCString(":\n");
+        else
+        {
+            s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset);
+            if (recurse_depth != UINT_MAX)
+                s->Printf(" recursing %u levels deep.", recurse_depth);
+            s->EOL();
+        }
+    }
+    else
+    {
+        s->PutCString(": < EMPTY >\n");
+        return;
+    }
+    DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo);
+}
+
+
+//----------------------------------------------------------------------
+// Dump
+//
+// Dump the contents of this DWARFDebugInfo object as has been parsed
+// and/or modified after it has been parsed.
+//----------------------------------------------------------------------
+void
+DWARFDebugInfo::Dump (Stream *s, const uint32_t die_offset, const uint32_t recurse_depth)
+{
+    DumpInfo dumpInfo(s, die_offset, recurse_depth);
+
+    s->PutCString("Dumping .debug_info section from internal representation\n");
+
+    CompileUnitColl::const_iterator pos;
+    uint32_t curr_depth = 0;
+    ParseCompileUnitHeadersIfNeeded();
+    for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos)
+    {
+        const DWARFCompileUnitSP& cu_sp = *pos;
+        DumpCallback(m_dwarf2Data, (DWARFCompileUnitSP&)cu_sp, NULL, 0, curr_depth, &dumpInfo);
+        cu_sp->DIE()->Dump(m_dwarf2Data, cu_sp.get(), s, recurse_depth);
+    }
+}
+
+
+//----------------------------------------------------------------------
+// FindCallbackString
+//
+// A callback function for the static DWARFDebugInfo::Parse() function
+// that gets called each time a compile unit header or debug information
+// entry is successfully parsed.
+//
+// This function will find the die_offset of any items whose DW_AT_name
+// matches the given string
+//----------------------------------------------------------------------
+typedef struct FindCallbackStringInfoTag
+{
+    const char* name;
+    bool ignore_case;
+    RegularExpression* regex;
+    vector<dw_offset_t>& die_offsets;
+} FindCallbackStringInfo;
+
+static dw_offset_t FindCallbackString
+(
+    SymbolFileDWARF* dwarf2Data,
+    DWARFCompileUnitSP& cu_sp,
+    DWARFDebugInfoEntry* die,
+    const dw_offset_t next_offset,
+    const uint32_t curr_depth,
+    void* userData
+)
+{
+    FindCallbackStringInfo* info = (FindCallbackStringInfo*)userData;
+    const DWARFCompileUnit* cu = cu_sp.get();
+
+    if (die)
+    {
+        const char* die_name = die->GetName(dwarf2Data, cu);
+        if (die_name)
+        {
+            if (info->regex)
+            {
+                if (info->regex->Execute(die_name))
+                    info->die_offsets.push_back(die->GetOffset());
+            }
+            else
+            {
+                if ((info->ignore_case ? strcasecmp(die_name, info->name) : strcmp(die_name, info->name)) == 0)
+                    info->die_offsets.push_back(die->GetOffset());
+            }
+        }
+    }
+
+    // Just return the current offset to parse the next CU or DIE entry
+    return next_offset;
+}
+
+//----------------------------------------------------------------------
+// Find
+//
+// Finds all DIE that have a specific DW_AT_name attribute by manually
+// searching through the debug information (not using the
+// .debug_pubnames section). The string must match the entire name
+// and case sensitive searches are an option.
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfo::Find(const char* name, bool ignore_case, vector<dw_offset_t>& die_offsets) const
+{
+    die_offsets.clear();
+    if (name && name[0])
+    {
+        FindCallbackStringInfo info = { name, ignore_case, NULL, die_offsets };
+        DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
+    }
+    return !die_offsets.empty();
+}
+
+//----------------------------------------------------------------------
+// Find
+//
+// Finds all DIE that have a specific DW_AT_name attribute by manually
+// searching through the debug information (not using the
+// .debug_pubnames section). The string must match the supplied regular
+// expression.
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfo::Find(RegularExpression& re, vector<dw_offset_t>& die_offsets) const
+{
+    die_offsets.clear();
+    FindCallbackStringInfo info = { NULL, false, &re, die_offsets };
+    DWARFDebugInfo::Parse(m_dwarf2Data, FindCallbackString, &info);
+    return !die_offsets.empty();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
new file mode 100644
index 0000000..f506a3d
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -0,0 +1,86 @@
+//===-- DWARFDebugInfo.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugInfo_h_
+#define SymbolFileDWARF_DWARFDebugInfo_h_
+
+#include <vector>
+#include <map>
+
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-private.h"
+#include "SymbolFileDWARF.h"
+
+typedef std::multimap<const char*, dw_offset_t, CStringCompareFunctionObject> CStringToDIEMap;
+typedef CStringToDIEMap::iterator CStringToDIEMapIter;
+typedef CStringToDIEMap::const_iterator CStringToDIEMapConstIter;
+
+typedef lldb::SharedPtr<DWARFCompileUnit>::Type DWARFCompileUnitSP;
+
+class DWARFDebugInfo
+{
+public:
+    typedef dw_offset_t (*Callback)(
+        SymbolFileDWARF* dwarf2Data,
+        DWARFCompileUnitSP& cu_shared_ptr,
+        DWARFDebugInfoEntry* die,
+        const dw_offset_t next_offset,
+        const uint32_t depth,
+        void* userData);
+
+    DWARFDebugInfo();
+    void SetDwarfData(SymbolFileDWARF* dwarf2Data);
+    bool BuildFunctionAddressRangeTable(DWARFDebugAranges* debug_aranges);
+
+    bool LookupAddress(
+            const dw_addr_t address,
+            const dw_offset_t cu_offset,    // Can be valid (find in .debug_aranges), or DW_INVALID_OFFSET if we need to search manually
+            DWARFCompileUnitSP& cu_shared_ptr,
+            DWARFDebugInfoEntry** function_die,
+            DWARFDebugInfoEntry** block_die);
+
+    void AddCompileUnit(DWARFCompileUnitSP& cu);
+    uint32_t GetNumCompileUnits();
+    DWARFCompileUnit* GetCompileUnitAtIndex(uint32_t idx);
+    DWARFCompileUnitSP GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
+    DWARFCompileUnitSP GetCompileUnitContainingDIE(dw_offset_t die_offset);
+
+    DWARFDebugInfoEntry* GetDIEPtr(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr);
+    const DWARFDebugInfoEntry* GetDIEPtrContainingOffset(dw_offset_t die_offset, DWARFCompileUnitSP* cu_sp_ptr);
+
+    void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth);
+    static void Parse(SymbolFileDWARF* parser, Callback callback, void* userData);
+    static void Verify(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data);
+    static void Dump(lldb_private::Stream *s, SymbolFileDWARF* dwarf2Data, const uint32_t die_offset, const uint32_t recurse_depth);
+    bool Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const;
+    bool Find(lldb_private::RegularExpression& re, std::vector<dw_offset_t>& die_offsets) const;
+
+    enum
+    {
+        eDumpFlag_Verbose               = (1<<0),   // Verbose dumping
+        eDumpFlag_ShowForm              = (1<<1),   // Show the DW_form type
+        eDumpFlag_EnglishyNames         = (1<<2),   // Show the DW_TAG, DW_AT and DW_FORM types in more englishy names instead of as DWARF definitions values
+        eDumpFlag_ShowAncestors         = (1<<3)    // Show all parent DIEs when dumping single DIEs
+    };
+
+
+protected:
+    SymbolFileDWARF* m_dwarf2Data;
+    typedef std::vector<DWARFCompileUnitSP>     CompileUnitColl;
+
+    CompileUnitColl m_compile_units;
+
+private:
+    // All parsing needs to be done partially any managed by this class as accessors are called.
+    void ParseCompileUnitHeadersIfNeeded();
+
+    DISALLOW_COPY_AND_ASSIGN (DWARFDebugInfo);
+};
+
+#endif  // SymbolFileDWARF_DWARFDebugInfo_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
new file mode 100644
index 0000000..19eef06
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -0,0 +1,1929 @@
+//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugInfoEntry.h"
+
+#include <assert.h>
+
+#include <algorithm>
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "DWARFCompileUnit.h"
+#include "SymbolFileDWARF.h"
+#include "DWARFDebugAbbrev.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFDIECollection.h"
+#include "DWARFFormValue.h"
+#include "DWARFLocationDescription.h"
+#include "DWARFLocationList.h"
+#include "DWARFDebugRanges.h"
+
+using namespace lldb_private;
+using namespace std;
+extern int g_verbose;
+
+
+
+DWARFDebugInfoEntry::Attributes::Attributes() :
+    m_infos()
+{
+    m_infos.reserve(20);
+}
+
+DWARFDebugInfoEntry::Attributes::~Attributes()
+{
+}
+
+
+uint32_t
+DWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const
+{
+    std::vector<Info>::const_iterator end = m_infos.end();
+    std::vector<Info>::const_iterator beg = m_infos.begin();
+    std::vector<Info>::const_iterator pos;
+    for (pos = beg; pos != end; ++pos)
+    {
+        if (pos->attr == attr)
+            return std::distance(beg, pos);
+    }
+    return UINT_MAX;
+}
+
+void
+DWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form)
+{
+    Info info = { cu, attr_die_offset, attr, form };
+    m_infos.push_back(info);
+}
+
+bool
+DWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const
+{
+    return FindAttributeIndex(attr) != UINT_MAX;
+}
+
+bool
+DWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr)
+{
+    uint32_t attr_index = FindAttributeIndex(attr);
+    if (attr_index != UINT_MAX)
+    {
+        m_infos.erase(m_infos.begin() + attr_index);
+        return true;
+    }
+    return false;
+}
+
+bool
+DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const
+{
+    form_value.SetForm(FormAtIndex(i));
+    dw_offset_t offset = DIEOffsetAtIndex(i);
+    return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i));
+}
+
+uint64_t
+DWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const
+{
+    DWARFFormValue form_value;
+    if (ExtractFormValueAtIndex(dwarf2Data, i, form_value))
+        return form_value.Reference(CompileUnitAtIndex(i));
+    return fail_value;
+}
+
+
+//----------------------------------------------------------------------
+// Extract
+//
+// Extract a debug info entry for a given compile unit from the
+// .debug_info and .debug_abbrev data within the SymbolFileDWARF class
+// starting at the given offset
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfoEntry::Extract
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    uint32_t* offset_ptr
+)
+{
+    const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
+//    const DataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
+    const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
+    const uint8_t cu_addr_size = cu->GetAddressByteSize();
+    uint32_t offset = *offset_ptr;
+//  if (offset >= cu_end_offset)
+//      Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
+    if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
+    {
+        m_offset = offset;
+
+        dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
+
+        if (abbrCode)
+        {
+            m_abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);
+
+            if (m_abbrevDecl)
+            {
+                dw_tag_t tag = m_abbrevDecl->Tag();
+
+                bool isCompileUnitTag = tag == DW_TAG_compile_unit;
+                if (cu && isCompileUnitTag)
+                    ((DWARFCompileUnit*)cu)->SetBaseAddress(0);
+
+                // Skip all data in the .debug_info for the attributes
+                const uint32_t numAttributes = m_abbrevDecl->NumAttributes();
+                uint32_t i;
+                dw_attr_t attr;
+                dw_form_t form;
+                for (i=0; i<numAttributes; ++i)
+                {
+                    m_abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+
+                    if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc)))
+                    {
+                        DWARFFormValue form_value(form);
+                        if (form_value.ExtractValue(debug_info_data, &offset, cu))
+                        {
+                            if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
+                                ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned());
+                        }
+                    }
+                    else
+                    {
+die_extract_indirect_form:
+                        register uint32_t form_size = 0;
+                        switch (form)
+                        {
+                        // Blocks if inlined data that have a length field and the data bytes
+                        // inlined in the .debug_info
+                        case DW_FORM_block      : form_size = debug_info_data.GetULEB128(&offset);  break;
+                        case DW_FORM_block1     : form_size = debug_info_data.GetU8(&offset);       break;
+                        case DW_FORM_block2     : form_size = debug_info_data.GetU16(&offset);      break;
+                        case DW_FORM_block4     : form_size = debug_info_data.GetU32(&offset);      break;
+
+                        // Inlined NULL terminated C-strings
+                        case DW_FORM_string     :
+                            {
+//                                const char *s = 
+                                debug_info_data.GetCStr(&offset);
+//                                switch (attr)
+//                                {
+//                                case DW_AT_name: m_name = s; break;
+//                                case DW_AT_MIPS_linkage_name: m_linkage_name = s; break;
+//                                default: break;
+//                                }
+                            }
+                            break;
+
+                        // Compile unit address sized values
+                        case DW_FORM_addr       :
+                        case DW_FORM_ref_addr   :
+                            form_size = cu_addr_size;
+                            break;
+
+                        // 1 byte values
+                        case DW_FORM_data1      :
+                        case DW_FORM_flag       :
+                        case DW_FORM_ref1       :
+                            form_size = 1;
+                            break;
+
+                        // 2 byte values
+                        case DW_FORM_data2      :
+                        case DW_FORM_ref2       :
+                            form_size = 2;
+                            break;
+
+                        // 4 byte values
+                        case DW_FORM_strp       :
+//                            switch (attr)
+//                            {
+//                            case DW_AT_name:
+//                                m_name = debug_str_data.PeekCStr(debug_info_data.GetU32(&offset));
+//                                break;
+//                            case DW_AT_MIPS_linkage_name:
+//                                m_linkage_name = debug_str_data.PeekCStr(debug_info_data.GetU32(&offset));
+//                                break;
+//
+//                            default:
+                                form_size = 4;
+//                                break;
+//                            }
+                            break;
+
+                        case DW_FORM_data4      :
+                        case DW_FORM_ref4       :
+                            form_size = 4;
+                            break;
+
+                        // 8 byte values
+                        case DW_FORM_data8      :
+                        case DW_FORM_ref8       :
+                            form_size = 8;
+                            break;
+
+                        // signed or unsigned LEB 128 values
+                    //  case DW_FORM_APPLE_db_str:
+                        case DW_FORM_sdata      :
+                        case DW_FORM_udata      :
+                        case DW_FORM_ref_udata  :
+                            debug_info_data.Skip_LEB128(&offset);
+                            break;
+
+                        case DW_FORM_indirect   :
+                            form = debug_info_data.GetULEB128(&offset);
+                            goto die_extract_indirect_form;
+
+                        default:
+                            *offset_ptr = offset;
+                            return false;
+                        }
+
+                        offset += form_size;
+                    }
+                }
+                *offset_ptr = offset;
+                return true;
+            }
+        }
+        else
+        {
+            m_abbrevDecl = NULL;
+            *offset_ptr = offset;
+            return true;    // NULL debug tag entry
+        }
+    }
+
+    return false;
+}
+
+//----------------------------------------------------------------------
+// AppendDependentDIES()
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfoEntry::AppendDependentDIES
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const bool add_children,
+    DWARFDIECollection& dependent_dies
+) const
+{
+    // Add this object's DIE offset
+    // The line below is the only place that should add a die to the
+    // dependent_dies collection as we have to be careful of recursion!
+    if ( !dependent_dies.Insert(this) )
+        return false;   // This DIE already exists in the collection, nothing to do!
+
+    //DEBUG_PRINTF("    dependent_dies.Insert(0x%8.8x)\n", GetOffset());///
+
+    if (m_abbrevDecl)
+    {
+        // Keep adding parent DIE offsets as long as the offsets do not
+        // already exist in the collection
+        const DWARFDebugInfoEntry* die = GetParent();
+        while ( die && die->AppendDependentDIES(dwarf2Data, cu, false, dependent_dies) )
+            die = die->GetParent();
+
+        bool add_non_subprogram_children = false;
+        bool add_children_override = false;
+
+        if (!add_children)
+        {
+            switch (m_abbrevDecl->Tag())
+            {
+            case DW_TAG_array_type:                                             break;
+            case DW_TAG_class_type:         add_non_subprogram_children = true; break;
+            case DW_TAG_entry_point:                                            break;
+            case DW_TAG_enumeration_type:                                       break;
+            case DW_TAG_formal_parameter:                                       break;
+            case DW_TAG_imported_declaration:                                   break;
+            case DW_TAG_label:                                                  break;
+            case DW_TAG_lexical_block:      add_children_override = true;       break;
+            case DW_TAG_member:                                                 break;
+            case DW_TAG_pointer_type:                                           break;
+            case DW_TAG_reference_type:                                         break;
+            case DW_TAG_compile_unit:                                           break;
+            case DW_TAG_string_type:                                            break;
+            case DW_TAG_structure_type:     add_non_subprogram_children = true; break;
+            case DW_TAG_subroutine_type:    add_children_override = true;       break;
+            case DW_TAG_typedef:                                                break;
+            case DW_TAG_union_type:         add_non_subprogram_children = true; break;
+            case DW_TAG_unspecified_parameters:                                 break;
+            case DW_TAG_variant:                                                break;
+            case DW_TAG_common_block:                                           break;
+            case DW_TAG_common_inclusion:                                       break;
+            case DW_TAG_inheritance:                                            break;
+            case DW_TAG_inlined_subroutine:                                     break;
+            case DW_TAG_module:                                                 break;
+            case DW_TAG_ptr_to_member_type:                                     break;
+            case DW_TAG_set_type:                                               break;
+            case DW_TAG_subrange_type:                                          break;
+            case DW_TAG_with_stmt:                                              break;
+            case DW_TAG_access_declaration:                                     break;
+            case DW_TAG_base_type:                                              break;
+            case DW_TAG_catch_block:                                            break;
+            case DW_TAG_const_type:                                             break;
+            case DW_TAG_constant:                                               break;
+            case DW_TAG_enumerator:                                             break;
+            case DW_TAG_file_type:                                              break;
+            case DW_TAG_friend:                                                 break;
+            case DW_TAG_namelist:                                               break;
+            case DW_TAG_namelist_item:                                          break;
+            case DW_TAG_packed_type:                                            break;
+            case DW_TAG_subprogram:             add_children_override = true;   break;
+            case DW_TAG_template_type_parameter:                                break;
+            case DW_TAG_template_value_parameter:                               break;
+            case DW_TAG_thrown_type:                                            break;
+            case DW_TAG_try_block:                                              break;
+            case DW_TAG_variant_part:                                           break;
+            case DW_TAG_variable:                                               break;
+            case DW_TAG_volatile_type:                                          break;
+            case DW_TAG_dwarf_procedure:                                        break;
+            case DW_TAG_restrict_type:                                          break;
+            case DW_TAG_interface_type:                                         break;
+            case DW_TAG_namespace:                                              break;
+            case DW_TAG_imported_module:                                        break;
+            case DW_TAG_unspecified_type:                                       break;
+            case DW_TAG_partial_unit:                                           break;
+            case DW_TAG_imported_unit:                                          break;
+            case DW_TAG_shared_type:                                            break;
+            }
+        }
+        const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
+
+        // Dump all data in the .debug_info for the attributes
+        const uint32_t numAttributes = m_abbrevDecl->NumAttributes();
+        uint32_t i;
+        dw_offset_t offset = GetOffset();
+        debug_info_data.Skip_LEB128(&offset);   // Skip abbreviation code
+
+        dw_attr_t attr;
+        dw_form_t form;
+        for (i=0; i<numAttributes; ++i)
+        {
+            m_abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+            DWARFFormValue form_value(form);
+
+            switch (attr)
+            {
+            // All cases that use refer to another DIE should use this case
+            // without
+            // having to check the FORM of the attribute to tell if it refers to another
+            // DIE
+            case DW_AT_abstract_origin:
+            case DW_AT_import:
+            case DW_AT_discr:
+            case DW_AT_containing_type:
+            case DW_AT_base_types:
+            case DW_AT_friend:
+            case DW_AT_specification:
+            case DW_AT_type:
+            case DW_AT_common_reference:
+            case DW_AT_default_value:
+                {
+                    form_value.ExtractValue(debug_info_data, &offset, cu);
+                    DWARFCompileUnitSP cu_sp_ptr;
+                    const DWARFDebugInfoEntry* ref_die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
+                    if (ref_die)
+                        ref_die->AppendDependentDIES(dwarf2Data, cu_sp_ptr.get(), true, dependent_dies);
+                }
+                break;
+
+            default:
+                if (attr != DW_AT_sibling)
+                {
+                    switch (form_value.Form())
+                    {
+                    case DW_FORM_ref_addr:
+                    case DW_FORM_ref1:
+                    case DW_FORM_ref2:
+                    case DW_FORM_ref4:
+                    case DW_FORM_ref8:
+                    case DW_FORM_ref_udata:
+//                      Log::WarningVerbose("DWARFDebugInfoEntry::AppendDependentDIES() -- check on this item %s: attr = %s  form = %s",
+//                          DW_TAG_value_to_name(m_abbrevDecl->Tag()),
+//                          DW_AT_value_to_name(attr),
+//                          DW_FORM_value_to_name(form));
+                        break;
+                    }
+                }
+                form_value.SkipValue(debug_info_data, &offset, cu);
+                break;
+            }
+        }
+
+        if (m_abbrevDecl->HasChildren())
+        {
+            const DWARFDebugInfoEntry* child;
+            for (child = GetFirstChild(); child != NULL; child = child->GetSibling())
+            {
+                bool add = add_children || add_children_override;
+
+                if (!add)
+                {
+                    if (add_non_subprogram_children)
+                    {
+                        // add_non_subprogram_children is used for classes and structs
+                        // that may contain children that are the member variables that
+                        // may have functions as children and whom may add the class or
+                        // struct by adding their parent. We don't want to add any
+                        // functions though since they may have been optimized out. But
+                        // we do need to watch for declarations and keep them.
+                        if (child->Tag() == DW_TAG_subprogram)
+                        {
+                            // Check if this subprogram TAG had a DW_AT_declaration attribute set to 1.
+                            // If so we need to include this DIE so that we always have a complete view
+                            // of a class definition so debuggers can track down any weak symbols that
+                            // may not have had weak definition entries.
+                            if (child->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_declaration, 0) == 1)
+                                add = true;
+                        }
+                        else
+                        {
+                            // Add all other items inside a class/struct
+                            add = true;
+                        }
+                    }
+                    else
+                    {
+                        // We don't need to add this child, only add it if it's a NULL tag
+                        add = child->IsNULL();
+                    }
+                }
+
+                if (add)
+                    child->AppendDependentDIES(dwarf2Data, cu, true, dependent_dies);
+            }
+        }
+    }
+    return true;
+}
+
+//----------------------------------------------------------------------
+// DumpAncestry
+//
+// Dumps all of a debug information entries parents up until oldest and
+// all of it's attributes to the specified stream.
+//----------------------------------------------------------------------
+void
+DWARFDebugInfoEntry::DumpAncestry
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const DWARFDebugInfoEntry* oldest,
+    Stream *s,
+    uint32_t recurse_depth
+) const
+{
+    const DWARFDebugInfoEntry* parent = GetParent();
+    if (parent && parent != oldest)
+        parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
+    Dump(dwarf2Data, cu, s, recurse_depth);
+}
+
+//----------------------------------------------------------------------
+// Compare two DIE by comparing all their attributes values, and
+// following all DW_FORM_ref attributes and comparing their contents as
+// well (except for DW_AT_sibling attributes.
+//
+//  DWARFDebugInfoEntry::CompareState compare_state;
+//  int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true);
+//----------------------------------------------------------------------
+int
+DWARFDebugInfoEntry::Compare
+(
+    SymbolFileDWARF* dwarf2Data,
+    dw_offset_t a_die_offset,
+    dw_offset_t b_die_offset,
+    CompareState &compare_state,
+    bool compare_siblings,
+    bool compare_children
+)
+{
+    if (a_die_offset == b_die_offset)
+        return 0;
+
+    DWARFCompileUnitSP a_cu_sp;
+    DWARFCompileUnitSP b_cu_sp;
+    const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp);
+    const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp);
+
+    return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children);
+}
+
+int
+DWARFDebugInfoEntry::Compare
+(
+    SymbolFileDWARF* dwarf2Data,
+    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
+    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
+    CompareState &compare_state,
+    bool compare_siblings,
+    bool compare_children
+)
+{
+    if (a_die == b_die)
+        return 0;
+
+    if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset()))
+    {
+        // We are already comparing both of these types, so let
+        // compares complete for the real result
+        return 0;
+    }
+
+    //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset());
+
+    // Do we have two valid DIEs?
+    if (a_die && b_die)
+    {
+        // Both DIE are valid
+        int result = 0;
+
+        const dw_tag_t a_tag = a_die->Tag();
+        const dw_tag_t b_tag = b_die->Tag();
+        if (a_tag == 0 && b_tag == 0)
+            return 0;
+
+        //printf("    comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag));
+
+        if (a_tag < b_tag)
+            return -1;
+        else if (a_tag > b_tag)
+            return 1;
+
+        DWARFDebugInfoEntry::Attributes a_attrs;
+        DWARFDebugInfoEntry::Attributes b_attrs;
+        size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs);
+        size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs);
+        if (a_attr_count != b_attr_count)
+        {
+            a_attrs.RemoveAttribute(DW_AT_sibling);
+            b_attrs.RemoveAttribute(DW_AT_sibling);
+        }
+
+        a_attr_count = a_attrs.Size();
+        b_attr_count = b_attrs.Size();
+
+        DWARFFormValue a_form_value;
+        DWARFFormValue b_form_value;
+
+        if (a_attr_count != b_attr_count)
+        {
+            uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration);
+            uint32_t a_name_index = UINT_MAX;
+            uint32_t b_name_index = UINT_MAX;
+            if (is_decl_index != UINT_MAX)
+            {
+                if (a_attr_count == 2)
+                {
+                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
+                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
+                }
+            }
+            else
+            {
+                is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration);
+                if (is_decl_index != UINT_MAX && a_attr_count == 2)
+                {
+                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
+                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
+                }
+            }
+            if (a_name_index != UINT_MAX && b_name_index != UINT_MAX)
+            {
+                if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) &&
+                    b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value))
+                {
+                    result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data());
+                    if (result == 0)
+                    {
+                        a_attr_count = b_attr_count = 0;
+                        compare_children = false;
+                    }
+                }
+            }
+        }
+
+        if (a_attr_count < b_attr_count)
+            return -1;
+        if (a_attr_count > b_attr_count)
+            return 1;
+
+
+        // The number of attributes are the same...
+        if (a_attr_count > 0)
+        {
+            const DataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data();
+
+            uint32_t i;
+            for (i=0; i<a_attr_count; ++i)
+            {
+                const dw_attr_t a_attr = a_attrs.AttributeAtIndex(i);
+                const dw_attr_t b_attr = b_attrs.AttributeAtIndex(i);
+                //printf("    comparing attributes\n\t\t0x%8.8x: %s %s\t\t0x%8.8x: %s %s\n",
+                //                a_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(a_attrs.FormAtIndex(i)), DW_AT_value_to_name(a_attr),
+                //                b_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(b_attrs.FormAtIndex(i)), DW_AT_value_to_name(b_attr));
+
+                if (a_attr < b_attr)
+                    return -1;
+                else if (a_attr > b_attr)
+                    return 1;
+
+                switch (a_attr)
+                {
+                // Since we call a form of GetAttributes which inlines the
+                // attributes from DW_AT_abstract_origin and DW_AT_specification
+                // we don't care if their values mismatch...
+                case DW_AT_abstract_origin:
+                case DW_AT_specification:
+                case DW_AT_sibling:
+                case DW_AT_containing_type:
+                    //printf("        action = IGNORE\n");
+                    result = 0;
+                    break;  // ignore
+
+                default:
+                    if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) &&
+                        b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value))
+                        result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr);
+                    break;
+                }
+
+                //printf("\t  result = %i\n", result);
+
+                if (result != 0)
+                {
+                    // Attributes weren't equal, lets see if we care?
+                    switch (a_attr)
+                    {
+                    case DW_AT_decl_file:
+                        // TODO: add the ability to compare files in two different compile units
+                        if (a_cu == b_cu)
+                        {
+                            //printf("        action = RETURN RESULT\n");
+                            return result;  // Only return the compare results when the compile units are the same and the decl_file attributes can be compared
+                        }
+                        else
+                        {
+                            result = 0;
+                            //printf("        action = IGNORE\n");
+                        }
+                        break;
+
+                    default:
+                        switch (a_attrs.FormAtIndex(i))
+                        {
+                        case DW_FORM_ref1:
+                        case DW_FORM_ref2:
+                        case DW_FORM_ref4:
+                        case DW_FORM_ref8:
+                        case DW_FORM_ref_udata:
+                        case DW_FORM_ref_addr:
+                            //printf("    action = COMPARE DIEs 0x%8.8x 0x%8.8x\n", (dw_offset_t)a_form_value.Reference(a_cu), (dw_offset_t)b_form_value.Reference(b_cu));
+                            // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets...
+                            result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true);
+                            if (result != 0)
+                                return result;
+                            break;
+
+                        default:
+                            // We do care that they were different, return this result...
+                            //printf("        action = RETURN RESULT\n");
+                            return result;
+                        }
+                    }
+                }
+            }
+        }
+        //printf("    SUCCESS\n\t\t0x%8.8x: %s\n\t\t0x%8.8x: %s\n", a_die->GetOffset(), DW_TAG_value_to_name(a_tag), b_die->GetOffset(), DW_TAG_value_to_name(b_tag));
+
+        if (compare_children)
+        {
+            bool a_has_children = a_die->HasChildren();
+            bool b_has_children = b_die->HasChildren();
+            if (a_has_children == b_has_children)
+            {
+                // Both either have kids or don't
+                if (a_has_children)
+                    result = Compare(   dwarf2Data,
+                                        a_cu, a_die->GetFirstChild(),
+                                        b_cu, b_die->GetFirstChild(),
+                                        compare_state, true, compare_children);
+                else
+                    result = 0;
+            }
+            else if (!a_has_children)
+                result = -1;    // A doesn't have kids, but B does
+            else
+                result = 1; // A has kids, but B doesn't
+        }
+
+        if (compare_siblings)
+        {
+            result = Compare(   dwarf2Data,
+                                a_cu, a_die->GetSibling(),
+                                b_cu, b_die->GetSibling(),
+                                compare_state, true, compare_children);
+        }
+
+        return result;
+    }
+
+    if (a_die == NULL)
+        return -1;  // a_die is NULL, yet b_die is non-NULL
+    else
+        return 1;   // a_die is non-NULL, yet b_die is NULL
+
+}
+
+//
+//int
+//DWARFDebugInfoEntry::Compare
+//(
+//  SymbolFileDWARF* dwarf2Data,
+//  const DWARFCompileUnit* cu_a,
+//  const DWARFDebugInfoEntry* die_a,
+//  const DWARFCompileUnit* cu_a,
+//  const DWARFDebugInfoEntry* die_b,
+//  CompareState &compare_state
+//)
+//{
+//}
+
+//----------------------------------------------------------------------
+// GetDIENamesAndRanges
+//
+// Gets the valid address ranges for a given DIE by looking for a
+// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
+// attributes.
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfoEntry::GetDIENamesAndRanges
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const char * &name,
+    const char * &mangled,
+    DWARFDebugRanges::RangeList& ranges,
+    int& decl_file,
+    int& decl_line,
+    int& decl_column,
+    int& call_file,
+    int& call_line,
+    int& call_column,
+    DWARFExpression *frame_base
+) const
+{
+    if (dwarf2Data == NULL)
+        return false;
+
+    dw_addr_t lo_pc = DW_INVALID_ADDRESS;
+    dw_addr_t hi_pc = DW_INVALID_ADDRESS;
+    std::vector<dw_offset_t> die_offsets;
+    if (m_abbrevDecl)
+    {
+        const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
+        uint32_t offset = m_offset;
+
+        if (!debug_info_data.ValidOffset(offset))
+            return false;
+
+        // Skip the abbreviation code
+        debug_info_data.Skip_LEB128(&offset);
+
+        const uint32_t numAttributes = m_abbrevDecl->NumAttributes();
+        uint32_t i;
+        dw_attr_t attr;
+        dw_form_t form;
+        for (i=0; i<numAttributes; ++i)
+        {
+            m_abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+            DWARFFormValue form_value(form);
+            if (form_value.ExtractValue(debug_info_data, &offset, cu))
+            {
+                switch (attr)
+                {
+                case DW_AT_low_pc:
+                case DW_AT_entry_pc:
+                    lo_pc = form_value.Unsigned();
+                    break;
+
+                case DW_AT_high_pc:
+                    hi_pc = form_value.Unsigned();
+                    break;
+
+                case DW_AT_ranges:
+                    {
+                        const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
+                        debug_ranges->FindRanges(form_value.Unsigned(), ranges);
+                        // All DW_AT_ranges are relative to the base address of the
+                        // compile unit. We add the compile unit base address to make
+                        // sure all the addresses are properly fixed up.
+                        ranges.AddOffset(cu->GetBaseAddress());
+                    }
+                    break;
+
+                case DW_AT_name:
+                    if (name == NULL)
+                        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+                    break;
+
+                case DW_AT_MIPS_linkage_name:
+                    if (mangled == NULL)
+                        mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+                    break;
+
+                case DW_AT_abstract_origin:
+                    die_offsets.push_back(form_value.Reference(cu));
+                    break;
+
+                case DW_AT_specification:
+                    die_offsets.push_back(form_value.Reference(cu));
+                    break;
+
+                case DW_AT_decl_file:
+                    if (decl_file == 0)
+                        decl_file = form_value.Unsigned();
+                    break;
+
+                case DW_AT_decl_line:
+                    if (decl_line == 0)
+                        decl_line = form_value.Unsigned();
+                    break;
+
+                case DW_AT_decl_column:
+                    if (decl_column == 0)
+                        decl_column = form_value.Unsigned();
+                    break;
+
+                case DW_AT_call_file:
+                    if (call_file == 0)
+                        call_file = form_value.Unsigned();
+                    break;
+
+                case DW_AT_call_line:
+                    if (call_line == 0)
+                        call_line = form_value.Unsigned();
+                    break;
+
+                case DW_AT_call_column:
+                    if (call_column == 0)
+                        call_column = form_value.Unsigned();
+                    break;
+
+                case DW_AT_frame_base:
+                    if (frame_base)
+                    {
+                        if (form_value.BlockData())
+                        {
+                            uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+                            uint32_t block_length = form_value.Unsigned();
+                            frame_base->SetOpcodeData(debug_info_data, block_offset, block_length, NULL);
+                        }
+                        else
+                        {
+                            const DataExtractor&    debug_loc_data = dwarf2Data->get_debug_loc_data();
+                            const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+                            size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
+                            if (loc_list_length > 0)
+                            {
+                                Address base_address(cu->GetBaseAddress(), dwarf2Data->GetObjectFile()->GetSectionList());
+                                frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
+                            }
+                        }
+                    }
+                    break;
+
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
+    size_t numRanges = ranges.Size();
+
+    if (numRanges == 0)
+    {
+        if (lo_pc != DW_INVALID_ADDRESS)
+        {
+            if (hi_pc != DW_INVALID_ADDRESS)
+                ranges.AddRange(lo_pc, hi_pc);
+            else
+                ranges.AddRange(lo_pc, lo_pc);
+        }
+    }
+
+    if (ranges.Size() == 0 || (name == NULL) || (mangled == NULL))
+    {
+        std::vector<dw_offset_t>::const_iterator pos;
+        std::vector<dw_offset_t>::const_iterator end = die_offsets.end();
+        for (pos = die_offsets.begin(); pos != end; ++pos)
+        {
+            DWARFCompileUnitSP cu_sp_ptr;
+            const DWARFDebugInfoEntry* die = NULL;
+            dw_offset_t die_offset = *pos;
+            if (die_offset != DW_INVALID_OFFSET)
+            {
+                die = dwarf2Data->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
+                if (die)
+                    die->GetDIENamesAndRanges(dwarf2Data, cu_sp_ptr.get(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
+            }
+        }
+    }
+    return ranges.Size() > 0;
+}
+
+//----------------------------------------------------------------------
+// Dump
+//
+// Dumps a debug information entry and all of it's attributes to the
+// specified stream.
+//----------------------------------------------------------------------
+void
+DWARFDebugInfoEntry::Dump
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    Stream *s,
+    uint32_t recurse_depth
+) const
+{
+    const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
+    uint32_t offset = m_offset;
+    bool english    = s->GetFlags().IsSet (DWARFDebugInfo::eDumpFlag_EnglishyNames);
+
+    if (debug_info_data.ValidOffset(offset))
+    {
+        dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
+
+        s->Printf("\n0x%8.8x: ", m_offset);
+        s->Indent();
+        if (abbrCode)
+        {
+            if (m_abbrevDecl)
+            {
+                if (english)
+                    s->PutCString(DW_TAG_value_to_englishy_name(m_abbrevDecl->Tag()));
+                else
+                    s->PutCString(DW_TAG_value_to_name(m_abbrevDecl->Tag()));
+                s->Printf( " [%u] %c\n", abbrCode, m_abbrevDecl->HasChildren() ? '*':' ');
+
+                // Dump all data in the .debug_info for the attributes
+                const uint32_t numAttributes = m_abbrevDecl->NumAttributes();
+                uint32_t i;
+                dw_attr_t attr;
+                dw_form_t form;
+                for (i=0; i<numAttributes; ++i)
+                {
+                    m_abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+
+                    DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form);
+                }
+
+                const DWARFDebugInfoEntry* child = GetFirstChild();
+                if (recurse_depth > 0 && child)
+                {
+                    s->IndentMore();
+
+                    while (child)
+                    {
+                        child->Dump(dwarf2Data, cu, s, recurse_depth-1);
+                        child = child->GetSibling();
+                    }
+                    s->IndentLess();
+                }
+            }
+            else
+                s->Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode);
+        }
+        else
+        {
+            s->Printf( "NULL\n");
+        }
+    }
+}
+
+//----------------------------------------------------------------------
+// DumpAttribute
+//
+// Dumps a debug information entry attribute along with it's form. Any
+// special display of attributes is done (disassemble location lists,
+// show enumeration values for attributes, etc).
+//----------------------------------------------------------------------
+void
+DWARFDebugInfoEntry::DumpAttribute
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const DataExtractor& debug_info_data,
+    uint32_t* offset_ptr,
+    Stream *s,
+    dw_attr_t attr,
+    dw_form_t form
+)
+{
+    bool verbose    = s->GetVerbose();
+    bool show_form  = s->GetFlags().IsSet(DWARFDebugInfo::eDumpFlag_ShowForm);
+    bool english    = s->GetFlags().IsSet(DWARFDebugInfo::eDumpFlag_EnglishyNames);
+    const DataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL;
+    if (verbose)
+        s->Offset(*offset_ptr);
+    else
+        s->Printf( "            ");
+    s->Indent();
+
+    if (english)
+        s->PutCString(DW_AT_value_to_englishy_name(attr));
+    else
+        s->PutCString(DW_AT_value_to_name(attr));
+
+    if (show_form)
+    {
+        s->Printf( "[%s", english ? DW_FORM_value_to_englishy_name(form) : DW_FORM_value_to_name(form));
+    }
+
+    DWARFFormValue form_value(form);
+
+    if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu))
+        return;
+
+    if (show_form)
+    {
+        if (form == DW_FORM_indirect)
+        {
+            s->Printf( " [%s]", english ? DW_FORM_value_to_englishy_name(form_value.Form()) : DW_FORM_value_to_name(form_value.Form()));
+        }
+
+        s->PutCString("] ");
+    }
+
+    s->PutCString("( ");
+
+    // Always dump form value if verbose is enabled
+    if (verbose)
+    {
+        form_value.Dump(s, debug_str_data, cu);
+    }
+
+
+    // Check to see if we have any special attribute formatters
+    switch (attr)
+    {
+    case DW_AT_stmt_list:
+        if ( verbose ) s->PutCString(" ( ");
+        s->Printf( "0x%8.8x", form_value.Unsigned());
+        if ( verbose ) s->PutCString(" )");
+        break;
+
+    case DW_AT_language:
+        if ( verbose ) s->PutCString(" ( ");
+        s->PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
+        if ( verbose ) s->PutCString(" )");
+        break;
+
+    case DW_AT_encoding:
+        if ( verbose ) s->PutCString(" ( ");
+        s->PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
+        if ( verbose ) s->PutCString(" )");
+        break;
+
+    case DW_AT_frame_base:
+    case DW_AT_location:
+    case DW_AT_data_member_location:
+        {
+            const uint8_t* blockData = form_value.BlockData();
+            if (blockData)
+            {
+                if (!verbose)
+                    form_value.Dump(s, debug_str_data, cu);
+
+                // Location description is inlined in data in the form value
+                DataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
+                if ( verbose ) s->PutCString(" ( ");
+                print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
+                if ( verbose ) s->PutCString(" )");
+            }
+            else
+            {
+                // We have a location list offset as the value that is
+                // the offset into the .debug_loc section that describes
+                // the value over it's lifetime
+                uint64_t debug_loc_offset = form_value.Unsigned();
+                if (dwarf2Data)
+                {
+                    if ( !verbose )
+                        form_value.Dump(s, debug_str_data, cu);
+                    DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
+                }
+                else
+                {
+                    if ( !verbose )
+                        form_value.Dump(s, NULL, cu);
+                }
+            }
+        }
+        break;
+
+    case DW_AT_abstract_origin:
+    case DW_AT_specification:
+        {
+            uint64_t abstract_die_offset = form_value.Reference(cu);
+            form_value.Dump(s, debug_str_data, cu);
+        //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
+            if ( verbose ) s->PutCString(" ( ");
+            GetName(dwarf2Data, cu, abstract_die_offset, s);
+            if ( verbose ) s->PutCString(" )");
+        }
+        break;
+
+    case DW_AT_type:
+        {
+            uint64_t type_die_offset = form_value.Reference(cu);
+            if (!verbose)
+                form_value.Dump(s, debug_str_data, cu);
+            s->PutCString(" ( ");
+            AppendTypeName(dwarf2Data, cu, type_die_offset, s);
+            s->PutCString(" )");
+        }
+        break;
+
+    case DW_AT_ranges:
+        {
+            if ( !verbose )
+                form_value.Dump(s, debug_str_data, cu);
+            uint32_t ranges_offset = form_value.Unsigned();
+            dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
+            DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
+        }
+        break;
+
+    default:
+        if ( !verbose )
+            form_value.Dump(s, debug_str_data, cu);
+        break;
+    }
+
+    s->PutCString(" )\n");
+}
+
+//----------------------------------------------------------------------
+// Get all attribute values for a given DIE, including following any
+// specification or abstract origin attributes and including those in
+// the results. Any duplicate attributes will have the first instance
+// take precedence (this can happen for declaration attributes).
+//----------------------------------------------------------------------
+size_t
+DWARFDebugInfoEntry::GetAttributes
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    DWARFDebugInfoEntry::Attributes& attributes
+) const
+{
+    if (m_abbrevDecl)
+    {
+        uint32_t offset = GetOffset();
+        const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
+
+        // Skip the abbreviation code so we are at the data for the attributes
+        debug_info_data.Skip_LEB128(&offset);
+
+        const uint32_t num_attributes = m_abbrevDecl->NumAttributes();
+        uint32_t i;
+        dw_attr_t attr;
+        dw_form_t form;
+        DWARFFormValue form_value;
+        for (i=0; i<num_attributes; ++i)
+        {
+            m_abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form);
+            attributes.Append(cu, offset, attr, form);
+            if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))
+            {
+                form_value.SetForm(form);
+                if (form_value.ExtractValue(debug_info_data, &offset, cu))
+                {
+                    const DWARFDebugInfoEntry* die = NULL;
+                    dw_offset_t die_offset = form_value.Reference(cu);
+                    if (cu->ContainsDIEOffset(die_offset))
+                    {
+                        die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset);
+                        if (die)
+                            die->GetAttributes(dwarf2Data, cu, attributes);
+                    }
+                    else
+                    {
+                        DWARFCompileUnitSP cu_sp_ptr;
+                        die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
+                        if (die)
+                            die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), attributes);
+                    }
+                }
+            }
+            else
+            {
+                assert(DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu));
+            }
+        }
+    }
+    else
+    {
+        attributes.Clear();
+    }
+    return attributes.Size();
+
+}
+
+//----------------------------------------------------------------------
+// GetAttributeValue
+//
+// Get the value of an attribute and return the .debug_info offset of the
+// attribute if it was properly extracted into form_value, or zero
+// if we fail since an offset of zero is invalid for an attribute (it
+// would be a compile unit header).
+//----------------------------------------------------------------------
+dw_offset_t
+DWARFDebugInfoEntry::GetAttributeValue
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    DWARFFormValue& form_value,
+    dw_offset_t* end_attr_offset_ptr
+) const
+{
+    if (m_abbrevDecl)
+    {
+        uint32_t attr_idx = m_abbrevDecl->FindAttributeIndex(attr);
+
+        if (attr_idx != DW_INVALID_INDEX)
+        {
+            uint32_t offset = GetOffset();
+
+            const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
+
+            // Skip the abbreviation code so we are at the data for the attributes
+            debug_info_data.Skip_LEB128(&offset);
+
+            uint32_t idx=0;
+            while (idx<attr_idx)
+                DWARFFormValue::SkipValue(m_abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
+
+            const dw_offset_t attr_offset = offset;
+            form_value.SetForm(m_abbrevDecl->GetFormByIndex(idx));
+            if (form_value.ExtractValue(debug_info_data, &offset, cu))
+            {
+                if (end_attr_offset_ptr)
+                    *end_attr_offset_ptr = offset;
+                return attr_offset;
+            }
+        }
+    }
+
+    return 0;
+}
+
+//----------------------------------------------------------------------
+// GetAttributeValueAsString
+//
+// Get the value of an attribute as a string return it. The resulting
+// pointer to the string data exists within the supplied SymbolFileDWARF
+// and will only be available as long as the SymbolFileDWARF is still around
+// and it's content doesn't change.
+//----------------------------------------------------------------------
+const char*
+DWARFDebugInfoEntry::GetAttributeValueAsString
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    const char* fail_value) const
+{
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
+        return form_value.AsCString(&dwarf2Data->get_debug_str_data());
+    return fail_value;
+}
+
+//----------------------------------------------------------------------
+// GetAttributeValueAsUnsigned
+//
+// Get the value of an attribute as unsigned and return it.
+//----------------------------------------------------------------------
+uint64_t
+DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    uint64_t fail_value
+) const
+{
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
+        return form_value.Unsigned();
+    return fail_value;
+}
+
+//----------------------------------------------------------------------
+// GetAttributeValueAsSigned
+//
+// Get the value of an attribute a signed value and return it.
+//----------------------------------------------------------------------
+int64_t
+DWARFDebugInfoEntry::GetAttributeValueAsSigned
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    int64_t fail_value
+) const
+{
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
+        return form_value.Signed();
+    return fail_value;
+}
+
+//----------------------------------------------------------------------
+// GetAttributeValueAsReference
+//
+// Get the value of an attribute as reference and fix up and compile
+// unit relative offsets as needed.
+//----------------------------------------------------------------------
+uint64_t
+DWARFDebugInfoEntry::GetAttributeValueAsReference
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    uint64_t fail_value
+) const
+{
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
+        return form_value.Reference(cu);
+    return fail_value;
+}
+
+//----------------------------------------------------------------------
+// GetAttributeValueAsLocation
+//
+// Get the value of an attribute as reference and fix up and compile
+// unit relative offsets as needed.
+//----------------------------------------------------------------------
+dw_offset_t
+DWARFDebugInfoEntry::GetAttributeValueAsLocation
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    DataExtractor& location_data,
+    uint32_t &block_size
+) const
+{
+    block_size = 0;
+    DWARFFormValue form_value;
+
+    // Empty out data in case we don't find anything
+    location_data.Clear();
+    dw_offset_t end_addr_offset = DW_INVALID_OFFSET;
+    const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset);
+    if (attr_offset)
+    {
+        const uint8_t* blockData = form_value.BlockData();
+        if (blockData)
+        {
+            // We have an inlined location list in the .debug_info section
+            const DataExtractor& debug_info = dwarf2Data->get_debug_info_data();
+            dw_offset_t block_offset = blockData - debug_info.GetDataStart();
+            block_size = (end_addr_offset - attr_offset) - form_value.Unsigned();
+            location_data.SetData(debug_info, block_offset, block_size);
+        }
+        else
+        {
+            // We have a location list offset as the value that is
+            // the offset into the .debug_loc section that describes
+            // the value over it's lifetime
+            dw_offset_t debug_loc_offset = form_value.Unsigned();
+            if (dwarf2Data)
+            {
+                assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
+                return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data);
+            }
+        }
+    }
+    return attr_offset;
+}
+
+//----------------------------------------------------------------------
+// GetName
+//
+// Get value of the DW_AT_name attribute and return it if one exists,
+// else return NULL.
+//----------------------------------------------------------------------
+const char*
+DWARFDebugInfoEntry::GetName
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu
+) const
+{
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
+        return form_value.AsCString(&dwarf2Data->get_debug_str_data());
+    return NULL;
+}
+
+
+//----------------------------------------------------------------------
+// GetMangledName
+//
+// Get value of the DW_AT_MIPS_linkage_name attribute and return it if
+// one exists, else return the value of the DW_AT_name attribute
+//----------------------------------------------------------------------
+const char*
+DWARFDebugInfoEntry::GetMangledName
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    bool substitute_name_allowed
+) const
+{
+    const char* name = NULL;
+    DWARFFormValue form_value;
+
+    if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
+        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+
+    if (substitute_name_allowed && name == NULL)
+    {
+        if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
+            name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+    }
+    return name;
+}
+
+
+//----------------------------------------------------------------------
+// GetPubname
+//
+// Get value the name for a DIE as it should appear for a
+// .debug_pubnames or .debug_pubtypes section.
+//----------------------------------------------------------------------
+const char*
+DWARFDebugInfoEntry::GetPubname
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu
+) const
+{
+    const char* name = NULL;
+    DWARFFormValue form_value;
+
+    if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
+        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
+        name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
+    {
+        // The specification DIE may be in another compile unit so we need
+        // to get a die and its compile unit.
+        DWARFCompileUnitSP cu_sp_ptr;
+        const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
+        if (die)
+            return die->GetPubname(dwarf2Data, cu_sp_ptr.get());
+    }
+    return name;
+}
+
+
+//----------------------------------------------------------------------
+// GetName
+//
+// Get value of the DW_AT_name attribute for a debug information entry
+// that exists at offset "die_offset" and place that value into the
+// supplied stream object. If the DIE is a NULL object "NULL" is placed
+// into the stream, and if no DW_AT_name attribute exists for the DIE
+// then nothing is printed.
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfoEntry::GetName
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const uint32_t die_offset,
+    Stream *s
+)
+{
+    DWARFDebugInfoEntry die;
+    uint32_t offset = die_offset;
+    if (die.Extract(dwarf2Data, cu, &offset))
+    {
+        if (die.IsNULL())
+        {
+            s->PutCString("NULL");
+            return true;
+        }
+        else
+        {
+            DWARFFormValue form_value;
+            if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
+            {
+                const char* name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+                if (name)
+                {
+                    s->PutCString(name);
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+//----------------------------------------------------------------------
+// AppendTypeName
+//
+// Follows the type name definition down through all needed tags to
+// end up with a fully qualified type name and dump the results to
+// the supplied stream. This is used to show the name of types given
+// a type identifier.
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfoEntry::AppendTypeName
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const uint32_t die_offset,
+    Stream *s
+)
+{
+    DWARFDebugInfoEntry die;
+    uint32_t offset = die_offset;
+    if (die.Extract(dwarf2Data, cu, &offset))
+    {
+        if (die.IsNULL())
+        {
+            s->PutCString("NULL");
+            return true;
+        }
+        else
+        {
+            const char* name = die.GetPubname(dwarf2Data, cu);
+        //  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
+        //      name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+            if (name)
+                s->PutCString(name);
+            else
+            {
+                bool result = true;
+                const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr();
+
+                switch (abbrevDecl->Tag())
+                {
+                case DW_TAG_array_type:         break;  // print out a "[]" after printing the full type of the element below
+                case DW_TAG_base_type:          s->PutCString("base ");         break;
+                case DW_TAG_class_type:         s->PutCString("class ");            break;
+                case DW_TAG_const_type:         s->PutCString("const ");            break;
+                case DW_TAG_enumeration_type:   s->PutCString("enum ");         break;
+                case DW_TAG_file_type:          s->PutCString("file ");         break;
+                case DW_TAG_interface_type:     s->PutCString("interface ");        break;
+                case DW_TAG_packed_type:        s->PutCString("packed ");       break;
+                case DW_TAG_pointer_type:       break;  // print out a '*' after printing the full type below
+                case DW_TAG_ptr_to_member_type: break;  // print out a '*' after printing the full type below
+                case DW_TAG_reference_type:     break;  // print out a '&' after printing the full type below
+                case DW_TAG_restrict_type:      s->PutCString("restrict ");     break;
+                case DW_TAG_set_type:           s->PutCString("set ");          break;
+                case DW_TAG_shared_type:        s->PutCString("shared ");       break;
+                case DW_TAG_string_type:        s->PutCString("string ");       break;
+                case DW_TAG_structure_type:     s->PutCString("struct ");       break;
+                case DW_TAG_subrange_type:      s->PutCString("subrange ");     break;
+                case DW_TAG_subroutine_type:    s->PutCString("function ");     break;
+                case DW_TAG_thrown_type:        s->PutCString("thrown ");       break;
+                case DW_TAG_union_type:         s->PutCString("union ");            break;
+                case DW_TAG_unspecified_type:   s->PutCString("unspecified ");  break;
+                case DW_TAG_volatile_type:      s->PutCString("volatile ");     break;
+                default:
+                    return false;
+                }
+
+                // Follow the DW_AT_type if possible
+                DWARFFormValue form_value;
+                if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
+                {
+                    uint64_t next_die_offset = form_value.Reference(cu);
+                    result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
+                }
+
+                switch (abbrevDecl->Tag())
+                {
+                case DW_TAG_array_type:         s->PutCString("[]");    break;
+                case DW_TAG_pointer_type:       s->PutChar('*');    break;
+                case DW_TAG_ptr_to_member_type: s->PutChar('*');    break;
+                case DW_TAG_reference_type:     s->PutChar('&');    break;
+                default:
+                    break;
+                }
+                return result;
+            }
+        }
+    }
+    return false;
+}
+
+//----------------------------------------------------------------------
+// BuildAddressRangeTable
+//----------------------------------------------------------------------
+void
+DWARFDebugInfoEntry::BuildAddressRangeTable
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    DWARFDebugAranges* debug_aranges
+) const
+{
+    if (m_abbrevDecl)
+    {
+        dw_tag_t tag = m_abbrevDecl->Tag();
+        if (tag == DW_TAG_subprogram)
+        {
+            dw_addr_t hi_pc = DW_INVALID_ADDRESS;
+            dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+            if (lo_pc != DW_INVALID_ADDRESS)
+                hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
+            if (hi_pc != DW_INVALID_ADDRESS)
+            {
+            /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
+                debug_aranges->InsertRange(cu->GetOffset(), lo_pc, hi_pc);
+            }
+        }
+
+
+        const DWARFDebugInfoEntry* child = GetFirstChild();
+        while (child)
+        {
+            child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
+            child = child->GetSibling();
+        }
+    }
+}
+
+//----------------------------------------------------------------------
+// BuildFunctionAddressRangeTable
+//
+// This function is very similar to the BuildAddressRangeTable function
+// except that the actual DIE offset for the function is placed in the
+// table instead of the compile unit offset (which is the way the
+// standard .debug_aranges section does it).
+//----------------------------------------------------------------------
+void
+DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    DWARFDebugAranges* debug_aranges
+) const
+{
+    if (m_abbrevDecl)
+    {
+        dw_tag_t tag = m_abbrevDecl->Tag();
+        if (tag == DW_TAG_subprogram)
+        {
+            dw_addr_t hi_pc = DW_INVALID_ADDRESS;
+            dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+            if (lo_pc != DW_INVALID_ADDRESS)
+                hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
+            if (hi_pc != DW_INVALID_ADDRESS)
+            {
+            //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
+                debug_aranges->InsertRange(GetOffset(), lo_pc, hi_pc);
+            }
+        }
+
+        const DWARFDebugInfoEntry* child = GetFirstChild();
+        while (child)
+        {
+            child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
+            child = child->GetSibling();
+        }
+    }
+}
+
+
+//----------------------------------------------------------------------
+// LookupAddress
+//----------------------------------------------------------------------
+bool
+DWARFDebugInfoEntry::LookupAddress
+(
+    const dw_addr_t address,
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    DWARFDebugInfoEntry** function_die,
+    DWARFDebugInfoEntry** block_die
+)
+{
+    bool found_address = false;
+    if (m_abbrevDecl)
+    {
+        bool check_children = false;
+        bool match_addr_range = false;
+        dw_tag_t tag = m_abbrevDecl->Tag();
+    //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
+        switch (tag)
+        {
+        case DW_TAG_array_type                 : break;
+        case DW_TAG_class_type                 : check_children = true; break;
+        case DW_TAG_entry_point                : break;
+        case DW_TAG_enumeration_type           : break;
+        case DW_TAG_formal_parameter           : break;
+        case DW_TAG_imported_declaration       : break;
+        case DW_TAG_label                      : break;
+        case DW_TAG_lexical_block              : check_children = true; match_addr_range = true; break;
+        case DW_TAG_member                     : break;
+        case DW_TAG_pointer_type               : break;
+        case DW_TAG_reference_type             : break;
+        case DW_TAG_compile_unit               : match_addr_range = true; break;
+        case DW_TAG_string_type                : break;
+        case DW_TAG_structure_type             : check_children = true; break;
+        case DW_TAG_subroutine_type            : break;
+        case DW_TAG_typedef                    : break;
+        case DW_TAG_union_type                 : break;
+        case DW_TAG_unspecified_parameters     : break;
+        case DW_TAG_variant                    : break;
+        case DW_TAG_common_block               : check_children = true; break;
+        case DW_TAG_common_inclusion           : break;
+        case DW_TAG_inheritance                : break;
+        case DW_TAG_inlined_subroutine         : check_children = true; match_addr_range = true; break;
+        case DW_TAG_module                     : match_addr_range = true; break;
+        case DW_TAG_ptr_to_member_type         : break;
+        case DW_TAG_set_type                   : break;
+        case DW_TAG_subrange_type              : break;
+        case DW_TAG_with_stmt                  : break;
+        case DW_TAG_access_declaration         : break;
+        case DW_TAG_base_type                  : break;
+        case DW_TAG_catch_block                : match_addr_range = true; break;
+        case DW_TAG_const_type                 : break;
+        case DW_TAG_constant                   : break;
+        case DW_TAG_enumerator                 : break;
+        case DW_TAG_file_type                  : break;
+        case DW_TAG_friend                     : break;
+        case DW_TAG_namelist                   : break;
+        case DW_TAG_namelist_item              : break;
+        case DW_TAG_packed_type                : break;
+        case DW_TAG_subprogram                 : match_addr_range = true; break;
+        case DW_TAG_template_type_parameter    : break;
+        case DW_TAG_template_value_parameter   : break;
+        case DW_TAG_thrown_type                : break;
+        case DW_TAG_try_block                  : match_addr_range = true; break;
+        case DW_TAG_variant_part               : break;
+        case DW_TAG_variable                   : break;
+        case DW_TAG_volatile_type              : break;
+        case DW_TAG_dwarf_procedure            : break;
+        case DW_TAG_restrict_type              : break;
+        case DW_TAG_interface_type             : break;
+        case DW_TAG_namespace                  : check_children = true; break;
+        case DW_TAG_imported_module            : break;
+        case DW_TAG_unspecified_type           : break;
+        case DW_TAG_partial_unit               : break;
+        case DW_TAG_imported_unit              : break;
+        case DW_TAG_shared_type                : break;
+        default: break;
+        }
+
+        if (match_addr_range)
+        {
+            dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+            if (lo_pc != DW_INVALID_ADDRESS)
+            {
+                dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
+                if (hi_pc != DW_INVALID_ADDRESS)
+                {
+                    //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
+                    if ((lo_pc <= address) && (address < hi_pc))
+                    {
+                        found_address = true;
+                    //  puts("***MATCH***");
+                        switch (tag)
+                        {
+                        case DW_TAG_compile_unit:       // File
+                            check_children = ((function_die != NULL) || (block_die != NULL));
+                            break;
+
+                        case DW_TAG_subprogram:         // Function
+                            if (function_die)
+                                *function_die = this;
+                            check_children = (block_die != NULL);
+                            break;
+
+                        case DW_TAG_inlined_subroutine: // Inlined Function
+                        case DW_TAG_lexical_block:      // Block { } in code
+                            if (block_die)
+                            {
+                                *block_die = this;
+                                check_children = true;
+                            }
+                            break;
+
+                        default:
+                            check_children = true;
+                            break;
+                        }
+                    }
+                }
+                else
+                {   // compile units may not have a valid high/low pc when there
+                    // are address gaps in subtroutines so we must always search
+                    // if there is no valid high and low PC
+                    check_children = (tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL));
+                }
+            }
+            else
+            {
+                dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
+                if (debug_ranges_offset != DW_INVALID_OFFSET)
+                {
+                    DWARFDebugRanges::RangeList ranges;
+                    DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
+                    debug_ranges->FindRanges(debug_ranges_offset, ranges);
+                    // All DW_AT_ranges are relative to the base address of the
+                    // compile unit. We add the compile unit base address to make
+                    // sure all the addresses are properly fixed up.
+                    ranges.AddOffset(cu->GetBaseAddress());
+                    if (ranges.Lookup(address))
+                    {
+                        found_address = true;
+                    //  puts("***MATCH***");
+                        switch (tag)
+                        {
+                        case DW_TAG_compile_unit:       // File
+                            check_children = ((function_die != NULL) || (block_die != NULL));
+                            break;
+
+                        case DW_TAG_subprogram:         // Function
+                            if (function_die)
+                                *function_die = this;
+                            check_children = (block_die != NULL);
+                            break;
+
+                        case DW_TAG_inlined_subroutine: // Inlined Function
+                        case DW_TAG_lexical_block:      // Block { } in code
+                            if (block_die)
+                            {
+                                *block_die = this;
+                                check_children = true;
+                            }
+                            break;
+
+                        default:
+                            check_children = true;
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        check_children = false;
+                    }
+                }
+            }
+        }
+
+
+        if (check_children)
+        {
+        //  printf("checking children\n");
+            DWARFDebugInfoEntry* child = GetFirstChild();
+            while (child)
+            {
+                if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
+                    return true;
+                child = child->GetSibling();
+            }
+        }
+    }
+    return found_address;
+}
+
+
+bool
+DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
+{
+    return a.GetOffset() < b.GetOffset();
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
new file mode 100644
index 0000000..8340acc
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -0,0 +1,320 @@
+//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugInfoEntry_h_
+#define liblldb_DWARFDebugInfoEntry_h_
+
+#include "SymbolFileDWARF.h"
+#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDebugRanges.h"
+#include <vector>
+#include <map>
+#include <set>
+
+typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t>     DIEToAddressMap;
+typedef DIEToAddressMap::iterator                           DIEToAddressMapIter;
+typedef DIEToAddressMap::const_iterator                     DIEToAddressMapConstIter;
+
+typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*>     AddressToDIEMap;
+typedef AddressToDIEMap::iterator                           AddressToDIEMapIter;
+typedef AddressToDIEMap::const_iterator                     AddressToDIEMapConstIter;
+
+
+typedef std::map<dw_offset_t, dw_offset_t>                  DIEToDIEMap;
+typedef DIEToDIEMap::iterator                               DIEToDIEMapIter;
+typedef DIEToDIEMap::const_iterator                         DIEToDIEMapConstIter;
+
+typedef std::map<uint32_t, const DWARFDebugInfoEntry*>      UInt32ToDIEMap;
+typedef UInt32ToDIEMap::iterator                            UInt32ToDIEMapIter;
+typedef UInt32ToDIEMap::const_iterator                      UInt32ToDIEMapConstIter;
+
+typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap;
+typedef UInt32ToDIEMMap::iterator                           UInt32ToDIEMMapIter;
+typedef UInt32ToDIEMMap::const_iterator                     UInt32ToDIEMMapConstIter;
+
+class DWARFDebugInfoEntry
+{
+public:
+    typedef std::vector<DWARFDebugInfoEntry>    collection;
+    typedef collection::iterator                iterator;
+    typedef collection::const_iterator          const_iterator;
+
+    typedef std::vector<dw_offset_t>            offset_collection;
+    typedef offset_collection::iterator         offset_collection_iterator;
+    typedef offset_collection::const_iterator   offset_collection_const_iterator;
+
+    class Attributes
+    {
+    public:
+        Attributes();
+        ~Attributes();
+
+        void Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form);
+        const DWARFCompileUnit * CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; }
+        dw_offset_t DIEOffsetAtIndex(uint32_t i) const { return m_infos[i].die_offset; }
+        dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr; }
+        dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].form; }
+        bool ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const;
+        uint64_t FormValueAsUnsignedAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const;
+        uint32_t FindAttributeIndex(dw_attr_t attr) const;
+        bool ContainsAttribute(dw_attr_t attr) const;
+        bool RemoveAttribute(dw_attr_t attr);
+        void Clear() { m_infos.clear(); }
+        uint32_t Size() const { return m_infos.size(); }
+
+    protected:
+        struct Info
+        {
+            const DWARFCompileUnit *cu; // Keep the compile unit with each attribute in case we have DW_FORM_ref_addr values
+            dw_offset_t die_offset;
+            dw_attr_t attr;
+            dw_form_t form;
+        };
+        std::vector<Info> m_infos;
+    };
+
+    struct CompareState
+    {
+        CompareState() :
+            die_offset_pairs()
+        {
+            assert(sizeof(dw_offset_t)*2 == sizeof(uint64_t));
+        }
+
+        bool AddTypePair(dw_offset_t a, dw_offset_t b)
+        {
+            uint64_t a_b_offsets = (uint64_t)a << 32 | (uint64_t)b;
+            // Return true if this type was inserted, false otherwise
+            return die_offset_pairs.insert(a_b_offsets).second;
+        }
+        std::set< uint64_t > die_offset_pairs;
+    };
+
+                DWARFDebugInfoEntry():
+                    m_offset        (DW_INVALID_OFFSET),
+                    m_parent_idx    (0),
+                    m_sibling_idx   (0),
+                    m_abbrevDecl    (NULL),
+                    m_user_data     (NULL)
+                {
+                }
+
+
+    void        BuildAddressRangeTable(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    DWARFDebugAranges* debug_aranges) const;
+
+    void        BuildFunctionAddressRangeTable(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    DWARFDebugAranges* debug_aranges) const;
+
+    bool        Extract(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    dw_offset_t* offset_ptr);
+
+    bool        LookupAddress(
+                    const dw_addr_t address,
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    DWARFDebugInfoEntry** function_die,
+                    DWARFDebugInfoEntry** block_die);
+
+    size_t      GetAttributes(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    DWARFDebugInfoEntry::Attributes& attrs) const;
+
+    dw_offset_t GetAttributeValue(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    DWARFFormValue& formValue,
+                    dw_offset_t* end_attr_offset_ptr = NULL) const;
+
+    const char* GetAttributeValueAsString(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    const char* fail_value) const;
+
+    uint64_t    GetAttributeValueAsUnsigned(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    uint64_t fail_value) const;
+
+    uint64_t    GetAttributeValueAsReference(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    uint64_t fail_value) const;
+
+    int64_t     GetAttributeValueAsSigned(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    int64_t fail_value) const;
+
+    dw_offset_t GetAttributeValueAsLocation(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    lldb_private::DataExtractor& data,
+                    uint32_t &block_size) const;
+
+    const char* GetName(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu) const;
+
+    const char* GetMangledName(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    bool substitute_name_allowed = true) const;
+
+    const char* GetPubname(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu) const;
+
+    static bool GetName(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_offset_t die_offset,
+                    lldb_private::Stream *s);
+
+    static bool AppendTypeName(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_offset_t die_offset,
+                    lldb_private::Stream *s);
+
+    static int  Compare(
+                    SymbolFileDWARF* dwarf2Data,
+                    dw_offset_t a_die_offset,
+                    dw_offset_t b_die_offset,
+                    CompareState &compare_state,
+                    bool compare_siblings,
+                    bool compare_children);
+
+    static int Compare(
+                    SymbolFileDWARF* dwarf2Data,
+                    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
+                    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
+                    CompareState &compare_state,
+                    bool compare_siblings,
+                    bool compare_children);
+
+    static bool OffsetLessThan (
+                    const DWARFDebugInfoEntry& a,
+                    const DWARFDebugInfoEntry& b);
+
+    bool        AppendDependentDIES(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const bool add_children,
+                    DWARFDIECollection& die_offsets) const;
+
+    void        Dump(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    lldb_private::Stream *s,
+                    uint32_t recurse_depth) const;
+
+    void        DumpAncestry(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const DWARFDebugInfoEntry* oldest,
+                    lldb_private::Stream *s,
+                    uint32_t recurse_depth) const;
+
+    static void DumpAttribute(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const lldb_private::DataExtractor& debug_info_data,
+                    uint32_t* offset_ptr,
+                    lldb_private::Stream *s,
+                    dw_attr_t attr,
+                    dw_form_t form);
+
+    bool        GetDIENamesAndRanges(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const char * &name,
+                    const char * &mangled,
+                    DWARFDebugRanges::RangeList& rangeList,
+                    int& decl_file,
+                    int& decl_line,
+                    int& decl_column,
+                    int& call_file,
+                    int& call_line,
+                    int& call_column,
+                    lldb_private::DWARFExpression *frame_base = NULL) const;
+
+
+    dw_tag_t    Tag()           const { return m_abbrevDecl ? m_abbrevDecl->Tag() : 0; }
+    bool        IsNULL()        const { return m_abbrevDecl == NULL; }
+    dw_offset_t GetOffset()     const { return m_offset; }
+    void        SetOffset(dw_offset_t offset) { m_offset = offset; }
+    uint32_t    NumAttributes() const { return m_abbrevDecl ? m_abbrevDecl->NumAttributes() : 0; }
+    bool        HasChildren()   const { return m_abbrevDecl != NULL && m_abbrevDecl->HasChildren(); }
+
+            // We know we are kept in a vector of contiguous entries, so we know
+            // our parent will be some index behind "this".
+            DWARFDebugInfoEntry*    GetParent()             { return m_parent_idx > 0 ? this - m_parent_idx : NULL;  }
+    const   DWARFDebugInfoEntry*    GetParent()     const   { return m_parent_idx > 0 ? this - m_parent_idx : NULL;  }
+            // We know we are kept in a vector of contiguous entries, so we know
+            // our sibling will be some index after "this".
+            DWARFDebugInfoEntry*    GetSibling()            { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;  }
+    const   DWARFDebugInfoEntry*    GetSibling()    const   { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;  }
+            // We know we are kept in a vector of contiguous entries, so we know
+            // we don't need to store our child pointer, if we have a child it will
+            // be the next entry in the list...
+            DWARFDebugInfoEntry*    GetFirstChild()         { return HasChildren() ? this + 1 : NULL; }
+    const   DWARFDebugInfoEntry*    GetFirstChild() const   { return HasChildren() ? this + 1 : NULL; }
+
+    void        
+    SetParent (DWARFDebugInfoEntry* parent)     
+    {
+        if (parent)
+        {
+            // We know we are kept in a vector of contiguous entries, so we know
+            // our parent will be some index behind "this".
+            m_parent_idx = this - parent;
+        }
+        else        
+            m_parent_idx = 0;
+    }
+    void
+    SetSibling (DWARFDebugInfoEntry* sibling)
+    {
+        if (sibling)
+        {
+            // We know we are kept in a vector of contiguous entries, so we know
+            // our sibling will be some index after "this".
+            m_sibling_idx = sibling - this;
+            sibling->SetParent(GetParent()); 
+        }
+        else        
+            m_sibling_idx = 0;
+    }
+    const DWARFAbbreviationDeclaration* GetAbbreviationDeclarationPtr() const { return m_abbrevDecl; }
+
+    void *      GetUserData() const { return m_user_data; }
+    void        SetUserData(void *d) const { m_user_data = d; }
+protected:
+    dw_offset_t                         m_offset;       // Offset within the .debug_info of the start of this entry
+    uint32_t                            m_parent_idx;   // How many to subtract from "this" to get the parent. If zero this die has no parent
+    uint32_t                            m_sibling_idx;  // How many to add to "this" to get the sibling.
+    const DWARFAbbreviationDeclaration* m_abbrevDecl;
+    mutable void *                      m_user_data;    // Flags for use by the parsers
+};
+
+#endif  // liblldb_DWARFDebugInfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
new file mode 100644
index 0000000..2b3f39b
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -0,0 +1,1410 @@
+//===-- DWARFDebugLine.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugLine.h"
+
+//#define ENABLE_DEBUG_PRINTF   // DO NOT LEAVE THIS DEFINED: DEBUG ONLY!!!
+#include <assert.h>
+
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Timer.h"
+
+#include "SymbolFileDWARF.h"
+#include "LogChannelDWARF.h"
+
+using namespace lldb_private;
+using namespace std;
+
+//----------------------------------------------------------------------
+// Parse
+//
+// Parse all information in the debug_line_data into an internal
+// representation.
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::Parse(const DataExtractor& debug_line_data)
+{
+    m_lineTableMap.clear();
+    dw_offset_t offset = 0;
+    LineTable::shared_ptr line_table_sp(new LineTable);
+    while (debug_line_data.ValidOffset(offset))
+    {
+        const uint32_t debug_line_offset = offset;
+
+        if (line_table_sp.get() == NULL)
+            break;
+
+        if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get()))
+        {
+            // Make sure we don't don't loop infinitely
+            if (offset <= debug_line_offset)
+                break;
+            //DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", debug_line_offset);
+            m_lineTableMap[debug_line_offset] = line_table_sp;
+            line_table_sp.reset(new LineTable);
+        }
+        else
+            ++offset;   // Try next byte in line table
+    }
+}
+
+void
+DWARFDebugLine::ParseIfNeeded(const DataExtractor& debug_line_data)
+{
+    if (m_lineTableMap.empty())
+        Parse(debug_line_data);
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::GetLineTable
+//----------------------------------------------------------------------
+DWARFDebugLine::LineTable::shared_ptr
+DWARFDebugLine::GetLineTable(const dw_offset_t offset) const
+{
+    DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
+    LineTableConstIter pos = m_lineTableMap.find(offset);
+    if (pos != m_lineTableMap.end())
+        line_table_shared_ptr = pos->second;
+    return line_table_shared_ptr;
+}
+
+
+//----------------------------------------------------------------------
+// DumpStateToFile
+//----------------------------------------------------------------------
+static void
+DumpStateToFile (dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
+{
+    Log *log = (Log *)userData;
+    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
+    {
+        // If the row is zero we are being called with the prologue only
+        state.prologue->Dump (log);
+        log->PutCString ("Address            Line   Column File");
+        log->PutCString ("------------------ ------ ------ ------");
+    }
+    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
+    {
+        // Done parsing line table
+    }
+    else
+    {
+        log->Printf( "0x%16.16llx %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
+    }
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::DumpLineTableRows
+//----------------------------------------------------------------------
+bool
+DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset)
+{
+    const DataExtractor& debug_line_data = dwarf2Data->get_debug_line_data();
+
+    if (debug_line_offset == DW_INVALID_OFFSET)
+    {
+        // Dump line table to a single file only
+        debug_line_offset = 0;
+        while (debug_line_data.ValidOffset(debug_line_offset))
+            debug_line_offset = DumpStatementTable (log, debug_line_data, debug_line_offset);
+    }
+    else
+    {
+        // Dump line table to a single file only
+        DumpStatementTable (log, debug_line_data, debug_line_offset);
+    }
+    return false;
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::DumpStatementTable
+//----------------------------------------------------------------------
+dw_offset_t
+DWARFDebugLine::DumpStatementTable(Log *log, const DataExtractor& debug_line_data, const dw_offset_t debug_line_offset)
+{
+    if (debug_line_data.ValidOffset(debug_line_offset))
+    {
+        uint32_t offset = debug_line_offset;
+        log->Printf(  "----------------------------------------------------------------------\n"
+                    "debug_line[0x%8.8x]\n"
+                    "----------------------------------------------------------------------\n", debug_line_offset);
+
+        if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
+            return offset;
+        else
+            return debug_line_offset + 1;   // Skip to next byte in .debug_line section
+    }
+
+    return DW_INVALID_OFFSET;
+}
+
+
+//----------------------------------------------------------------------
+// DumpOpcodes
+//----------------------------------------------------------------------
+bool
+DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset, uint32_t dump_flags)
+{
+    const DataExtractor& debug_line_data = dwarf2Data->get_debug_line_data();
+
+    if (debug_line_data.GetByteSize() == 0)
+    {
+        log->Printf( "< EMPTY >\n");
+        return false;
+    }
+
+    if (debug_line_offset == DW_INVALID_OFFSET)
+    {
+        // Dump line table to a single file only
+        debug_line_offset = 0;
+        while (debug_line_data.ValidOffset(debug_line_offset))
+            debug_line_offset = DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags);
+    }
+    else
+    {
+        // Dump line table to a single file only
+        DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags);
+    }
+    return false;
+}
+
+//----------------------------------------------------------------------
+// DumpStatementOpcodes
+//----------------------------------------------------------------------
+dw_offset_t
+DWARFDebugLine::DumpStatementOpcodes(Log *log, const DataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags)
+{
+    uint32_t offset = debug_line_offset;
+    if (debug_line_data.ValidOffset(offset))
+    {
+        Prologue prologue;
+
+        if (ParsePrologue(debug_line_data, &offset, &prologue))
+        {
+            log->PutCString ("----------------------------------------------------------------------");
+            log->Printf     ("debug_line[0x%8.8x]", debug_line_offset);
+            log->PutCString ("----------------------------------------------------------------------\n");
+            prologue.Dump (log);
+        }
+        else
+        {
+            offset = debug_line_offset;
+            log->Printf( "0x%8.8x: skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
+            return offset;
+        }
+
+        Row row(prologue.default_is_stmt);
+        const dw_offset_t end_offset = debug_line_offset + prologue.total_length + sizeof(prologue.total_length);
+
+        assert(debug_line_data.ValidOffset(end_offset-1));
+
+        while (offset < end_offset)
+        {
+            const uint32_t op_offset = offset;
+            uint8_t opcode = debug_line_data.GetU8(&offset);
+            switch (opcode)
+            {
+            case 0: // Extended Opcodes always start with a zero opcode followed by
+                {   // a uleb128 length so you can skip ones you don't know about
+
+                    dw_offset_t ext_offset = offset;
+                    dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
+                    dw_offset_t arg_size = len - (offset - ext_offset);
+                    uint8_t sub_opcode = debug_line_data.GetU8(&offset);
+//                    if (verbose)
+//                        log->Printf( "Extended: <%u> %2.2x ", len, sub_opcode);
+
+                    switch (sub_opcode)
+                    {
+                    case DW_LNE_end_sequence    :
+                        log->Printf( "0x%8.8x: DW_LNE_end_sequence", op_offset);
+                        row.Dump(log);
+                        row.Reset(prologue.default_is_stmt);
+                        break;
+
+                    case DW_LNE_set_address     :
+                        {
+                            row.address = debug_line_data.GetMaxU64(&offset, arg_size);
+                            log->Printf( "0x%8.8x: DW_LNE_set_address (0x%llx)", op_offset, row.address);
+                        }
+                        break;
+
+                    case DW_LNE_define_file:
+                        {
+                            FileNameEntry fileEntry;
+                            fileEntry.name      = debug_line_data.GetCStr(&offset);
+                            fileEntry.dir_idx   = debug_line_data.GetULEB128(&offset);
+                            fileEntry.mod_time  = debug_line_data.GetULEB128(&offset);
+                            fileEntry.length    = debug_line_data.GetULEB128(&offset);
+                            log->Printf( "0x%8.8x: DW_LNE_define_file('%s', dir=%i, mod_time=0x%8.8x, length=%i )",
+                                    op_offset,
+                                    fileEntry.name.c_str(),
+                                    fileEntry.dir_idx,
+                                    fileEntry.mod_time,
+                                    fileEntry.length);
+                            prologue.file_names.push_back(fileEntry);
+                        }
+                        break;
+
+                    default:
+                        log->Printf( "0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", op_offset, opcode);
+                        // Length doesn't include the zero opcode byte or the length itself, but
+                        // it does include the sub_opcode, so we have to adjust for that below
+                        offset += arg_size;
+                        break;
+                    }
+                }
+                break;
+
+            // Standard Opcodes
+            case DW_LNS_copy:
+                log->Printf( "0x%8.8x: DW_LNS_copy", op_offset);
+                row.Dump (log);
+                break;
+
+            case DW_LNS_advance_pc:
+                {
+                    dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
+                    dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
+                    log->Printf( "0x%8.8x: DW_LNS_advance_pc (0x%llx)", op_offset, addr_offset);
+                    row.address += addr_offset;
+                }
+                break;
+
+            case DW_LNS_advance_line:
+                {
+                    dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
+                    log->Printf( "0x%8.8x: DW_LNS_advance_line (%i)", op_offset, line_offset);
+                    row.line += line_offset;
+                }
+                break;
+
+            case DW_LNS_set_file:
+                row.file = debug_line_data.GetULEB128(&offset);
+                log->Printf( "0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
+                break;
+
+            case DW_LNS_set_column:
+                row.column = debug_line_data.GetULEB128(&offset);
+                log->Printf( "0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
+                break;
+
+            case DW_LNS_negate_stmt:
+                row.is_stmt = !row.is_stmt;
+                log->Printf( "0x%8.8x: DW_LNS_negate_stmt", op_offset);
+                break;
+
+            case DW_LNS_set_basic_block:
+                row.basic_block = true;
+                log->Printf( "0x%8.8x: DW_LNS_set_basic_block", op_offset);
+                break;
+
+            case DW_LNS_const_add_pc:
+                {
+                    uint8_t adjust_opcode = 255 - prologue.opcode_base;
+                    dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
+                    log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8llx)", op_offset, addr_offset);
+                    row.address += addr_offset;
+                }
+                break;
+
+            case DW_LNS_fixed_advance_pc:
+                {
+                    uint16_t pc_offset = debug_line_data.GetU16(&offset);
+                    log->Printf( "0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, pc_offset);
+                    row.address += pc_offset;
+                }
+                break;
+
+            case DW_LNS_set_prologue_end:
+                row.prologue_end = true;
+                log->Printf( "0x%8.8x: DW_LNS_set_prologue_end", op_offset);
+                break;
+
+            case DW_LNS_set_epilogue_begin:
+                row.epilogue_begin = true;
+                log->Printf( "0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
+                break;
+
+            case DW_LNS_set_isa:
+                row.isa = debug_line_data.GetULEB128(&offset);
+                log->Printf( "0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
+                break;
+
+            // Special Opcodes
+            default:
+                if (opcode < prologue.opcode_base)
+                {
+                    // We have an opcode that this parser doesn't know about, skip
+                    // the number of ULEB128 numbers that is says to skip in the
+                    // prologue's standard_opcode_lengths array
+                    uint8_t n = prologue.standard_opcode_lengths[opcode-1];
+                    log->Printf( "0x%8.8x: Special : Unknown skipping %u ULEB128 values.", op_offset, n);
+                    while (n > 0)
+                    {
+                        debug_line_data.GetULEB128(&offset);
+                        --n;
+                    }
+                }
+                else
+                {
+                    uint8_t adjust_opcode = opcode - prologue.opcode_base;
+                    dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
+                    int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range);
+                    log->Printf("0x%8.8x: address += 0x%llx,  line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
+                    row.address += addr_offset;
+                    row.line += line_offset;
+                    row.Dump (log);
+                }
+                break;
+            }
+        }
+        return end_offset;
+    }
+    return DW_INVALID_OFFSET;
+}
+
+
+
+
+//----------------------------------------------------------------------
+// Parse
+//
+// Parse the entire line table contents calling callback each time a
+// new prologue is parsed and every time a new row is to be added to
+// the line table.
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::Parse(const DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData)
+{
+    uint32_t offset = 0;
+    if (debug_line_data.ValidOffset(offset))
+    {
+        if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
+            ++offset;   // Skip to next byte in .debug_line section
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::ParsePrologue
+//----------------------------------------------------------------------
+bool
+DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue)
+{
+//  const uint32_t prologue_offset = *offset_ptr;
+
+    //DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
+
+    prologue->Clear();
+    uint32_t i;
+    const char * s;
+    prologue->total_length      = debug_line_data.GetU32(offset_ptr);
+    prologue->version           = debug_line_data.GetU16(offset_ptr);
+    if (prologue->version != 2)
+      return false;
+
+    prologue->prologue_length   = debug_line_data.GetU32(offset_ptr);
+    const dw_offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
+    prologue->min_inst_length   = debug_line_data.GetU8(offset_ptr);
+    prologue->default_is_stmt   = debug_line_data.GetU8(offset_ptr);
+    prologue->line_base         = debug_line_data.GetU8(offset_ptr);
+    prologue->line_range        = debug_line_data.GetU8(offset_ptr);
+    prologue->opcode_base       = debug_line_data.GetU8(offset_ptr);
+
+    prologue->standard_opcode_lengths.reserve(prologue->opcode_base-1);
+
+    for (i=1; i<prologue->opcode_base; ++i)
+    {
+        uint8_t op_len = debug_line_data.GetU8(offset_ptr);
+        prologue->standard_opcode_lengths.push_back(op_len);
+    }
+
+    while (*offset_ptr < end_prologue_offset)
+    {
+        s = debug_line_data.GetCStr(offset_ptr);
+        if (s && s[0])
+            prologue->include_directories.push_back(s);
+        else
+            break;
+    }
+
+    while (*offset_ptr < end_prologue_offset)
+    {
+        const char* name = debug_line_data.GetCStr( offset_ptr );
+        if (name && name[0])
+        {
+            FileNameEntry fileEntry;
+            fileEntry.name      = name;
+            fileEntry.dir_idx   = debug_line_data.GetULEB128( offset_ptr );
+            fileEntry.mod_time  = debug_line_data.GetULEB128( offset_ptr );
+            fileEntry.length    = debug_line_data.GetULEB128( offset_ptr );
+            prologue->file_names.push_back(fileEntry);
+        }
+        else
+            break;
+    }
+
+    assert(*offset_ptr == end_prologue_offset);
+    return end_prologue_offset;
+}
+
+bool
+DWARFDebugLine::ParseSupportFiles(const DataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, FileSpecList &support_files)
+{
+    uint32_t offset = stmt_list + 4;    // Skip the total length
+    const char * s;
+    uint32_t version = debug_line_data.GetU16(&offset);
+    if (version != 2)
+      return false;
+
+    const dw_offset_t end_prologue_offset = debug_line_data.GetU32(&offset) + offset;
+    // Skip instruction length, default is stmt, line base, line range and
+    // opcode base, and all opcode lengths
+    offset += 4;
+    const uint8_t opcode_base = debug_line_data.GetU8(&offset);
+    offset += opcode_base - 1;
+    std::vector<std::string> include_directories;
+    include_directories.push_back("");  // Directory at index zero doesn't exist
+    while (offset < end_prologue_offset)
+    {
+        s = debug_line_data.GetCStr(&offset);
+        if (s && s[0])
+            include_directories.push_back(s);
+        else
+            break;
+    }
+    std::string fullpath;
+    while (offset < end_prologue_offset)
+    {
+        const char* path = debug_line_data.GetCStr( &offset );
+        if (path && path[0])
+        {
+            uint32_t dir_idx    = debug_line_data.GetULEB128( &offset );
+            debug_line_data.Skip_LEB128(&offset); // Skip mod_time
+            debug_line_data.Skip_LEB128(&offset); // Skip length
+
+            if (path[0] == '/')
+            {
+                // The path starts with a directory delimiter, so we are done.
+                fullpath = path;
+            }
+            else
+            {
+                if (dir_idx > 0 && dir_idx < include_directories.size())
+                {
+                    if (cu_comp_dir && include_directories[dir_idx][0] != '/')
+                    {
+                        fullpath = cu_comp_dir;
+
+                        if (*fullpath.rbegin() != '/')
+                            fullpath += '/';
+                        fullpath += include_directories[dir_idx];
+
+                    }
+                    else
+                        fullpath = include_directories[dir_idx];
+                }
+                else if (cu_comp_dir && cu_comp_dir[0])
+                {
+                    fullpath = cu_comp_dir;
+                }
+
+                if (!fullpath.empty())
+                {
+                   if (*fullpath.rbegin() != '/')
+                        fullpath += '/';
+                }
+                fullpath += path;
+            }
+            FileSpec file_spec(fullpath.c_str());
+            support_files.Append(file_spec);
+        }
+    }
+
+    assert(offset == end_prologue_offset);
+    return end_prologue_offset;
+}
+
+//----------------------------------------------------------------------
+// ParseStatementTable
+//
+// Parse a single line table (prologue and all rows) and call the
+// callback function once for the prologue (row in state will be zero)
+// and each time a row is to be added to the line table.
+//----------------------------------------------------------------------
+bool
+DWARFDebugLine::ParseStatementTable
+(
+    const DataExtractor& debug_line_data,
+    dw_offset_t* offset_ptr,
+    DWARFDebugLine::State::Callback callback,
+    void* userData
+)
+{
+    Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE);
+    Prologue::shared_ptr prologue(new Prologue());
+
+
+    const dw_offset_t debug_line_offset = *offset_ptr;
+
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
+                        debug_line_offset);
+
+    if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get()))
+    {
+        if (log)
+            log->Error ("failed to parse DWARF line table prologue");
+        // Restore our offset and return false to indicate failure!
+        *offset_ptr = debug_line_offset;
+        return false;
+    }
+
+    if (log)
+        prologue->Dump (log);
+
+    const dw_offset_t end_offset = debug_line_offset + prologue->total_length + sizeof(prologue->total_length);
+
+    assert(debug_line_data.ValidOffset(end_offset-1));
+
+    State state(prologue, log, callback, userData);
+
+    while (*offset_ptr < end_offset)
+    {
+        //DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
+        uint8_t opcode = debug_line_data.GetU8(offset_ptr);
+
+        if (opcode == 0)
+        {
+            // Extended Opcodes always start with a zero opcode followed by
+            // a uleb128 length so you can skip ones you don't know about
+            dw_offset_t ext_offset = *offset_ptr;
+            dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
+            dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
+
+            //DEBUG_PRINTF("Extended: <%2u> ", len);
+            uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
+            switch (sub_opcode)
+            {
+            case DW_LNE_end_sequence:
+                // Set the end_sequence register of the state machine to true and
+                // append a row to the matrix using the current values of the
+                // state-machine registers. Then reset the registers to the initial
+                // values specified above. Every statement program sequence must end
+                // with a DW_LNE_end_sequence instruction which creates a row whose
+                // address is that of the byte after the last target machine instruction
+                // of the sequence.
+                state.end_sequence = true;
+                state.AppendRowToMatrix(*offset_ptr);
+                state.Reset();
+                break;
+
+            case DW_LNE_set_address:
+                // Takes a single relocatable address as an operand. The size of the
+                // operand is the size appropriate to hold an address on the target
+                // machine. Set the address register to the value given by the
+                // relocatable address. All of the other statement program opcodes
+                // that affect the address register add a delta to it. This instruction
+                // stores a relocatable value into it instead.
+                state.address = debug_line_data.GetAddress(offset_ptr);
+                break;
+
+            case DW_LNE_define_file:
+                // Takes 4 arguments. The first is a null terminated string containing
+                // a source file name. The second is an unsigned LEB128 number representing
+                // the directory index of the directory in which the file was found. The
+                // third is an unsigned LEB128 number representing the time of last
+                // modification of the file. The fourth is an unsigned LEB128 number
+                // representing the length in bytes of the file. The time and length
+                // fields may contain LEB128(0) if the information is not available.
+                //
+                // The directory index represents an entry in the include_directories
+                // section of the statement program prologue. The index is LEB128(0)
+                // if the file was found in the current directory of the compilation,
+                // LEB128(1) if it was found in the first directory in the
+                // include_directories section, and so on. The directory index is
+                // ignored for file names that represent full path names.
+                //
+                // The files are numbered, starting at 1, in the order in which they
+                // appear; the names in the prologue come before names defined by
+                // the DW_LNE_define_file instruction. These numbers are used in the
+                // the file register of the state machine.
+                {
+                    FileNameEntry fileEntry;
+                    fileEntry.name      = debug_line_data.GetCStr(offset_ptr);
+                    fileEntry.dir_idx   = debug_line_data.GetULEB128(offset_ptr);
+                    fileEntry.mod_time  = debug_line_data.GetULEB128(offset_ptr);
+                    fileEntry.length    = debug_line_data.GetULEB128(offset_ptr);
+                    state.prologue->file_names.push_back(fileEntry);
+                }
+                break;
+
+            default:
+                // Length doesn't include the zero opcode byte or the length itself, but
+                // it does include the sub_opcode, so we have to adjust for that below
+                (*offset_ptr) += arg_size;
+                break;
+            }
+        }
+        else if (opcode < prologue->opcode_base)
+        {
+            switch (opcode)
+            {
+            // Standard Opcodes
+            case DW_LNS_copy:
+                // Takes no arguments. Append a row to the matrix using the
+                // current values of the state-machine registers. Then set
+                // the basic_block register to false.
+                state.AppendRowToMatrix(*offset_ptr);
+                break;
+
+            case DW_LNS_advance_pc:
+                // Takes a single unsigned LEB128 operand, multiplies it by the
+                // min_inst_length field of the prologue, and adds the
+                // result to the address register of the state machine.
+                state.address += debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
+                break;
+
+            case DW_LNS_advance_line:
+                // Takes a single signed LEB128 operand and adds that value to
+                // the line register of the state machine.
+                state.line += debug_line_data.GetSLEB128(offset_ptr);
+                break;
+
+            case DW_LNS_set_file:
+                // Takes a single unsigned LEB128 operand and stores it in the file
+                // register of the state machine.
+                state.file = debug_line_data.GetULEB128(offset_ptr);
+                break;
+
+            case DW_LNS_set_column:
+                // Takes a single unsigned LEB128 operand and stores it in the
+                // column register of the state machine.
+                state.column = debug_line_data.GetULEB128(offset_ptr);
+                break;
+
+            case DW_LNS_negate_stmt:
+                // Takes no arguments. Set the is_stmt register of the state
+                // machine to the logical negation of its current value.
+                state.is_stmt = !state.is_stmt;
+                break;
+
+            case DW_LNS_set_basic_block:
+                // Takes no arguments. Set the basic_block register of the
+                // state machine to true
+                state.basic_block = true;
+                break;
+
+            case DW_LNS_const_add_pc:
+                // Takes no arguments. Add to the address register of the state
+                // machine the address increment value corresponding to special
+                // opcode 255. The motivation for DW_LNS_const_add_pc is this:
+                // when the statement program needs to advance the address by a
+                // small amount, it can use a single special opcode, which occupies
+                // a single byte. When it needs to advance the address by up to
+                // twice the range of the last special opcode, it can use
+                // DW_LNS_const_add_pc followed by a special opcode, for a total
+                // of two bytes. Only if it needs to advance the address by more
+                // than twice that range will it need to use both DW_LNS_advance_pc
+                // and a special opcode, requiring three or more bytes.
+                {
+                    uint8_t adjust_opcode = 255 - prologue->opcode_base;
+                    dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
+                    state.address += addr_offset;
+                }
+                break;
+
+            case DW_LNS_fixed_advance_pc:
+                // Takes a single uhalf operand. Add to the address register of
+                // the state machine the value of the (unencoded) operand. This
+                // is the only extended opcode that takes an argument that is not
+                // a variable length number. The motivation for DW_LNS_fixed_advance_pc
+                // is this: existing assemblers cannot emit DW_LNS_advance_pc or
+                // special opcodes because they cannot encode LEB128 numbers or
+                // judge when the computation of a special opcode overflows and
+                // requires the use of DW_LNS_advance_pc. Such assemblers, however,
+                // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
+                state.address += debug_line_data.GetU16(offset_ptr);
+                break;
+
+            case DW_LNS_set_prologue_end:
+                // Takes no arguments. Set the prologue_end register of the
+                // state machine to true
+                state.prologue_end = true;
+                break;
+
+            case DW_LNS_set_epilogue_begin:
+                // Takes no arguments. Set the basic_block register of the
+                // state machine to true
+                state.epilogue_begin = true;
+                break;
+
+            case DW_LNS_set_isa:
+                // Takes a single unsigned LEB128 operand and stores it in the
+                // column register of the state machine.
+                state.isa = debug_line_data.GetULEB128(offset_ptr);
+                break;
+
+            default:
+                // Handle any unknown standard opcodes here. We know the lengths
+                // of such opcodes because they are specified in the prologue
+                // as a multiple of LEB128 operands for each opcode.
+                {
+                    uint8_t i;
+                    assert (opcode - 1 < prologue->standard_opcode_lengths.size());
+                    const uint8_t opcode_length = prologue->standard_opcode_lengths[opcode - 1];
+                    for (i=0; i<opcode_length; ++i)
+                        debug_line_data.Skip_LEB128(offset_ptr);
+                }
+                break;
+            }
+        }
+        else
+        {
+            // Special Opcodes
+
+            // A special opcode value is chosen based on the amount that needs
+            // to be added to the line and address registers. The maximum line
+            // increment for a special opcode is the value of the line_base
+            // field in the header, plus the value of the line_range field,
+            // minus 1 (line base + line range - 1). If the desired line
+            // increment is greater than the maximum line increment, a standard
+            // opcode must be used instead of a special opcode. The “address
+            // advance” is calculated by dividing the desired address increment
+            // by the minimum_instruction_length field from the header. The
+            // special opcode is then calculated using the following formula:
+            //
+            //  opcode = (desired line increment - line_base) + (line_range * address advance) + opcode_base
+            //
+            // If the resulting opcode is greater than 255, a standard opcode
+            // must be used instead.
+            //
+            // To decode a special opcode, subtract the opcode_base from the
+            // opcode itself to give the adjusted opcode. The amount to
+            // increment the address register is the result of the adjusted
+            // opcode divided by the line_range multiplied by the
+            // minimum_instruction_length field from the header. That is:
+            //
+            //  address increment = (adjusted opcode / line_range) * minimim_instruction_length
+            //
+            // The amount to increment the line register is the line_base plus
+            // the result of the adjusted opcode modulo the line_range. That is:
+            //
+            // line increment = line_base + (adjusted opcode % line_range)
+
+            uint8_t adjust_opcode = opcode - prologue->opcode_base;
+            dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
+            int32_t line_offset = prologue->line_base + (adjust_opcode % prologue->line_range);
+            state.line += line_offset;
+            state.address += addr_offset;
+            state.AppendRowToMatrix(*offset_ptr);
+        }
+    }
+
+    state.Finalize( *offset_ptr );
+
+    return end_offset;
+}
+
+
+//----------------------------------------------------------------------
+// ParseStatementTableCallback
+//----------------------------------------------------------------------
+static void
+ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
+{
+    DWARFDebugLine::LineTable* line_table = (DWARFDebugLine::LineTable*)userData;
+    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
+    {
+        // Just started parsing the line table, so lets keep a reference to
+        // the prologue using the supplied shared pointer
+        line_table->prologue = state.prologue;
+    }
+    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
+    {
+        // Done parsing line table, nothing to do for the cleanup
+    }
+    else
+    {
+        // We have a new row, lets append it
+        line_table->AppendRow(state);
+    }
+}
+
+//----------------------------------------------------------------------
+// ParseStatementTable
+//
+// Parse a line table at offset and populate the LineTable class with
+// the prologue and all rows.
+//----------------------------------------------------------------------
+bool
+DWARFDebugLine::ParseStatementTable(const DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table)
+{
+    return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table);
+}
+
+
+inline bool
+DWARFDebugLine::Prologue::IsValid() const
+{
+    return SymbolFileDWARF::SupportedVersion(version);
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::Prologue::Dump
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::Prologue::Dump(Log *log)
+{
+    uint32_t i;
+
+    log->Printf( "Line table prologue:");
+    log->Printf( "   total_length: 0x%8.8x", total_length);
+    log->Printf( "        version: %u", version);
+    log->Printf( "prologue_length: 0x%8.8x", prologue_length);
+    log->Printf( "min_inst_length: %u", min_inst_length);
+    log->Printf( "default_is_stmt: %u", default_is_stmt);
+    log->Printf( "      line_base: %i", line_base);
+    log->Printf( "     line_range: %u", line_range);
+    log->Printf( "    opcode_base: %u", opcode_base);
+
+    for (i=0; i<standard_opcode_lengths.size(); ++i)
+    {
+        log->Printf( "standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i+1), standard_opcode_lengths[i]);
+    }
+
+    if (!include_directories.empty())
+    {
+        for (i=0; i<include_directories.size(); ++i)
+        {
+            log->Printf( "include_directories[%3u] = '%s'", i+1, include_directories[i].c_str());
+        }
+    }
+
+    if (!file_names.empty())
+    {
+        log->PutCString ("                Dir  Mod Time   File Len   File Name");
+        log->PutCString ("                ---- ---------- ---------- ---------------------------");
+        for (i=0; i<file_names.size(); ++i)
+        {
+            const FileNameEntry& fileEntry = file_names[i];
+            log->Printf ("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s",
+                i+1,
+                fileEntry.dir_idx,
+                fileEntry.mod_time,
+                fileEntry.length,
+                fileEntry.name.c_str());
+        }
+    }
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::ParsePrologue::Append
+//
+// Append the contents of the prologue to the binary stream buffer
+//----------------------------------------------------------------------
+//void
+//DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
+//{
+//  uint32_t i;
+//
+//  buff.Append32(total_length);
+//  buff.Append16(version);
+//  buff.Append32(prologue_length);
+//  buff.Append8(min_inst_length);
+//  buff.Append8(default_is_stmt);
+//  buff.Append8(line_base);
+//  buff.Append8(line_range);
+//  buff.Append8(opcode_base);
+//
+//  for (i=0; i<standard_opcode_lengths.size(); ++i)
+//      buff.Append8(standard_opcode_lengths[i]);
+//
+//  for (i=0; i<include_directories.size(); ++i)
+//      buff.AppendCStr(include_directories[i].c_str());
+//  buff.Append8(0);    // Terminate the include directory section with empty string
+//
+//  for (i=0; i<file_names.size(); ++i)
+//  {
+//      buff.AppendCStr(file_names[i].name.c_str());
+//      buff.Append32_as_ULEB128(file_names[i].dir_idx);
+//      buff.Append32_as_ULEB128(file_names[i].mod_time);
+//      buff.Append32_as_ULEB128(file_names[i].length);
+//  }
+//  buff.Append8(0);    // Terminate the file names section with empty string
+//}
+
+
+bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, std::string& path, std::string& directory) const
+{
+    uint32_t idx = file_idx - 1;    // File indexes are 1 based...
+    if (idx < file_names.size())
+    {
+        path = file_names[idx].name;
+        uint32_t dir_idx = file_names[idx].dir_idx - 1;
+        if (dir_idx < include_directories.size())
+            directory = include_directories[dir_idx];
+        else
+            directory.clear();
+        return true;
+    }
+    return false;
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::LineTable::Dump
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::LineTable::Dump(Log *log) const
+{
+    if (prologue.get())
+        prologue->Dump (log);
+
+    if (!rows.empty())
+    {
+        log->PutCString ("Address            Line   Column File   ISA Flags");
+        log->PutCString ("------------------ ------ ------ ------ --- -------------");
+        Row::const_iterator pos = rows.begin();
+        Row::const_iterator end = rows.end();
+        while (pos != end)
+        {
+            (*pos).Dump (log);
+            ++pos;
+        }
+    }
+}
+
+
+void
+DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row& state)
+{
+    rows.push_back(state);
+}
+
+
+
+//----------------------------------------------------------------------
+// Compare function for the binary search in DWARFDebugLine::LineTable::LookupAddress()
+//----------------------------------------------------------------------
+static bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDebugLine::Row& row2)
+{
+    return row1.address < row2.address;
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::LineTable::LookupAddress
+//----------------------------------------------------------------------
+uint32_t
+DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const
+{
+    uint32_t index = UINT_MAX;
+    if (!rows.empty())
+    {
+        // Use the lower_bound algorithm to perform a binary search since we know
+        // that our line table data is ordered by address.
+        DWARFDebugLine::Row row;
+        row.address = address;
+        Row::const_iterator begin_pos = rows.begin();
+        Row::const_iterator end_pos = rows.end();
+        Row::const_iterator pos = lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
+        if (pos == end_pos)
+        {
+            if (address < cu_high_pc)
+                return rows.size()-1;
+        }
+        else
+        {
+            // Rely on fact that we are using a std::vector and we can do
+            // pointer arithmetic to find the row index (which will be one less
+            // that what we found since it will find the first position after
+            // the current address) since std::vector iterators are just
+            // pointers to the container type.
+            index = pos - begin_pos;
+            if (pos->address > address)
+            {
+                if (index > 0)
+                    --index;
+                else
+                    index = UINT_MAX;
+            }
+        }
+    }
+    return index;   // Failed to find address
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::Row::Row
+//----------------------------------------------------------------------
+DWARFDebugLine::Row::Row(bool default_is_stmt) :
+    address(0),
+    line(1),
+    column(0),
+    file(1),
+    is_stmt(default_is_stmt),
+    basic_block(false),
+    end_sequence(false),
+    prologue_end(false),
+    epilogue_begin(false),
+    isa(0)
+{
+}
+
+//----------------------------------------------------------------------
+// Called after a row is appended to the matrix
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::Row::PostAppend()
+{
+    basic_block = false;
+    prologue_end = false;
+    epilogue_begin = false;
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::Row::Reset
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::Row::Reset(bool default_is_stmt)
+{
+    address = 0;
+    line = 1;
+    column = 0;
+    file = 1;
+    is_stmt = default_is_stmt;
+    basic_block = false;
+    end_sequence = false;
+    prologue_end = false;
+    epilogue_begin = false;
+    isa = 0;
+}
+//----------------------------------------------------------------------
+// DWARFDebugLine::Row::Dump
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::Row::Dump(Log *log) const
+{
+    log->Printf( "0x%16.16llx %6u %6u %6u %3u %s%s%s%s%s",
+                address,
+                line,
+                column,
+                file,
+                isa,
+                is_stmt ? " is_stmt" : "",
+                basic_block ? " basic_block" : "",
+                prologue_end ? " prologue_end" : "",
+                epilogue_begin ? " epilogue_begin" : "",
+                end_sequence ? " end_sequence" : "");
+}
+
+//----------------------------------------------------------------------
+// Compare function LineTable structures
+//----------------------------------------------------------------------
+static bool AddressLessThan (const DWARFDebugLine::Row& a, const DWARFDebugLine::Row& b)
+{
+    return a.address < b.address;
+}
+
+
+
+// Insert a row at the correct address if the addresses can be out of
+// order which can only happen when we are linking a line table that
+// may have had it's contents rearranged.
+void
+DWARFDebugLine::Row::Insert(Row::collection& state_coll, const Row& state)
+{
+    // If we don't have anything yet, or if the address of the last state in our
+    // line table is less than the current one, just append the current state
+    if (state_coll.empty() || AddressLessThan(state_coll.back(), state))
+    {
+        state_coll.push_back(state);
+    }
+    else
+    {
+        // Do a binary search for the correct entry
+        pair<Row::iterator, Row::iterator> range(equal_range(state_coll.begin(), state_coll.end(), state, AddressLessThan));
+
+        // If the addresses are equal, we can safely replace the previous entry
+        // with the current one if the one it is replacing is an end_sequence entry.
+        // We currently always place an extra end sequence when ever we exit a valid
+        // address range for a function in case the functions get rearranged by
+        // optmimizations or by order specifications. These extra end sequences will
+        // disappear by getting replaced with valid consecutive entries within a
+        // compile unit if there are no gaps.
+        if (range.first == range.second)
+        {
+            state_coll.insert(range.first, state);
+        }
+        else
+        {
+            if ((distance(range.first, range.second) == 1) && range.first->end_sequence == true)
+            {
+                *range.first = state;
+            }
+            else
+            {
+                state_coll.insert(range.second, state);
+            }
+        }
+    }
+}
+
+void
+DWARFDebugLine::Row::Dump(Log *log, const Row::collection& state_coll)
+{
+    std::for_each (state_coll.begin(), state_coll.end(), bind2nd(std::mem_fun_ref(&Row::Dump),log));
+}
+
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::State::State
+//----------------------------------------------------------------------
+DWARFDebugLine::State::State(Prologue::shared_ptr& p, Log *l, DWARFDebugLine::State::Callback cb, void* userData) :
+    Row (p->default_is_stmt),
+    prologue (p),
+    log (l),
+    callback (cb),
+    callbackUserData (userData),
+    row (StartParsingLineTable)
+{
+    // Call the callback with the initial row state of zero for the prologue
+    if (callback)
+        callback(0, *this, callbackUserData);
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::State::Reset
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::State::Reset()
+{
+    Row::Reset(prologue->default_is_stmt);
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::State::AppendRowToMatrix
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset)
+{
+    // Each time we are to add an entry into the line table matrix
+    // call the callback funtion so that someone can do something with
+    // the current state of the state machine (like build a line table
+    // or dump the line table!)
+    if (log)
+    {
+        if (row == 0)
+        {
+            log->PutCString ("Address            Line   Column File   ISA Flags");
+            log->PutCString ("------------------ ------ ------ ------ --- -------------");
+        }
+        Dump (log);
+    }
+
+    ++row;  // Increase the row number before we call our callback for a real row
+    if (callback)
+        callback(offset, *this, callbackUserData);
+    PostAppend();
+}
+
+//----------------------------------------------------------------------
+// DWARFDebugLine::State::Finalize
+//----------------------------------------------------------------------
+void
+DWARFDebugLine::State::Finalize(dw_offset_t offset)
+{
+    // Call the callback with a special row state when we are done parsing a
+    // line table
+    row = DoneParsingLineTable;
+    if (callback)
+        callback(offset, *this, callbackUserData);
+}
+
+//void
+//DWARFDebugLine::AppendLineTableData
+//(
+//  const DWARFDebugLine::Prologue* prologue,
+//  const DWARFDebugLine::Row::collection& state_coll,
+//  const uint32_t addr_size,
+//  BinaryStreamBuf &debug_line_data
+//)
+//{
+//  if (state_coll.empty())
+//  {
+//      // We have no entries, just make an empty line table
+//      debug_line_data.Append8(0);
+//      debug_line_data.Append8(1);
+//      debug_line_data.Append8(DW_LNE_end_sequence);
+//  }
+//  else
+//  {
+//      DWARFDebugLine::Row::const_iterator pos;
+//      Row::const_iterator end = state_coll.end();
+//      bool default_is_stmt = prologue->default_is_stmt;
+//      const DWARFDebugLine::Row reset_state(default_is_stmt);
+//      const DWARFDebugLine::Row* prev_state = &reset_state;
+//      const int32_t max_line_increment_for_special_opcode = prologue->MaxLineIncrementForSpecialOpcode();
+//      for (pos = state_coll.begin(); pos != end; ++pos)
+//      {
+//          const DWARFDebugLine::Row& curr_state = *pos;
+//          int32_t line_increment  = 0;
+//          dw_addr_t addr_offset   = curr_state.address - prev_state->address;
+//          dw_addr_t addr_advance  = (addr_offset) / prologue->min_inst_length;
+//          line_increment = (int32_t)(curr_state.line - prev_state->line);
+//
+//          // If our previous state was the reset state, then let's emit the
+//          // address to keep GDB's DWARF parser happy. If we don't start each
+//          // sequence with a DW_LNE_set_address opcode, the line table won't
+//          // get slid properly in GDB.
+//
+//          if (prev_state == &reset_state)
+//          {
+//              debug_line_data.Append8(0); // Extended opcode
+//              debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of opcode bytes
+//              debug_line_data.Append8(DW_LNE_set_address);
+//              debug_line_data.AppendMax64(curr_state.address, addr_size);
+//              addr_advance = 0;
+//          }
+//
+//          if (prev_state->file != curr_state.file)
+//          {
+//              debug_line_data.Append8(DW_LNS_set_file);
+//              debug_line_data.Append32_as_ULEB128(curr_state.file);
+//          }
+//
+//          if (prev_state->column != curr_state.column)
+//          {
+//              debug_line_data.Append8(DW_LNS_set_column);
+//              debug_line_data.Append32_as_ULEB128(curr_state.column);
+//          }
+//
+//          // Don't do anything fancy if we are at the end of a sequence
+//          // as we don't want to push any extra rows since the DW_LNE_end_sequence
+//          // will push a row itself!
+//          if (curr_state.end_sequence)
+//          {
+//              if (line_increment != 0)
+//              {
+//                  debug_line_data.Append8(DW_LNS_advance_line);
+//                  debug_line_data.Append32_as_SLEB128(line_increment);
+//              }
+//
+//              if (addr_advance > 0)
+//              {
+//                  debug_line_data.Append8(DW_LNS_advance_pc);
+//                  debug_line_data.Append32_as_ULEB128(addr_advance);
+//              }
+//
+//              // Now push the end sequence on!
+//              debug_line_data.Append8(0);
+//              debug_line_data.Append8(1);
+//              debug_line_data.Append8(DW_LNE_end_sequence);
+//
+//              prev_state = &reset_state;
+//          }
+//          else
+//          {
+//              if (line_increment || addr_advance)
+//              {
+//                  if (line_increment > max_line_increment_for_special_opcode)
+//                  {
+//                      debug_line_data.Append8(DW_LNS_advance_line);
+//                      debug_line_data.Append32_as_SLEB128(line_increment);
+//                      line_increment = 0;
+//                  }
+//
+//                  uint32_t special_opcode = (line_increment >= prologue->line_base) ? ((line_increment - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
+//                  if (special_opcode > 255)
+//                  {
+//                      // Both the address and line won't fit in one special opcode
+//                      // check to see if just the line advance will?
+//                      uint32_t special_opcode_line = ((line_increment >= prologue->line_base) && (line_increment != 0)) ?
+//                              ((line_increment - prologue->line_base) + prologue->opcode_base) : 256;
+//
+//
+//                      if (special_opcode_line > 255)
+//                      {
+//                          // Nope, the line advance won't fit by itself, check the address increment by itself
+//                          uint32_t special_opcode_addr = addr_advance ?
+//                              ((0 - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
+//
+//                          if (special_opcode_addr > 255)
+//                          {
+//                              // Neither the address nor the line will fit in a
+//                              // special opcode, we must manually enter both then
+//                              // do a DW_LNS_copy to push a row (special opcode
+//                              // automatically imply a new row is pushed)
+//                              if (line_increment != 0)
+//                              {
+//                                  debug_line_data.Append8(DW_LNS_advance_line);
+//                                  debug_line_data.Append32_as_SLEB128(line_increment);
+//                              }
+//
+//                              if (addr_advance > 0)
+//                              {
+//                                  debug_line_data.Append8(DW_LNS_advance_pc);
+//                                  debug_line_data.Append32_as_ULEB128(addr_advance);
+//                              }
+//
+//                              // Now push a row onto the line table manually
+//                              debug_line_data.Append8(DW_LNS_copy);
+//
+//                          }
+//                          else
+//                          {
+//                              // The address increment alone will fit into a special opcode
+//                              // so modify our line change, then issue a special opcode
+//                              // for the address increment and it will push a row into the
+//                              // line table
+//                              if (line_increment != 0)
+//                              {
+//                                  debug_line_data.Append8(DW_LNS_advance_line);
+//                                  debug_line_data.Append32_as_SLEB128(line_increment);
+//                              }
+//
+//                              // Advance of line and address will fit into a single byte special opcode
+//                              // and this will also push a row onto the line table
+//                              debug_line_data.Append8(special_opcode_addr);
+//                          }
+//                      }
+//                      else
+//                      {
+//                          // The line change alone will fit into a special opcode
+//                          // so modify our address increment first, then issue a
+//                          // special opcode for the line change and it will push
+//                          // a row into the line table
+//                          if (addr_advance > 0)
+//                          {
+//                              debug_line_data.Append8(DW_LNS_advance_pc);
+//                              debug_line_data.Append32_as_ULEB128(addr_advance);
+//                          }
+//
+//                          // Advance of line and address will fit into a single byte special opcode
+//                          // and this will also push a row onto the line table
+//                          debug_line_data.Append8(special_opcode_line);
+//                      }
+//                  }
+//                  else
+//                  {
+//                      // Advance of line and address will fit into a single byte special opcode
+//                      // and this will also push a row onto the line table
+//                      debug_line_data.Append8(special_opcode);
+//                  }
+//              }
+//              prev_state = &curr_state;
+//          }
+//      }
+//  }
+//}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
new file mode 100644
index 0000000..57b2f15
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -0,0 +1,225 @@
+//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugLine_h_
+#define liblldb_DWARFDebugLine_h_
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include "lldb/lldb-private.h"
+
+#include "DWARFDefines.h"
+
+class SymbolFileDWARF;
+class DWARFDebugInfoEntry;
+
+//----------------------------------------------------------------------
+// DWARFDebugLine
+//----------------------------------------------------------------------
+class DWARFDebugLine
+{
+public:
+    //------------------------------------------------------------------
+    // FileNameEntry
+    //------------------------------------------------------------------
+    struct FileNameEntry
+    {
+        FileNameEntry() :
+            name(),
+            dir_idx(0),
+            mod_time(0),
+            length(0)
+        {
+        }
+
+        std::string     name;
+        dw_sleb128_t    dir_idx;
+        dw_sleb128_t    mod_time;
+        dw_sleb128_t    length;
+
+    };
+
+    //------------------------------------------------------------------
+    // Prologue
+    //------------------------------------------------------------------
+    struct Prologue
+    {
+
+        Prologue() :
+            total_length(0),
+            version(0),
+            prologue_length(0),
+            min_inst_length(0),
+            default_is_stmt(0),
+            line_base(0),
+            line_range(0),
+            opcode_base(0),
+            standard_opcode_lengths(),
+            include_directories(),
+            file_names()
+        {
+        }
+
+        typedef lldb::SharedPtr<Prologue>::Type shared_ptr;
+
+        uint32_t    total_length;   // The size in bytes of the statement information for this compilation unit (not including the total_length field itself).
+        uint16_t    version;        // Version identifier for the statement information format.
+        uint32_t    prologue_length;// The number of bytes following the prologue_length field to the beginning of the first byte of the statement program itself.
+        uint8_t     min_inst_length;// The size in bytes of the smallest target machine instruction. Statement program opcodes that alter the address register first multiply their operands by this value.
+        uint8_t     default_is_stmt;// The initial value of theis_stmtregister.
+        int8_t      line_base;      // This parameter affects the meaning of the special opcodes. See below.
+        uint8_t     line_range;     // This parameter affects the meaning of the special opcodes. See below.
+        uint8_t     opcode_base;    // The number assigned to the first special opcode.
+        std::vector<uint8_t>            standard_opcode_lengths;
+        std::vector<std::string>        include_directories;
+        std::vector<FileNameEntry>      file_names;
+
+        // Length of the prologue in bytes
+        uint32_t Length() const { return prologue_length + sizeof(total_length) + sizeof(version) + sizeof(prologue_length); }
+        // Length of the line table data in bytes (not including the prologue)
+        uint32_t StatementTableLength() const { return total_length + sizeof(total_length) - Length(); }
+        int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; };
+        bool IsValid() const;
+//      void Append(BinaryStreamBuf& buff) const;
+        void Dump (lldb_private::Log *log);
+        void Clear()
+        {
+            total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0;
+            line_base = 0;
+            standard_opcode_lengths.clear();
+            include_directories.clear();
+            file_names.clear();
+        }
+        bool GetFile(uint32_t file_idx, std::string& file, std::string& dir) const;
+
+    };
+
+    // Standard .debug_line state machine structure
+    struct Row
+    {
+        typedef std::vector<Row>            collection;
+        typedef collection::iterator        iterator;
+        typedef collection::const_iterator  const_iterator;
+
+        Row(bool default_is_stmt = false);
+        virtual ~Row() {}
+        void PostAppend ();
+        void Reset(bool default_is_stmt);
+        void Dump(lldb_private::Log *log) const;
+        static void Insert(Row::collection& state_coll, const Row& state);
+        static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
+
+        dw_addr_t   address;        // The program-counter value corresponding to a machine instruction generated by the compiler.
+        uint32_t    line;           // An unsigned integer indicating a source line number. Lines are numbered beginning at 1. The compiler may emit the value 0 in cases where an instruction cannot be attributed to any source line.
+        uint16_t    column;         // An unsigned integer indicating a column number within a source line. Columns are numbered beginning at 1. The value 0 is reserved to indicate that a statement begins at the ‘‘left edge’’ of the line.
+        uint16_t    file;           // An unsigned integer indicating the identity of the source file corresponding to a machine instruction.
+        uint8_t     is_stmt:1,      // A boolean indicating that the current instruction is the beginning of a statement.
+                    basic_block:1,  // A boolean indicating that the current instruction is the beginning of a basic block.
+                    end_sequence:1, // A boolean indicating that the current address is that of the first byte after the end of a sequence of target machine instructions.
+                    prologue_end:1, // A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
+                    epilogue_begin:1;// A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
+        uint32_t    isa;            // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction.
+    };
+
+
+    //------------------------------------------------------------------
+    // LineTable
+    //------------------------------------------------------------------
+    struct LineTable
+    {
+        typedef lldb::SharedPtr<LineTable>::Type shared_ptr;
+
+        LineTable() :
+            prologue(),
+            rows()
+        {
+        }
+
+        void AppendRow(const DWARFDebugLine::Row& state);
+        void Clear()
+        {
+            prologue.reset();
+            rows.clear();
+        }
+
+        uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
+        void Dump(lldb_private::Log *log) const;
+
+        Prologue::shared_ptr prologue;
+        Row::collection rows;
+    };
+
+    //------------------------------------------------------------------
+    // State
+    //------------------------------------------------------------------
+    struct State : public Row
+    {
+        typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData);
+
+        // Special row codes used when calling the callback
+        enum
+        {
+            StartParsingLineTable = 0,
+            DoneParsingLineTable = -1
+        };
+
+        State (Prologue::shared_ptr& prologue_sp,
+               lldb_private::Log *log,
+               Callback callback,
+               void* userData);
+
+        void
+        AppendRowToMatrix (dw_offset_t offset);
+
+        void
+        Finalize (dw_offset_t offset);
+
+        void
+        Reset ();
+
+        Prologue::shared_ptr prologue;
+        lldb_private::Log *log;
+        Callback callback; // Callback funcation that gets called each time an entry it to be added to the matrix
+        void* callbackUserData;
+        int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix
+    private:
+        DISALLOW_COPY_AND_ASSIGN (State);
+    };
+
+    static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0);   // If line_offset is invalid, dump everything
+    static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET);  // If line_offset is invalid, dump everything
+    static bool ParseSupportFiles(const lldb_private::DataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files);
+    static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue);
+    static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, State::Callback callback, void* userData);
+    static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset);
+    static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset, uint32_t flags);
+    static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table);
+    static void Parse(const lldb_private::DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
+//  static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
+
+    DWARFDebugLine() :
+        m_lineTableMap()
+    {
+    }
+
+    void Parse(const lldb_private::DataExtractor& debug_line_data);
+    void ParseIfNeeded(const lldb_private::DataExtractor& debug_line_data);
+    LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
+
+protected:
+    typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
+    typedef LineTableMap::iterator LineTableIter;
+    typedef LineTableMap::const_iterator LineTableConstIter;
+
+    LineTableMap m_lineTableMap;
+};
+
+#endif  // liblldb_DWARFDebugLine_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
new file mode 100644
index 0000000..0501da8
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
@@ -0,0 +1,48 @@
+//===-- DWARFDebugMacinfo.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugMacinfo.h"
+
+#include "DWARFDebugMacinfoEntry.h"
+#include "SymbolFileDWARF.h"
+
+#include "lldb/Core/Stream.h"
+
+using namespace lldb_private;
+using namespace std;
+
+DWARFDebugMacinfo::DWARFDebugMacinfo()
+{
+}
+
+DWARFDebugMacinfo::~DWARFDebugMacinfo()
+{
+}
+
+void
+DWARFDebugMacinfo::Dump(Stream *s, const DataExtractor& macinfo_data, dw_offset_t offset)
+{
+    DWARFDebugMacinfoEntry maninfo_entry;
+    if (macinfo_data.GetByteSize() == 0)
+    {
+        s->PutCString("< EMPTY >\n");
+        return;
+    }
+    if (offset == DW_INVALID_OFFSET)
+    {
+        offset = 0;
+        while (maninfo_entry.Extract(macinfo_data, &offset))
+            maninfo_entry.Dump(s);
+    }
+    else
+    {
+        if (maninfo_entry.Extract(macinfo_data, &offset))
+            maninfo_entry.Dump(s);
+    }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
new file mode 100644
index 0000000..e420a5b
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
@@ -0,0 +1,29 @@
+//===-- DWARFDebugMacinfo.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugLine_h_
+#define SymbolFileDWARF_DWARFDebugLine_h_
+
+#include "SymbolFileDWARF.h"
+
+class DWARFDebugMacinfo
+{
+public:
+    DWARFDebugMacinfo();
+
+    ~DWARFDebugMacinfo();
+
+    static void
+    Dump (lldb_private::Stream *s,
+          const lldb_private::DataExtractor& macinfo_data,
+          dw_offset_t offset = DW_INVALID_OFFSET);
+};
+
+
+#endif  // SymbolFileDWARF_DWARFDebugLine_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
new file mode 100644
index 0000000..c07cec4
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
@@ -0,0 +1,132 @@
+//===-- DWARFDebugMacinfoEntry.cpp ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugMacinfoEntry.h"
+
+#include "lldb/Core/Stream.h"
+
+using namespace lldb_private;
+using namespace std;
+
+DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry() :
+    m_type_code(0),
+    m_line(0),
+    m_op2()
+{
+    m_op2.cstr = NULL;
+}
+
+DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry()
+{
+}
+
+const char*
+DWARFDebugMacinfoEntry::GetCString() const
+{
+    switch (m_type_code)
+    {
+    case 0:
+    case DW_MACINFO_start_file:
+    case DW_MACINFO_end_file:
+        return NULL;
+    default:
+        break;
+    }
+    return m_op2.cstr;
+}
+
+
+
+void
+DWARFDebugMacinfoEntry::Dump(Stream *s) const
+{
+    if (m_type_code)
+    {
+        s->PutCString(DW_MACINFO_value_to_name(m_type_code));
+
+        switch (m_type_code)
+        {
+        case DW_MACINFO_define:
+            s->Printf(" line:%u  #define %s\n", (uint32_t)m_line, m_op2.cstr);
+            break;
+
+        case DW_MACINFO_undef:
+            s->Printf(" line:%u  #undef %s\n", (uint32_t)m_line, m_op2.cstr);
+            break;
+
+        default:
+            s->Printf(" line:%u  str: '%s'\n", (uint32_t)m_line, m_op2.cstr);
+            break;
+
+        case DW_MACINFO_start_file:
+            s->Printf(" line:%u  file index: '%s'\n", (uint32_t)m_line, (uint32_t)m_op2.file_idx);
+            break;
+
+        case DW_MACINFO_end_file:
+            break;
+        }
+    }
+    else
+    {
+        s->PutCString(" END\n");
+    }
+}
+
+
+bool
+DWARFDebugMacinfoEntry::Extract(const DataExtractor& mac_info_data, dw_offset_t* offset_ptr)
+{
+    if (mac_info_data.ValidOffset(*offset_ptr))
+    {
+        m_type_code = mac_info_data.GetU8(offset_ptr);
+
+        switch (m_type_code)
+        {
+
+        case DW_MACINFO_define:
+        case DW_MACINFO_undef:
+            // 2 operands:
+            // Arg 1: operand encodes the line number of the source line on which
+            //      the relevant defining or undefining pre-processor directives
+            //      appeared.
+            m_line  = mac_info_data.GetULEB128(offset_ptr);
+            // Arg 2: define string
+            m_op2.cstr  = mac_info_data.GetCStr(offset_ptr);
+            break;
+
+        case DW_MACINFO_start_file:
+            // 2 operands:
+            // Op 1: line number of the source line on which the inclusion
+            //      pre-processor directive occurred.
+            m_line  = mac_info_data.GetULEB128(offset_ptr);
+            // Op 2: a source file name index to a file number in the statement
+            //      information table for the relevant compilation unit.
+            m_op2.file_idx  = mac_info_data.GetULEB128(offset_ptr);
+            break;
+
+        case 0: // End of list
+        case DW_MACINFO_end_file:
+            // No operands
+            m_line = DW_INVALID_OFFSET;
+            m_op2.cstr = NULL;
+            break;
+        default:
+            // Vendor specific entries always have a ULEB128 and a string
+            m_line      = mac_info_data.GetULEB128(offset_ptr);
+            m_op2.cstr  = mac_info_data.GetCStr(offset_ptr);
+            break;
+        }
+        return true;
+    }
+    else
+        m_type_code = 0;
+
+    return false;
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
new file mode 100644
index 0000000..85dd625
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
@@ -0,0 +1,57 @@
+//===-- DWARFDebugMacinfoEntry.h --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugMacinfoEntry_h_
+#define SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
+
+#include "SymbolFileDWARF.h"
+
+class DWARFDebugMacinfoEntry
+{
+public:
+    DWARFDebugMacinfoEntry();
+
+    ~DWARFDebugMacinfoEntry();
+
+    uint8_t
+    TypeCode() const
+    {
+        return m_type_code;
+    }
+
+    uint8_t
+    GetLineNumber() const
+    {
+        return m_line;
+    }
+
+    void
+    Dump(lldb_private::Stream *s) const;
+
+    const char*
+    GetCString() const;
+
+    bool
+    Extract(const lldb_private::DataExtractor& mac_info_data,
+            dw_offset_t* offset_ptr);
+
+protected:
+
+private:
+    uint8_t m_type_code;
+    dw_uleb128_t m_line;
+    union
+    {
+        dw_uleb128_t file_idx;
+        const char* cstr;
+    } m_op2;
+};
+
+
+#endif  // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
new file mode 100644
index 0000000..93ecaed
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
@@ -0,0 +1,297 @@
+//===-- DWARFDebugPubnames.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugPubnames.h"
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/Timer.h"
+
+#include "DWARFDebugInfo.h"
+#include "DWARFDIECollection.h"
+#include "DWARFFormValue.h"
+#include "DWARFCompileUnit.h"
+#include "LogChannelDWARF.h"
+#include "SymbolFileDWARF.h"
+
+
+using namespace lldb_private;
+
+DWARFDebugPubnames::DWARFDebugPubnames() :
+    m_sets()
+{
+}
+
+bool
+DWARFDebugPubnames::Extract(const DataExtractor& data)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "DWARFDebugPubnames::Extract (byte_size = %zu)",
+                        data.GetByteSize());
+    Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES);
+    if (log)
+        log->Printf("DWARFDebugPubnames::Extract (byte_size = %zu)", data.GetByteSize());
+
+    if (data.ValidOffset(0))
+    {
+        uint32_t offset = 0;
+
+        DWARFDebugPubnamesSet set;
+        while (data.ValidOffset(offset))
+        {
+            if (set.Extract(data, &offset))
+            {
+                m_sets.push_back(set);
+                offset = set.GetOffsetOfNextEntry();
+            }
+            else
+                break;
+        }
+        if (log)
+            Dump (log);
+        return true;
+    }
+    return false;
+}
+
+
+bool
+DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "DWARFDebugPubnames::GeneratePubnames (data = %p)",
+                        dwarf2Data);
+
+    Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES);
+    if (log)
+        log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", dwarf2Data);
+
+    m_sets.clear();
+    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
+    if (debug_info)
+    {
+
+        const DataExtractor* debug_str = &dwarf2Data->get_debug_str_data();
+
+        uint32_t cu_idx = 0;
+        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+        {
+
+            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+            bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
+
+            DWARFDIECollection dies;
+            const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_subprogram, dies) +
+                                     cu->AppendDIEsWithTag (DW_TAG_variable, dies);
+
+            dw_offset_t cu_offset = cu->GetOffset();
+            DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);
+
+            size_t die_idx;
+            for (die_idx = 0; die_idx < die_count; ++die_idx)
+            {
+                const DWARFDebugInfoEntry *die = dies.GetDIEPtrAtIndex(die_idx);
+                DWARFDebugInfoEntry::Attributes attributes;
+                const char *name = NULL;
+                const char *mangled = NULL;
+                bool add_die = false;
+                bool is_variable = false;
+                const size_t num_attributes = die->GetAttributes(dwarf2Data, cu, attributes);
+                if (num_attributes > 0)
+                {
+                    uint32_t i;
+
+                    dw_tag_t tag = die->Tag();
+                    
+                    is_variable = tag == DW_TAG_variable;
+
+                    for (i=0; i<num_attributes; ++i)
+                    {
+                        dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        switch (attr)
+                        {
+                        case DW_AT_name:
+                            if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
+                                name = form_value.AsCString(debug_str);
+                            break;
+
+                        case DW_AT_MIPS_linkage_name:
+                            if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
+                                mangled = form_value.AsCString(debug_str);
+                            break;
+
+                        case DW_AT_low_pc:
+                        case DW_AT_ranges:
+                        case DW_AT_entry_pc:
+                            if (tag == DW_TAG_subprogram)
+                                add_die = true;
+                            break;
+
+                        case DW_AT_location:
+                            if (tag == DW_TAG_variable)
+                            {
+                                const DWARFDebugInfoEntry* parent_die = die->GetParent();
+                                while ( parent_die != NULL )
+                                {
+                                    switch (parent_die->Tag())
+                                    {
+                                    case DW_TAG_subprogram:
+                                    case DW_TAG_lexical_block:
+                                    case DW_TAG_inlined_subroutine:
+                                        // Even if this is a function level static, we don't add it. We could theoretically
+                                        // add these if we wanted to by introspecting into the DW_AT_location and seeing
+                                        // if the location describes a hard coded address, but we dont want the performance
+                                        // penalty of that right now.
+                                        add_die = false;
+//                                      if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
+//                                      {
+//                                          // If we have valid block data, then we have location expression bytes
+//                                          // that are fixed (not a location list).
+//                                          const uint8_t *block_data = form_value.BlockData();
+//                                          if (block_data)
+//                                          {
+//                                              uint32_t block_length = form_value.Unsigned();
+//                                              if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
+//                                              {
+//                                                  if (block_data[0] == DW_OP_addr)
+//                                                      add_die = true;
+//                                              }
+//                                          }
+//                                      }
+                                        parent_die = NULL;  // Terminate the while loop.
+                                        break;
+
+                                    case DW_TAG_compile_unit:
+                                        add_die = true;
+                                        parent_die = NULL;  // Terminate the while loop.
+                                        break;
+
+                                    default:
+                                        parent_die = parent_die->GetParent();   // Keep going in the while loop.
+                                        break;
+                                    }
+                                }
+                            }
+                            break;
+                        }
+                    }
+                }
+
+                if (add_die && (name || mangled))
+                {
+                    if (is_variable)
+                        cu->AddGlobal(die);
+                    pubnames_set.AddDescriptor(die->GetOffset() - cu_offset, mangled ? mangled : name);
+                }
+            }
+
+            if (pubnames_set.NumDescriptors() > 0)
+            {
+                m_sets.push_back(pubnames_set);
+            }
+            
+            // Keep memory down by clearing DIEs if this generate function
+            // caused them to be parsed
+            if (clear_dies)
+                cu->ClearDIEs (true);
+        }
+    }
+    if (m_sets.empty())
+        return false;
+    if (log)
+        Dump (log);
+    return true;
+}
+
+bool
+DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data)
+{
+    m_sets.clear();
+    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
+    if (debug_info)
+    {
+        uint32_t cu_idx = 0;
+        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+        {
+            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+            DWARFDIECollection dies;
+            const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_base_type, dies);
+            dw_offset_t cu_offset = cu->GetOffset();
+            DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);
+
+            size_t die_idx;
+            for (die_idx = 0; die_idx < die_count; ++die_idx)
+            {
+                const DWARFDebugInfoEntry *die = dies.GetDIEPtrAtIndex(die_idx);
+                const char *name = die->GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, NULL);
+
+                if (name)
+                {
+                    pubnames_set.AddDescriptor(die->GetOffset() - cu_offset, name);
+                }
+            }
+
+            if (pubnames_set.NumDescriptors() > 0)
+            {
+                m_sets.push_back(pubnames_set);
+            }
+        }
+    }
+    return !m_sets.empty();
+}
+
+void
+DWARFDebugPubnames::Dump(Log *s) const
+{
+    if (m_sets.empty())
+        s->PutCString("< EMPTY >\n");
+    else
+    {
+        const_iterator pos;
+        const_iterator end = m_sets.end();
+
+        for (pos = m_sets.begin(); pos != end; ++pos)
+            (*pos).Dump(s);
+    }
+}
+
+bool
+DWARFDebugPubnames::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const
+{
+    const_iterator pos;
+    const_iterator end = m_sets.end();
+
+    die_offsets.clear();
+
+    for (pos = m_sets.begin(); pos != end; ++pos)
+    {
+        (*pos).Find(name, ignore_case, die_offsets);
+    }
+
+    return !die_offsets.empty();
+}
+
+bool
+DWARFDebugPubnames::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const
+{
+    const_iterator pos;
+    const_iterator end = m_sets.end();
+
+    die_offsets.clear();
+
+    for (pos = m_sets.begin(); pos != end; ++pos)
+    {
+        (*pos).Find(regex, die_offsets);
+    }
+
+    return !die_offsets.empty();
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
new file mode 100644
index 0000000..7d09bf3
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
@@ -0,0 +1,38 @@
+//===-- DWARFDebugPubnames.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugPubnames_h_
+#define SymbolFileDWARF_DWARFDebugPubnames_h_
+
+#include "SymbolFileDWARF.h"
+
+#include <list>
+
+#include "DWARFDebugPubnamesSet.h"
+
+class DWARFDebugPubnames
+{
+public:
+            DWARFDebugPubnames();
+    bool    Extract(const lldb_private::DataExtractor& data);
+    bool    GeneratePubnames(SymbolFileDWARF* dwarf2Data);
+    bool    GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data);
+
+    void    Dump(lldb_private::Log *s) const;
+    bool    Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
+    bool    Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const;
+protected:
+    typedef std::list<DWARFDebugPubnamesSet>    collection;
+    typedef collection::iterator                iterator;
+    typedef collection::const_iterator          const_iterator;
+
+    collection m_sets;
+};
+
+#endif  // SymbolFileDWARF_DWARFDebugPubnames_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
new file mode 100644
index 0000000..0421ced
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
@@ -0,0 +1,166 @@
+//===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugPubnamesSet.h"
+
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Log.h"
+
+#include "SymbolFileDWARF.h"
+
+using namespace lldb_private;
+
+DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
+    m_offset(DW_INVALID_OFFSET),
+    m_header(),
+    m_descriptors(),
+    m_name_to_descriptor_index()
+{
+}
+
+DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
+    m_offset(debug_aranges_offset),
+    m_header(),
+    m_descriptors(),
+    m_name_to_descriptor_index()
+{
+    m_header.length = 10;               // set the length to only include the header right for now
+    m_header.version = 2;               // The DWARF version number
+    m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
+    m_header.die_length = cu_die_length;// compile unit .debug_info length
+}
+
+void
+DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
+{
+    if (name && name[0])
+    {
+        // Adjust our header length
+        m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
+        Descriptor pubnameDesc(cu_rel_offset, name);
+        m_descriptors.push_back(pubnameDesc);
+    }
+}
+
+void
+DWARFDebugPubnamesSet::Clear()
+{
+    m_offset = DW_INVALID_OFFSET;
+    m_header.length = 10;
+    m_header.version = 2;
+    m_header.die_offset = DW_INVALID_OFFSET;
+    m_header.die_length = 0;
+    m_descriptors.clear();
+}
+
+
+//----------------------------------------------------------------------
+// InitNameIndexes
+//----------------------------------------------------------------------
+void
+DWARFDebugPubnamesSet::InitNameIndexes() const
+{
+    // Create the name index vector to be able to quickly search by name
+    const size_t count = m_descriptors.size();
+    for (uint32_t idx = 0; idx < count; ++idx)
+    {
+        const char* name = m_descriptors[idx].name.c_str();
+        if (name && name[0])
+            m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
+    }
+}
+
+
+bool
+DWARFDebugPubnamesSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+{
+    if (data.ValidOffset(*offset_ptr))
+    {
+        m_descriptors.clear();
+        m_offset = *offset_ptr;
+        m_header.length     = data.GetU32(offset_ptr);
+        m_header.version    = data.GetU16(offset_ptr);
+        m_header.die_offset = data.GetU32(offset_ptr);
+        m_header.die_length = data.GetU32(offset_ptr);
+
+        Descriptor pubnameDesc;
+        while (data.ValidOffset(*offset_ptr))
+        {
+            pubnameDesc.offset  = data.GetU32(offset_ptr);
+
+            if (pubnameDesc.offset)
+            {
+                const char* name = data.GetCStr(offset_ptr);
+                if (name && name[0])
+                {
+                    pubnameDesc.name = name;
+                    m_descriptors.push_back(pubnameDesc);
+                }
+            }
+            else
+                break;  // We are done if we get a zero 4 byte offset
+        }
+
+        return !m_descriptors.empty();
+    }
+    return false;
+}
+
+dw_offset_t
+DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
+{
+    return m_offset + m_header.length + 4;
+}
+
+void
+DWARFDebugPubnamesSet::Dump(Log *log) const
+{
+    log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
+        m_header.length,
+        m_header.version,
+        m_header.die_offset,
+        m_header.die_length);
+
+    bool verbose = log->GetVerbose();
+
+    DescriptorConstIter pos;
+    DescriptorConstIter end = m_descriptors.end();
+    for (pos = m_descriptors.begin(); pos != end; ++pos)
+    {
+        if (verbose)
+            log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str());
+        else
+            log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
+    }
+}
+
+
+void
+DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
+{
+    if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
+        InitNameIndexes();
+
+    std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
+    for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
+        die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
+}
+
+void
+DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
+{
+    DescriptorConstIter pos;
+    DescriptorConstIter end = m_descriptors.end();
+    for (pos = m_descriptors.begin(); pos != end; ++pos)
+    {
+        if ( regex.Execute(pos->name.c_str()) )
+            die_offset_coll.push_back(m_header.die_offset + pos->offset);
+    }
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
new file mode 100644
index 0000000..0597e36
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
@@ -0,0 +1,91 @@
+//===-- DWARFDebugPubnamesSet.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugPubnamesSet_h_
+#define SymbolFileDWARF_DWARFDebugPubnamesSet_h_
+
+#include "SymbolFileDWARF.h"
+#include <string>
+#include <vector>
+#include <ext/hash_map>
+
+class DWARFDebugPubnamesSet
+{
+public:
+    struct Header
+    {
+        uint32_t    length;     // length of the set of entries for this compilation unit, not including the length field itself
+        uint16_t    version;    // The DWARF version number
+        uint32_t    die_offset; // compile unit .debug_info offset
+        uint32_t    die_length; // compile unit .debug_info length
+        Header() :
+            length(10),
+            version(2),
+            die_offset(DW_INVALID_OFFSET),
+            die_length(0)
+        {
+        }
+    };
+
+    struct Descriptor
+    {
+        Descriptor() :
+            offset(),
+            name()
+        {
+        }
+
+        Descriptor(dw_offset_t the_offset, const char *the_name) :
+            offset(the_offset),
+            name(the_name ? the_name : "")
+        {
+        }
+
+        dw_offset_t offset;
+        std::string name;
+    };
+
+                DWARFDebugPubnamesSet();
+                DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t die_length);
+    dw_offset_t GetOffset() const { return m_offset; }
+    void        SetOffset(dw_offset_t offset) { m_offset = offset; }
+    DWARFDebugPubnamesSet::Header& GetHeader() { return m_header; }
+    const DWARFDebugPubnamesSet::Header& GetHeader() const { return m_header; }
+    const DWARFDebugPubnamesSet::Descriptor* GetDescriptor(uint32_t i) const
+        {
+            if (i < m_descriptors.size())
+                return &m_descriptors[i];
+            return NULL;
+        }
+    uint32_t    NumDescriptors() const { return m_descriptors.size(); }
+    void        AddDescriptor(dw_offset_t cu_rel_offset, const char* name);
+    void        Clear();
+    bool        Extract(const lldb_private::DataExtractor& debug_pubnames_data, uint32_t* offset_ptr);
+    void        Dump(lldb_private::Log *s) const;
+    void        InitNameIndexes() const;
+    void        Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
+    void        Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const;
+    dw_offset_t GetOffsetOfNextEntry() const;
+
+
+
+protected:
+    typedef std::vector<Descriptor>         DescriptorColl;
+    typedef DescriptorColl::iterator        DescriptorIter;
+    typedef DescriptorColl::const_iterator  DescriptorConstIter;
+
+
+    dw_offset_t     m_offset;
+    Header          m_header;
+    typedef __gnu_cxx::hash_multimap<const char*, uint32_t, __gnu_cxx::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap;
+    DescriptorColl  m_descriptors;
+    mutable cstr_to_index_mmap m_name_to_descriptor_index;
+};
+
+#endif  // SymbolFileDWARF_DWARFDebugPubnamesSet_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
new file mode 100644
index 0000000..62da228
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -0,0 +1,275 @@
+//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugRanges.h"
+#include "SymbolFileDWARF.h"
+#include "lldb/Core/Stream.h"
+#include <assert.h>
+
+using namespace lldb_private;
+using namespace std;
+
+DWARFDebugRanges::DWARFDebugRanges() :
+    m_range_map()
+{
+}
+
+DWARFDebugRanges::~DWARFDebugRanges()
+{
+}
+
+void
+DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
+{
+    RangeList range_list;
+    dw_offset_t offset = 0;
+    dw_offset_t debug_ranges_offset = offset;
+    while (range_list.Extract(dwarf2Data, &offset))
+    {
+        m_range_map[debug_ranges_offset] = range_list;
+        debug_ranges_offset = offset;
+    }
+}
+
+bool
+DWARFDebugRanges::RangeList::AddRange(dw_addr_t lo_addr, dw_addr_t hi_addr)
+{
+    if (lo_addr <= hi_addr)
+    {
+        Range range(lo_addr, hi_addr);
+        ranges.push_back(range);
+        return true;
+    }
+    return false;
+}
+
+const DWARFDebugRanges::Range*
+DWARFDebugRanges::RangeList::Lookup(dw_addr_t offset) const
+{
+    Range::const_iterator pos = ranges.begin();
+    Range::const_iterator end_pos = ranges.end();
+    for (pos = ranges.begin(); pos != end_pos; ++pos)
+    {
+        if (pos->begin_offset <= offset && offset < pos->end_offset)
+        {
+            return &(*pos);
+        }
+    }
+    return NULL;
+}
+
+size_t
+DWARFDebugRanges::RangeList::Size() const
+{
+    return ranges.size();
+}
+
+void
+DWARFDebugRanges::RangeList::AddOffset(dw_addr_t offset)
+{
+    if (!ranges.empty())
+    {
+        Range::iterator pos = ranges.begin();
+        Range::iterator end_pos = ranges.end();
+        for (pos = ranges.begin(); pos != end_pos; ++pos)
+        {
+            // assert for unsigned overflows
+            assert (~pos->begin_offset >= offset);
+            assert (~pos->end_offset >= offset);
+            pos->begin_offset += offset;
+            pos->end_offset += offset;
+        }
+    }
+}
+
+void
+DWARFDebugRanges::RangeList::SubtractOffset(dw_addr_t offset)
+{
+    if (!ranges.empty())
+    {
+        Range::iterator pos = ranges.begin();
+        Range::iterator end_pos = ranges.end();
+        for (pos = ranges.begin(); pos != end_pos; ++pos)
+        {
+            assert (pos->begin_offset >= offset);
+            assert (pos->end_offset >= offset);
+            pos->begin_offset -= offset;
+            pos->end_offset -= offset;
+        }
+    }
+}
+
+
+const DWARFDebugRanges::Range*
+DWARFDebugRanges::RangeList::RangeAtIndex(size_t i) const
+{
+    if (i < ranges.size())
+        return &ranges[i];
+    return NULL;
+}
+
+bool
+DWARFDebugRanges::RangeList::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr)
+{
+    Clear();
+    uint32_t range_offset = *offset_ptr;
+    const DataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
+    uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
+
+    while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
+    {
+        dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+        dw_addr_t end   = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+        if (!begin && !end)
+        {
+            // End of range list
+            break;
+        }
+        // Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits
+        // of ones
+        switch (addr_size)
+        {
+        case 2:
+            if (begin == 0xFFFFull)
+                begin = DW_INVALID_ADDRESS;
+            break;
+
+        case 4:
+            if (begin == 0xFFFFFFFFull)
+                begin = DW_INVALID_ADDRESS;
+            break;
+
+        case 8:
+            break;
+
+        default:
+            assert(!"DWARFDebugRanges::RangeList::Extract() unsupported address size.");
+            break;
+        }
+
+        // Filter out empty ranges
+        if (begin != end)
+            ranges.push_back(Range(begin, end));
+    }
+
+    // Make sure we consumed at least something
+    return range_offset != *offset_ptr;
+}
+
+
+dw_addr_t
+DWARFDebugRanges::RangeList::LowestAddress(const dw_addr_t cu_base_addr) const
+{
+    dw_addr_t addr = DW_INVALID_ADDRESS;
+    dw_addr_t curr_base_addr = cu_base_addr;
+    if (!ranges.empty())
+    {
+        Range::const_iterator pos = ranges.begin();
+        Range::const_iterator end_pos = ranges.end();
+        for (pos = ranges.begin(); pos != end_pos; ++pos)
+        {
+            if (pos->begin_offset == DW_INVALID_ADDRESS)
+                curr_base_addr = pos->end_offset;
+            else if (curr_base_addr != DW_INVALID_ADDRESS)
+            {
+                dw_addr_t curr_addr = curr_base_addr + pos->begin_offset;
+                if (addr > curr_addr)
+                    addr = curr_addr;
+            }
+        }
+    }
+    return addr;
+}
+
+dw_addr_t
+DWARFDebugRanges::RangeList::HighestAddress(const dw_addr_t cu_base_addr) const
+{
+    dw_addr_t addr = 0;
+    dw_addr_t curr_base_addr = cu_base_addr;
+    if (!ranges.empty())
+    {
+        Range::const_iterator pos = ranges.begin();
+        Range::const_iterator end_pos = ranges.end();
+        for (pos = ranges.begin(); pos != end_pos; ++pos)
+        {
+            if (pos->begin_offset == DW_INVALID_ADDRESS)
+                curr_base_addr = pos->end_offset;
+            else if (curr_base_addr != DW_INVALID_ADDRESS)
+            {
+                dw_addr_t curr_addr = curr_base_addr + pos->end_offset;
+                if (addr < curr_addr)
+                    addr = curr_addr;
+            }
+        }
+    }
+    if (addr != 0)
+        return addr;
+    return DW_INVALID_ADDRESS;
+}
+
+
+void
+DWARFDebugRanges::Dump(Stream *s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr)
+{
+    uint32_t addr_size = s->GetAddressByteSize();
+    bool verbose = s->GetVerbose();
+
+    dw_addr_t base_addr = cu_base_addr;
+    while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
+    {
+        dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+        dw_addr_t end   = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+        // Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits
+        // of ones
+        if (begin == 0xFFFFFFFFull && addr_size == 4)
+            begin = DW_INVALID_ADDRESS;
+
+        s->Indent();
+        if (verbose)
+        {
+            s->AddressRange(begin, end, sizeof (dw_addr_t), " offsets = ");
+        }
+
+
+        if (begin == 0 && end == 0)
+        {
+            s->PutCString(" End");
+            break;
+        }
+        else if (begin == DW_INVALID_ADDRESS)
+        {
+            // A base address selection entry
+            base_addr = end;
+            s->Address(base_addr, sizeof (dw_addr_t), " Base address = ");
+        }
+        else
+        {
+            // Convert from offset to an address
+            dw_addr_t begin_addr = begin + base_addr;
+            dw_addr_t end_addr = end + base_addr;
+
+            s->AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL);
+        }
+    }
+}
+
+bool
+DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, RangeList& range_list) const
+{
+    range_map_const_iterator pos = m_range_map.find(debug_ranges_offset);
+    if (pos != m_range_map.end())
+    {
+        range_list = pos->second;
+        return true;
+    }
+    return false;
+}
+
+
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
new file mode 100644
index 0000000..607c3c2
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -0,0 +1,89 @@
+//===-- DWARFDebugRanges.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDebugRanges_h_
+#define liblldb_DWARFDebugRanges_h_
+
+#include "SymbolFileDWARF.h"
+#include <map>
+#include <vector>
+
+
+class DWARFDebugRanges
+{
+public:
+
+    //------------------------------------------------------------------
+    // Address range
+    //------------------------------------------------------------------
+    struct Range
+    {
+        Range(dw_addr_t begin = DW_INVALID_ADDRESS, dw_addr_t end = DW_INVALID_ADDRESS) :
+            begin_offset(begin),
+            end_offset(end)
+        {
+        }
+
+        void Clear()
+        {
+            begin_offset = DW_INVALID_ADDRESS;
+            end_offset = DW_INVALID_ADDRESS;
+        }
+
+        dw_addr_t   begin_offset;
+        dw_addr_t   end_offset;
+
+        typedef std::vector<Range>          collection;
+        typedef collection::iterator        iterator;
+        typedef collection::const_iterator  const_iterator;
+
+    };
+
+    //------------------------------------------------------------------
+    // Collection of ranges
+    //------------------------------------------------------------------
+    struct RangeList
+    {
+            RangeList() :
+                ranges()
+            {
+            }
+
+        bool Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr);
+        bool AddRange(dw_addr_t lo_addr, dw_addr_t hi_addr);
+        void Clear()
+            {
+                ranges.clear();
+            }
+
+        dw_addr_t LowestAddress(const dw_addr_t base_addr) const;
+        dw_addr_t HighestAddress(const dw_addr_t base_addr) const;
+        void AddOffset(dw_addr_t offset);
+        void SubtractOffset(dw_addr_t offset);
+        size_t Size() const;
+        const Range* RangeAtIndex(size_t i) const;
+        const Range* Lookup(dw_addr_t offset) const;
+        Range::collection   ranges;
+    };
+
+    DWARFDebugRanges();
+    ~DWARFDebugRanges();
+    void Extract(SymbolFileDWARF* dwarf2Data);
+    static void Dump(lldb_private::Stream *s, const lldb_private::DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr);
+    bool FindRanges(dw_offset_t debug_ranges_offset, DWARFDebugRanges::RangeList& range_list) const;
+
+protected:
+    typedef std::map<dw_offset_t, RangeList>    range_map;
+    typedef range_map::iterator                 range_map_iterator;
+    typedef range_map::const_iterator           range_map_const_iterator;
+    range_map m_range_map;
+};
+
+
+#endif  // liblldb_DWARFDebugRanges_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.c b/source/Plugins/SymbolFile/DWARF/DWARFDefines.c
new file mode 100644
index 0000000..fe487f9
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.c
@@ -0,0 +1,2224 @@
+//===-- DWARFDefines.c ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDefines.h"
+#include <stdio.h>
+
+#define DW_TAG_PREFIX   "TAG_"
+#define DW_AT_PREFIX    " AT_"
+#define DW_FORM_PREFIX  "FORM_"
+
+/* [7.5.4] Figure 16 "Tag Encodings" (pp. 125-127) in DWARFv3 draft 8 */
+
+const char *
+DW_TAG_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0000: return DW_TAG_PREFIX "NULL";
+    case 0x0001: return DW_TAG_PREFIX "array_type";
+    case 0x0002: return DW_TAG_PREFIX "class_type";
+    case 0x0003: return DW_TAG_PREFIX "entry_point";
+    case 0x0004: return DW_TAG_PREFIX "enumeration_type";
+    case 0x0005: return DW_TAG_PREFIX "formal_parameter";
+    case 0x0008: return DW_TAG_PREFIX "imported_declaration";
+    case 0x000a: return DW_TAG_PREFIX "label";
+    case 0x000b: return DW_TAG_PREFIX "lexical_block";
+    case 0x000d: return DW_TAG_PREFIX "member";
+    case 0x000f: return DW_TAG_PREFIX "pointer_type";
+    case 0x0010: return DW_TAG_PREFIX "reference_type";
+    case 0x0011: return DW_TAG_PREFIX "compile_unit";
+    case 0x0012: return DW_TAG_PREFIX "string_type";
+    case 0x0013: return DW_TAG_PREFIX "structure_type";
+    case 0x0015: return DW_TAG_PREFIX "subroutine_type";
+    case 0x0016: return DW_TAG_PREFIX "typedef";
+    case 0x0017: return DW_TAG_PREFIX "union_type";
+    case 0x0018: return DW_TAG_PREFIX "unspecified_parameters";
+    case 0x0019: return DW_TAG_PREFIX "variant";
+    case 0x001a: return DW_TAG_PREFIX "common_block";
+    case 0x001b: return DW_TAG_PREFIX "common_inclusion";
+    case 0x001c: return DW_TAG_PREFIX "inheritance";
+    case 0x001d: return DW_TAG_PREFIX "inlined_subroutine";
+    case 0x001e: return DW_TAG_PREFIX "module";
+    case 0x001f: return DW_TAG_PREFIX "ptr_to_member_type";
+    case 0x0020: return DW_TAG_PREFIX "set_type";
+    case 0x0021: return DW_TAG_PREFIX "subrange_type";
+    case 0x0022: return DW_TAG_PREFIX "with_stmt";
+    case 0x0023: return DW_TAG_PREFIX "access_declaration";
+    case 0x0024: return DW_TAG_PREFIX "base_type";
+    case 0x0025: return DW_TAG_PREFIX "catch_block";
+    case 0x0026: return DW_TAG_PREFIX "const_type";
+    case 0x0027: return DW_TAG_PREFIX "constant";
+    case 0x0028: return DW_TAG_PREFIX "enumerator";
+    case 0x0029: return DW_TAG_PREFIX "file_type";
+    case 0x002a: return DW_TAG_PREFIX "friend";
+    case 0x002b: return DW_TAG_PREFIX "namelist";
+    case 0x002c: return DW_TAG_PREFIX "namelist_item";
+    case 0x002d: return DW_TAG_PREFIX "packed_type";
+    case 0x002e: return DW_TAG_PREFIX "subprogram";
+    case 0x002f: return DW_TAG_PREFIX "template_type_parameter";
+    case 0x0030: return DW_TAG_PREFIX "template_value_parameter";
+    case 0x0031: return DW_TAG_PREFIX "thrown_type";
+    case 0x0032: return DW_TAG_PREFIX "try_block";
+    case 0x0033: return DW_TAG_PREFIX "variant_part";
+    case 0x0034: return DW_TAG_PREFIX "variable";
+    case 0x0035: return DW_TAG_PREFIX "volatile_type";
+    case 0x0036: return DW_TAG_PREFIX "dwarf_procedure";
+    case 0x0037: return DW_TAG_PREFIX "restrict_type";
+    case 0x0038: return DW_TAG_PREFIX "interface_type";
+    case 0x0039: return DW_TAG_PREFIX "namespace";
+    case 0x003a: return DW_TAG_PREFIX "imported_module";
+    case 0x003b: return DW_TAG_PREFIX "unspecified_type";
+    case 0x003c: return DW_TAG_PREFIX "partial_unit";
+    case 0x003d: return DW_TAG_PREFIX "imported_unit";
+//  case 0x003d: return DW_TAG_PREFIX "condition";
+    case 0x0040: return DW_TAG_PREFIX "shared_type";
+    case 0x4080: return DW_TAG_PREFIX "lo_user";
+    case 0xffff: return DW_TAG_PREFIX "hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_TAG constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_TAG_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0001: return "array type";
+    case 0x0002: return "class type";
+    case 0x0003: return "entry point";
+    case 0x0004: return "enumeration type";
+    case 0x0005: return "formal parameter";
+    case 0x0008: return "imported declaration";
+    case 0x000a: return "label";
+    case 0x000b: return "lexical block";
+    case 0x000d: return "member";
+    case 0x000f: return "pointer type";
+    case 0x0010: return "reference type";
+    case 0x0011: return "file";
+    case 0x0012: return "string type";
+    case 0x0013: return "structure type";
+    case 0x0015: return "subroutine type";
+    case 0x0016: return "typedef";
+    case 0x0017: return "union type";
+    case 0x0018: return "unspecified parameters";
+    case 0x0019: return "variant";
+    case 0x001a: return "common block";
+    case 0x001b: return "common inclusion";
+    case 0x001c: return "inheritance";
+    case 0x001d: return "inlined subroutine";
+    case 0x001e: return "module";
+    case 0x001f: return "ptr to member type";
+    case 0x0020: return "set type";
+    case 0x0021: return "subrange type";
+    case 0x0022: return "with stmt";
+    case 0x0023: return "access declaration";
+    case 0x0024: return "base type";
+    case 0x0025: return "catch block";
+    case 0x0026: return "const type";
+    case 0x0027: return "constant";
+    case 0x0028: return "enumerator";
+    case 0x0029: return "file type";
+    case 0x002a: return "friend";
+    case 0x002b: return "namelist";
+    case 0x002c: return "namelist item";
+    case 0x002d: return "packed type";
+    case 0x002e: return "function";
+    case 0x002f: return "template type parameter";
+    case 0x0030: return "template value parameter";
+    case 0x0031: return "thrown type";
+    case 0x0032: return "try block";
+    case 0x0033: return "variant part";
+    case 0x0034: return "variable";
+    case 0x0035: return "volatile type";
+    case 0x0036: return "dwarf procedure";
+    case 0x0037: return "restrict type";
+    case 0x0038: return "interface type";
+    case 0x0039: return "namespace";
+    case 0x003a: return "imported module";
+    case 0x003b: return "unspecified type";
+    case 0x003c: return "partial unit";
+    case 0x003d: return "imported unit";
+//  case 0x003d: return "condition";
+    case 0x0040: return "shared type";
+    case 0x4080: return "lo user";
+    case 0xffff: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_TAG constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_TAG_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0001: return 0;
+    case 0x0002: return 0;
+    case 0x0003: return 0;
+    case 0x0004: return 0;
+    case 0x0005: return 0;
+    case 0x0008: return 0;
+    case 0x000a: return 0;
+    case 0x000b: return 0;
+    case 0x000d: return 0;
+    case 0x000f: return 0;
+    case 0x0010: return 0;
+    case 0x0011: return 0;
+    case 0x0012: return 0;
+    case 0x0013: return 0;
+    case 0x0015: return 0;
+    case 0x0016: return 0;
+    case 0x0017: return 0;
+    case 0x0018: return 0;
+    case 0x0019: return 0;
+    case 0x001a: return 0;
+    case 0x001b: return 0;
+    case 0x001c: return 0;
+    case 0x001d: return 0;
+    case 0x001e: return 0;
+    case 0x001f: return 0;
+    case 0x0020: return 0;
+    case 0x0021: return 0;
+    case 0x0022: return 0;
+    case 0x0023: return 0;
+    case 0x0024: return 0;
+    case 0x0025: return 0;
+    case 0x0026: return 0;
+    case 0x0027: return 0;
+    case 0x0028: return 0;
+    case 0x0029: return 0;
+    case 0x002a: return 0;
+    case 0x002b: return 0;
+    case 0x002c: return 0;
+    case 0x002d: return 0;
+    case 0x002e: return 0;
+    case 0x002f: return 0;
+    case 0x0030: return 0;
+    case 0x0031: return 0;
+    case 0x0032: return 0;
+    case 0x0033: return 0;
+    case 0x0034: return 0;
+    case 0x0035: return 0;
+    case 0x0036: return DRC_DWARFv3;
+    case 0x0037: return DRC_DWARFv3;
+    case 0x0038: return DRC_DWARFv3;
+    case 0x0039: return DRC_DWARFv3;
+    case 0x003a: return DRC_DWARFv3;
+    case 0x003b: return DRC_DWARFv3;
+    case 0x003c: return DRC_DWARFv3;
+    case 0x003d: return DRC_DWARFv3;
+//  case 0x003d: return DRC_DWARFv3;
+    case 0x0040: return DRC_DWARFv3;
+    case 0x4080: return 0;
+    case 0xffff: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.5.4] Figure 17 "Child determination encodings" (p. 128) in DWARFv3 draft 8 */
+
+const char *
+DW_CHILDREN_value_to_name (uint8_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_CHILDREN_no";
+    case 0x1: return "DW_CHILDREN_yes";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_CHILDREN constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_CHILDREN_value_to_englishy_name (uint8_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "no";
+    case 0x1: return "yes";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_CHILDREN constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_CHILDREN_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    case 0x1: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.5.4] Figure 18 "Attribute encodings" (pp. 129-132) in DWARFv3 draft 8 */
+
+const char *
+DW_AT_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0001: return DW_AT_PREFIX "sibling";
+    case 0x0002: return DW_AT_PREFIX "location";
+    case 0x0003: return DW_AT_PREFIX "name";
+    case 0x0009: return DW_AT_PREFIX "ordering";
+    case 0x000b: return DW_AT_PREFIX "byte_size";
+    case 0x000c: return DW_AT_PREFIX "bit_offset";
+    case 0x000d: return DW_AT_PREFIX "bit_size";
+    case 0x0010: return DW_AT_PREFIX "stmt_list";
+    case 0x0011: return DW_AT_PREFIX "low_pc";
+    case 0x0012: return DW_AT_PREFIX "high_pc";
+    case 0x0013: return DW_AT_PREFIX "language";
+    case 0x0015: return DW_AT_PREFIX "discr";
+    case 0x0016: return DW_AT_PREFIX "discr_value";
+    case 0x0017: return DW_AT_PREFIX "visibility";
+    case 0x0018: return DW_AT_PREFIX "import";
+    case 0x0019: return DW_AT_PREFIX "string_length";
+    case 0x001a: return DW_AT_PREFIX "common_reference";
+    case 0x001b: return DW_AT_PREFIX "comp_dir";
+    case 0x001c: return DW_AT_PREFIX "const_value";
+    case 0x001d: return DW_AT_PREFIX "containing_type";
+    case 0x001e: return DW_AT_PREFIX "default_value";
+    case 0x0020: return DW_AT_PREFIX "inline";
+    case 0x0021: return DW_AT_PREFIX "is_optional";
+    case 0x0022: return DW_AT_PREFIX "lower_bound";
+    case 0x0025: return DW_AT_PREFIX "producer";
+    case 0x0027: return DW_AT_PREFIX "prototyped";
+    case 0x002a: return DW_AT_PREFIX "return_addr";
+    case 0x002c: return DW_AT_PREFIX "start_scope";
+    case 0x002e: return DW_AT_PREFIX "bit_stride";
+    case 0x002f: return DW_AT_PREFIX "upper_bound";
+    case 0x0031: return DW_AT_PREFIX "abstract_origin";
+    case 0x0032: return DW_AT_PREFIX "accessibility";
+    case 0x0033: return DW_AT_PREFIX "address_class";
+    case 0x0034: return DW_AT_PREFIX "artificial";
+    case 0x0035: return DW_AT_PREFIX "base_types";
+    case 0x0036: return DW_AT_PREFIX "calling_convention";
+    case 0x0037: return DW_AT_PREFIX "count";
+    case 0x0038: return DW_AT_PREFIX "data_member_location";
+    case 0x0039: return DW_AT_PREFIX "decl_column";
+    case 0x003a: return DW_AT_PREFIX "decl_file";
+    case 0x003b: return DW_AT_PREFIX "decl_line";
+    case 0x003c: return DW_AT_PREFIX "declaration";
+    case 0x003d: return DW_AT_PREFIX "discr_list";
+    case 0x003e: return DW_AT_PREFIX "encoding";
+    case 0x003f: return DW_AT_PREFIX "external";
+    case 0x0040: return DW_AT_PREFIX "frame_base";
+    case 0x0041: return DW_AT_PREFIX "friend";
+    case 0x0042: return DW_AT_PREFIX "identifier_case";
+    case 0x0043: return DW_AT_PREFIX "macro_info";
+    case 0x0044: return DW_AT_PREFIX "namelist_item";
+    case 0x0045: return DW_AT_PREFIX "priority";
+    case 0x0046: return DW_AT_PREFIX "segment";
+    case 0x0047: return DW_AT_PREFIX "specification";
+    case 0x0048: return DW_AT_PREFIX "static_link";
+    case 0x0049: return DW_AT_PREFIX "type";
+    case 0x004a: return DW_AT_PREFIX "use_location";
+    case 0x004b: return DW_AT_PREFIX "variable_parameter";
+    case 0x004c: return DW_AT_PREFIX "virtuality";
+    case 0x004d: return DW_AT_PREFIX "vtable_elem_location";
+    case 0x004e: return DW_AT_PREFIX "allocated";
+    case 0x004f: return DW_AT_PREFIX "associated";
+    case 0x0050: return DW_AT_PREFIX "data_location";
+    case 0x0051: return DW_AT_PREFIX "byte_stride";
+    case 0x0052: return DW_AT_PREFIX "entry_pc";
+    case 0x0053: return DW_AT_PREFIX "use_UTF8";
+    case 0x0054: return DW_AT_PREFIX "extension";
+    case 0x0055: return DW_AT_PREFIX "ranges";
+    case 0x0056: return DW_AT_PREFIX "trampoline";
+    case 0x0057: return DW_AT_PREFIX "call_column";
+    case 0x0058: return DW_AT_PREFIX "call_file";
+    case 0x0059: return DW_AT_PREFIX "call_line";
+    case 0x005a: return DW_AT_PREFIX "description";
+    case 0x005b: return DW_AT_PREFIX "binary_scale";
+    case 0x005c: return DW_AT_PREFIX "decimal_scale";
+    case 0x005d: return DW_AT_PREFIX "small";
+    case 0x005e: return DW_AT_PREFIX "decimal_sign";
+    case 0x005f: return DW_AT_PREFIX "digit_count";
+    case 0x0060: return DW_AT_PREFIX "picture_string";
+    case 0x0061: return DW_AT_PREFIX "mutable";
+    case 0x0062: return DW_AT_PREFIX "threads_scaled";
+    case 0x0063: return DW_AT_PREFIX "explicit";
+    case 0x0064: return DW_AT_PREFIX "object_pointer";
+    case 0x0065: return DW_AT_PREFIX "endianity";
+    case 0x0066: return DW_AT_PREFIX "elemental";
+    case 0x0067: return DW_AT_PREFIX "pure";
+    case 0x0068: return DW_AT_PREFIX "recursive";
+    case 0x2000: return DW_AT_PREFIX "lo_user";
+    case 0x3fff: return DW_AT_PREFIX "hi_user";
+    case 0x2001: return DW_AT_PREFIX "MIPS_fde";
+    case 0x2002: return DW_AT_PREFIX "MIPS_loop_begin";
+    case 0x2003: return DW_AT_PREFIX "MIPS_tail_loop_begin";
+    case 0x2004: return DW_AT_PREFIX "MIPS_epilog_begin";
+    case 0x2005: return DW_AT_PREFIX "MIPS_loop_unroll_factor";
+    case 0x2006: return DW_AT_PREFIX "MIPS_software_pipeline_depth";
+    case 0x2007: return DW_AT_PREFIX "MIPS_linkage_name";
+    case 0x2008: return DW_AT_PREFIX "MIPS_stride";
+    case 0x2009: return DW_AT_PREFIX "MIPS_abstract_name";
+    case 0x200a: return DW_AT_PREFIX "MIPS_clone_origin";
+    case 0x200b: return DW_AT_PREFIX "MIPS_has_inlines";
+    case 0x2101: return DW_AT_PREFIX "sf_names";
+    case 0x2102: return DW_AT_PREFIX "src_info";
+    case 0x2103: return DW_AT_PREFIX "mac_info";
+    case 0x2104: return DW_AT_PREFIX "src_coords";
+    case 0x2105: return DW_AT_PREFIX "body_begin";
+    case 0x2106: return DW_AT_PREFIX "body_end";
+    case 0x2107: return DW_AT_PREFIX "GNU_vector";
+    case 0x2501: return DW_AT_PREFIX "APPLE_repository_file";
+    case 0x2502: return DW_AT_PREFIX "APPLE_repository_type";
+    case 0x2503: return DW_AT_PREFIX "APPLE_repository_name";
+    case 0x2504: return DW_AT_PREFIX "APPLE_repository_specification";
+    case 0x2505: return DW_AT_PREFIX "APPLE_repository_import";
+    case 0x2506: return DW_AT_PREFIX "APPLE_repository_abstract_origin";
+    case DW_AT_APPLE_flags: return DW_AT_PREFIX "APPLE_flags";
+    case DW_AT_APPLE_optimized: return DW_AT_PREFIX "APPLE_optimized";
+    case DW_AT_APPLE_isa: return DW_AT_PREFIX "APPLE_isa";
+    case DW_AT_APPLE_block: return DW_AT_PREFIX "APPLE_block";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_AT constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_AT_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0001: return "sibling";
+    case 0x0002: return "location";
+    case 0x0003: return "name";
+    case 0x0009: return "ordering";
+    case 0x000b: return "byte size";
+    case 0x000c: return "bit offset";
+    case 0x000d: return "bit size";
+    case 0x0010: return "stmt list";
+    case 0x0011: return "low pc";
+    case 0x0012: return "high pc";
+    case 0x0013: return "language";
+    case 0x0015: return "discr";
+    case 0x0016: return "discr value";
+    case 0x0017: return "visibility";
+    case 0x0018: return "import";
+    case 0x0019: return "string length";
+    case 0x001a: return "common reference";
+    case 0x001b: return "comp dir";
+    case 0x001c: return "const value";
+    case 0x001d: return "containing type";
+    case 0x001e: return "default value";
+    case 0x0020: return "inline";
+    case 0x0021: return "is optional";
+    case 0x0022: return "lower bound";
+    case 0x0025: return "producer";
+    case 0x0027: return "prototyped";
+    case 0x002a: return "return addr";
+    case 0x002c: return "start scope";
+    case 0x002e: return "bit stride";
+    case 0x002f: return "upper bound";
+    case 0x0031: return "abstract origin";
+    case 0x0032: return "accessibility";
+    case 0x0033: return "address class";
+    case 0x0034: return "artificial";
+    case 0x0035: return "base types";
+    case 0x0036: return "calling convention";
+    case 0x0037: return "count";
+    case 0x0038: return "data member location";
+    case 0x0039: return "decl column";
+    case 0x003a: return "decl file";
+    case 0x003b: return "decl line";
+    case 0x003c: return "declaration";
+    case 0x003d: return "discr list";
+    case 0x003e: return "encoding";
+    case 0x003f: return "external";
+    case 0x0040: return "frame base";
+    case 0x0041: return "friend";
+    case 0x0042: return "identifier case";
+    case 0x0043: return "macro info";
+    case 0x0044: return "namelist item";
+    case 0x0045: return "priority";
+    case 0x0046: return "segment";
+    case 0x0047: return "specification";
+    case 0x0048: return "static link";
+    case 0x0049: return "type";
+    case 0x004a: return "use location";
+    case 0x004b: return "variable parameter";
+    case 0x004c: return "virtuality";
+    case 0x004d: return "vtable elem location";
+    case 0x004e: return "allocated";
+    case 0x004f: return "associated";
+    case 0x0050: return "data location";
+    case 0x0051: return "byte stride";
+    case 0x0052: return "entry pc";
+    case 0x0053: return "use UTF8";
+    case 0x0054: return "extension";
+    case 0x0055: return "ranges";
+    case 0x0056: return "trampoline";
+    case 0x0057: return "call column";
+    case 0x0058: return "call file";
+    case 0x0059: return "call line";
+    case 0x005a: return "description";
+    case 0x005b: return "binary scale";
+    case 0x005c: return "decimal scale";
+    case 0x005d: return "small";
+    case 0x005e: return "decimal sign";
+    case 0x005f: return "digit count";
+    case 0x0060: return "picture string";
+    case 0x0061: return "mutable";
+    case 0x0062: return "threads scaled";
+    case 0x0063: return "explicit";
+    case 0x0064: return "object pointer";
+    case 0x0065: return "endianity";
+    case 0x0066: return "elemental";
+    case 0x0067: return "pure";
+    case 0x0068: return "recursive";
+    case 0x2000: return "lo user";
+    case 0x3fff: return "hi user";
+    case 0x2001: return "MIPS fde";
+    case 0x2002: return "MIPS loop begin";
+    case 0x2003: return "MIPS tail loop begin";
+    case 0x2004: return "MIPS epilog begin";
+    case 0x2005: return "MIPS loop unroll factor";
+    case 0x2006: return "MIPS software pipeline depth";
+    case 0x2007: return "MIPS linkage name";
+    case 0x2008: return "MIPS stride";
+    case 0x2009: return "MIPS abstract name";
+    case 0x200a: return "MIPS clone origin";
+    case 0x200b: return "MIPS has inlines";
+    case 0x2101: return "source file names";
+    case 0x2102: return "source info";
+    case 0x2103: return "macro info";
+    case 0x2104: return "source coordinates";
+    case 0x2105: return "body begin";
+    case 0x2106: return "body end";
+    case 0x2107: return "GNU vector";
+    case 0x2501: return "repository file";
+    case 0x2502: return "repository type";
+    case 0x2503: return "repository name";
+    case 0x2504: return "repository specification";
+    case 0x2505: return "repository import";
+    case 0x2506: return "repository abstract origin";
+    case DW_AT_APPLE_flags: return "Apple gcc compiler flags";
+    case DW_AT_APPLE_optimized: return "APPLE optimized";
+    case DW_AT_APPLE_isa: return "APPLE instruction set architecture";
+    case DW_AT_APPLE_block: return "APPLE block";
+   default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_AT constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_AT_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0001: return DRC_REFERENCE;
+    case 0x0002: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x0003: return DRC_STRING;
+    case 0x0009: return DRC_CONSTANT;
+    case 0x000b: return DRC_BLOCK | DRC_CONSTANT | DRC_REFERENCE;
+    case 0x000c: return DRC_BLOCK | DRC_CONSTANT | DRC_REFERENCE;
+    case 0x000d: return DRC_BLOCK | DRC_CONSTANT | DRC_REFERENCE;
+    case 0x0010: return DRC_LINEPTR;
+    case 0x0011: return DRC_ADDRESS;
+    case 0x0012: return DRC_ADDRESS;
+    case 0x0013: return DRC_CONSTANT;
+    case 0x0015: return DRC_REFERENCE;
+    case 0x0016: return DRC_CONSTANT;
+    case 0x0017: return DRC_CONSTANT;
+    case 0x0018: return DRC_REFERENCE;
+    case 0x0019: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x001a: return DRC_REFERENCE;
+    case 0x001b: return DRC_STRING;
+    case 0x001c: return DRC_BLOCK | DRC_CONSTANT | DRC_STRING;
+    case 0x001d: return DRC_REFERENCE;
+    case 0x001e: return DRC_REFERENCE;
+    case 0x0020: return DRC_CONSTANT;
+    case 0x0021: return DRC_FLAG;
+    case 0x0022: return DRC_BLOCK | DRC_CONSTANT | DRC_REFERENCE;
+    case 0x0025: return DRC_STRING;
+    case 0x0027: return DRC_FLAG;
+    case 0x002a: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x002c: return DRC_CONSTANT;
+    case 0x002e: return DRC_CONSTANT;
+    case 0x002f: return DRC_BLOCK | DRC_CONSTANT | DRC_REFERENCE;
+    case 0x0031: return DRC_REFERENCE;
+    case 0x0032: return DRC_CONSTANT;
+    case 0x0033: return DRC_CONSTANT;
+    case 0x0034: return DRC_FLAG;
+    case 0x0035: return DRC_REFERENCE;
+    case 0x0036: return DRC_CONSTANT;
+    case 0x0037: return DRC_BLOCK | DRC_CONSTANT | DRC_REFERENCE;
+    case 0x0038: return DRC_BLOCK | DRC_CONSTANT | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x0039: return DRC_CONSTANT;
+    case 0x003a: return DRC_CONSTANT;
+    case 0x003b: return DRC_CONSTANT;
+    case 0x003c: return DRC_FLAG;
+    case 0x003d: return DRC_BLOCK;
+    case 0x003e: return DRC_CONSTANT;
+    case 0x003f: return DRC_FLAG;
+    case 0x0040: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x0041: return DRC_REFERENCE;
+    case 0x0042: return DRC_CONSTANT;
+    case 0x0043: return DRC_MACPTR;
+    case 0x0044: return DRC_BLOCK;
+    case 0x0045: return DRC_REFERENCE;
+    case 0x0046: return DRC_BLOCK | DRC_CONSTANT;
+    case 0x0047: return DRC_REFERENCE;
+    case 0x0048: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x0049: return DRC_REFERENCE;
+    case 0x004a: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x004b: return DRC_FLAG;
+    case 0x004c: return DRC_CONSTANT;
+    case 0x004d: return DRC_BLOCK | DRC_LOCEXPR | DRC_LOCLISTPTR;
+    case 0x004e: return DRC_BLOCK | DRC_CONSTANT | DRC_DWARFv3 | DRC_REFERENCE;
+    case 0x004f: return DRC_BLOCK | DRC_CONSTANT | DRC_DWARFv3 | DRC_REFERENCE;
+    case 0x0050: return DRC_BLOCK | DRC_DWARFv3;
+    case 0x0051: return DRC_BLOCK | DRC_CONSTANT | DRC_DWARFv3 | DRC_REFERENCE;
+    case 0x0052: return DRC_ADDRESS | DRC_DWARFv3;
+    case 0x0053: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x0054: return DRC_DWARFv3 | DRC_REFERENCE;
+    case 0x0055: return DRC_DWARFv3 | DRC_RANGELISTPTR;
+    case 0x0056: return DRC_ADDRESS | DRC_DWARFv3 | DRC_FLAG | DRC_REFERENCE | DRC_STRING;
+    case 0x0057: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x0058: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x0059: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x005a: return DRC_DWARFv3 | DRC_STRING;
+    case 0x005b: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x005c: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x005d: return DRC_DWARFv3 | DRC_REFERENCE;
+    case 0x005e: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x005f: return DRC_CONSTANT | DRC_DWARFv3;
+    case 0x0060: return DRC_DWARFv3 | DRC_STRING;
+    case 0x0061: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x0062: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x0063: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x0064: return DRC_DWARFv3 | DRC_REFERENCE;
+    case 0x0065: return DRC_0x65 | DRC_CONSTANT | DRC_DWARFv3;
+    case 0x0066: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x0067: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x0068: return DRC_DWARFv3 | DRC_FLAG;
+    case 0x2000: return 0;
+    case 0x3fff: return 0;
+    case 0x2001: return DRC_VENDOR_MIPS;
+    case 0x2002: return DRC_VENDOR_MIPS;
+    case 0x2003: return DRC_VENDOR_MIPS;
+    case 0x2004: return DRC_VENDOR_MIPS;
+    case 0x2005: return DRC_VENDOR_MIPS;
+    case 0x2006: return DRC_VENDOR_MIPS;
+    case 0x2007: return DRC_STRING | DRC_VENDOR_MIPS;
+    case 0x2008: return DRC_VENDOR_MIPS;
+    case 0x2009: return DRC_VENDOR_MIPS;
+    case 0x200a: return DRC_VENDOR_MIPS;
+    case 0x200b: return DRC_VENDOR_MIPS;
+    default: return 0;
+  }
+}
+
+/* [7.5.4] Figure 19 "Attribute form encodings" (pp. 133-134) in DWARFv3 draft 8 */
+
+const char *
+DW_FORM_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return DW_FORM_PREFIX "addr";
+    case 0x03: return DW_FORM_PREFIX "block2";
+    case 0x04: return DW_FORM_PREFIX "block4";
+    case 0x05: return DW_FORM_PREFIX "data2";
+    case 0x06: return DW_FORM_PREFIX "data4";
+    case 0x07: return DW_FORM_PREFIX "data8";
+    case 0x08: return DW_FORM_PREFIX "string";
+    case 0x09: return DW_FORM_PREFIX "block";
+    case 0x0a: return DW_FORM_PREFIX "block1";
+    case 0x0b: return DW_FORM_PREFIX "data1";
+    case 0x0c: return DW_FORM_PREFIX "flag";
+    case 0x0d: return DW_FORM_PREFIX "sdata";
+    case 0x0e: return DW_FORM_PREFIX "strp";
+    case 0x0f: return DW_FORM_PREFIX "udata";
+    case 0x10: return DW_FORM_PREFIX "ref_addr";
+    case 0x11: return DW_FORM_PREFIX "ref1";
+    case 0x12: return DW_FORM_PREFIX "ref2";
+    case 0x13: return DW_FORM_PREFIX "ref4";
+    case 0x14: return DW_FORM_PREFIX "ref8";
+    case 0x15: return DW_FORM_PREFIX "ref_udata";
+    case 0x16: return DW_FORM_PREFIX "indirect";
+//  case DW_FORM_APPLE_db_str: return DW_FORM_PREFIX "APPLE_db_str";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_FORM constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_FORM_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "addr";
+    case 0x03: return "block2";
+    case 0x04: return "block4";
+    case 0x05: return "data2";
+    case 0x06: return "data4";
+    case 0x07: return "data8";
+    case 0x08: return "string";
+    case 0x09: return "block";
+    case 0x0a: return "block1";
+    case 0x0b: return "data1";
+    case 0x0c: return "flag";
+    case 0x0d: return "sdata";
+    case 0x0e: return "strp";
+    case 0x0f: return "udata";
+    case 0x10: return "ref addr";
+    case 0x11: return "ref1";
+    case 0x12: return "ref2";
+    case 0x13: return "ref4";
+    case 0x14: return "ref8";
+    case 0x15: return "ref udata";
+    case 0x16: return "indirect";
+//  case DW_FORM_APPLE_db_str: return "repository str";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_FORM constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_FORM_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x01: return DRC_ADDRESS;
+    case 0x03: return DRC_BLOCK | DRC_LOCEXPR;
+    case 0x04: return DRC_BLOCK | DRC_LOCEXPR;
+    case 0x05: return DRC_CONSTANT;
+    case 0x06: return DRC_CONSTANT | DRC_LINEPTR | DRC_LOCLISTPTR | DRC_MACPTR | DRC_RANGELISTPTR;
+    case 0x07: return DRC_CONSTANT | DRC_LINEPTR | DRC_LOCLISTPTR | DRC_MACPTR | DRC_RANGELISTPTR;
+    case 0x08: return DRC_STRING;
+    case 0x09: return DRC_BLOCK | DRC_LOCEXPR;
+    case 0x0a: return DRC_BLOCK | DRC_LOCEXPR;
+    case 0x0b: return DRC_CONSTANT;
+    case 0x0c: return DRC_FLAG;
+    case 0x0d: return DRC_CONSTANT;
+    case 0x0e: return DRC_STRING;
+    case 0x0f: return DRC_CONSTANT;
+    case 0x10: return DRC_REFERENCE;
+    case 0x11: return DRC_REFERENCE;
+    case 0x12: return DRC_REFERENCE;
+    case 0x13: return DRC_REFERENCE;
+    case 0x14: return DRC_REFERENCE;
+    case 0x15: return DRC_REFERENCE;
+    case 0x16: return DRC_INDIRECT_SPECIAL;
+    default: return 0;
+  }
+}
+
+/* [7.7.1] Figure 22 "DWARF operation encodings" (pp. 136-139) in DWARFv3 draft 8 */
+
+const char *
+DW_OP_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x03: return "DW_OP_addr";
+    case 0x06: return "DW_OP_deref";
+    case 0x08: return "DW_OP_const1u";
+    case 0x09: return "DW_OP_const1s";
+    case 0x0a: return "DW_OP_const2u";
+    case 0x0b: return "DW_OP_const2s";
+    case 0x0c: return "DW_OP_const4u";
+    case 0x0d: return "DW_OP_const4s";
+    case 0x0e: return "DW_OP_const8u";
+    case 0x0f: return "DW_OP_const8s";
+    case 0x10: return "DW_OP_constu";
+    case 0x11: return "DW_OP_consts";
+    case 0x12: return "DW_OP_dup";
+    case 0x13: return "DW_OP_drop";
+    case 0x14: return "DW_OP_over";
+    case 0x15: return "DW_OP_pick";
+    case 0x16: return "DW_OP_swap";
+    case 0x17: return "DW_OP_rot";
+    case 0x18: return "DW_OP_xderef";
+    case 0x19: return "DW_OP_abs";
+    case 0x1a: return "DW_OP_and";
+    case 0x1b: return "DW_OP_div";
+    case 0x1c: return "DW_OP_minus";
+    case 0x1d: return "DW_OP_mod";
+    case 0x1e: return "DW_OP_mul";
+    case 0x1f: return "DW_OP_neg";
+    case 0x20: return "DW_OP_not";
+    case 0x21: return "DW_OP_or";
+    case 0x22: return "DW_OP_plus";
+    case 0x23: return "DW_OP_plus_uconst";
+    case 0x24: return "DW_OP_shl";
+    case 0x25: return "DW_OP_shr";
+    case 0x26: return "DW_OP_shra";
+    case 0x27: return "DW_OP_xor";
+    case 0x2f: return "DW_OP_skip";
+    case 0x28: return "DW_OP_bra";
+    case 0x29: return "DW_OP_eq";
+    case 0x2a: return "DW_OP_ge";
+    case 0x2b: return "DW_OP_gt";
+    case 0x2c: return "DW_OP_le";
+    case 0x2d: return "DW_OP_lt";
+    case 0x2e: return "DW_OP_ne";
+    case 0x30: return "DW_OP_lit0";
+    case 0x31: return "DW_OP_lit1";
+    case 0x32: return "DW_OP_lit2";
+    case 0x33: return "DW_OP_lit3";
+    case 0x34: return "DW_OP_lit4";
+    case 0x35: return "DW_OP_lit5";
+    case 0x36: return "DW_OP_lit6";
+    case 0x37: return "DW_OP_lit7";
+    case 0x38: return "DW_OP_lit8";
+    case 0x39: return "DW_OP_lit9";
+    case 0x3a: return "DW_OP_lit10";
+    case 0x3b: return "DW_OP_lit11";
+    case 0x3c: return "DW_OP_lit12";
+    case 0x3d: return "DW_OP_lit13";
+    case 0x3e: return "DW_OP_lit14";
+    case 0x3f: return "DW_OP_lit15";
+    case 0x40: return "DW_OP_lit16";
+    case 0x41: return "DW_OP_lit17";
+    case 0x42: return "DW_OP_lit18";
+    case 0x43: return "DW_OP_lit19";
+    case 0x44: return "DW_OP_lit20";
+    case 0x45: return "DW_OP_lit21";
+    case 0x46: return "DW_OP_lit22";
+    case 0x47: return "DW_OP_lit23";
+    case 0x48: return "DW_OP_lit24";
+    case 0x49: return "DW_OP_lit25";
+    case 0x4a: return "DW_OP_lit26";
+    case 0x4b: return "DW_OP_lit27";
+    case 0x4c: return "DW_OP_lit28";
+    case 0x4d: return "DW_OP_lit29";
+    case 0x4e: return "DW_OP_lit30";
+    case 0x4f: return "DW_OP_lit31";
+    case 0x50: return "DW_OP_reg0";
+    case 0x51: return "DW_OP_reg1";
+    case 0x52: return "DW_OP_reg2";
+    case 0x53: return "DW_OP_reg3";
+    case 0x54: return "DW_OP_reg4";
+    case 0x55: return "DW_OP_reg5";
+    case 0x56: return "DW_OP_reg6";
+    case 0x57: return "DW_OP_reg7";
+    case 0x58: return "DW_OP_reg8";
+    case 0x59: return "DW_OP_reg9";
+    case 0x5a: return "DW_OP_reg10";
+    case 0x5b: return "DW_OP_reg11";
+    case 0x5c: return "DW_OP_reg12";
+    case 0x5d: return "DW_OP_reg13";
+    case 0x5e: return "DW_OP_reg14";
+    case 0x5f: return "DW_OP_reg15";
+    case 0x60: return "DW_OP_reg16";
+    case 0x61: return "DW_OP_reg17";
+    case 0x62: return "DW_OP_reg18";
+    case 0x63: return "DW_OP_reg19";
+    case 0x64: return "DW_OP_reg20";
+    case 0x65: return "DW_OP_reg21";
+    case 0x66: return "DW_OP_reg22";
+    case 0x67: return "DW_OP_reg23";
+    case 0x68: return "DW_OP_reg24";
+    case 0x69: return "DW_OP_reg25";
+    case 0x6a: return "DW_OP_reg26";
+    case 0x6b: return "DW_OP_reg27";
+    case 0x6c: return "DW_OP_reg28";
+    case 0x6d: return "DW_OP_reg29";
+    case 0x6e: return "DW_OP_reg30";
+    case 0x6f: return "DW_OP_reg31";
+    case 0x70: return "DW_OP_breg0";
+    case 0x71: return "DW_OP_breg1";
+    case 0x72: return "DW_OP_breg2";
+    case 0x73: return "DW_OP_breg3";
+    case 0x74: return "DW_OP_breg4";
+    case 0x75: return "DW_OP_breg5";
+    case 0x76: return "DW_OP_breg6";
+    case 0x77: return "DW_OP_breg7";
+    case 0x78: return "DW_OP_breg8";
+    case 0x79: return "DW_OP_breg9";
+    case 0x7a: return "DW_OP_breg10";
+    case 0x7b: return "DW_OP_breg11";
+    case 0x7c: return "DW_OP_breg12";
+    case 0x7d: return "DW_OP_breg13";
+    case 0x7e: return "DW_OP_breg14";
+    case 0x7f: return "DW_OP_breg15";
+    case 0x80: return "DW_OP_breg16";
+    case 0x81: return "DW_OP_breg17";
+    case 0x82: return "DW_OP_breg18";
+    case 0x83: return "DW_OP_breg19";
+    case 0x84: return "DW_OP_breg20";
+    case 0x85: return "DW_OP_breg21";
+    case 0x86: return "DW_OP_breg22";
+    case 0x87: return "DW_OP_breg23";
+    case 0x88: return "DW_OP_breg24";
+    case 0x89: return "DW_OP_breg25";
+    case 0x8a: return "DW_OP_breg26";
+    case 0x8b: return "DW_OP_breg27";
+    case 0x8c: return "DW_OP_breg28";
+    case 0x8d: return "DW_OP_breg29";
+    case 0x8e: return "DW_OP_breg30";
+    case 0x8f: return "DW_OP_breg31";
+    case 0x90: return "DW_OP_regx";
+    case 0x91: return "DW_OP_fbreg";
+    case 0x92: return "DW_OP_bregx";
+    case 0x93: return "DW_OP_piece";
+    case 0x94: return "DW_OP_deref_size";
+    case 0x95: return "DW_OP_xderef_size";
+    case 0x96: return "DW_OP_nop";
+    case 0x97: return "DW_OP_push_object_address";
+    case 0x98: return "DW_OP_call2";
+    case 0x99: return "DW_OP_call4";
+    case 0x9a: return "DW_OP_call_ref";
+    case 0xf0: return "DW_OP_APPLE_uninit";
+    case 0xe0: return "DW_OP_lo_user";
+    case 0xff: return "DW_OP_hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_OP_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x03: return "addr";
+    case 0x06: return "deref";
+    case 0x08: return "const1u";
+    case 0x09: return "const1s";
+    case 0x0a: return "const2u";
+    case 0x0b: return "const2s";
+    case 0x0c: return "const4u";
+    case 0x0d: return "const4s";
+    case 0x0e: return "const8u";
+    case 0x0f: return "const8s";
+    case 0x10: return "constu";
+    case 0x11: return "consts";
+    case 0x12: return "dup";
+    case 0x13: return "drop";
+    case 0x14: return "over";
+    case 0x15: return "pick";
+    case 0x16: return "swap";
+    case 0x17: return "rot";
+    case 0x18: return "xderef";
+    case 0x19: return "abs";
+    case 0x1a: return "and";
+    case 0x1b: return "div";
+    case 0x1c: return "minus";
+    case 0x1d: return "mod";
+    case 0x1e: return "mul";
+    case 0x1f: return "neg";
+    case 0x20: return "not";
+    case 0x21: return "or";
+    case 0x22: return "plus";
+    case 0x23: return "plus uconst";
+    case 0x24: return "shl";
+    case 0x25: return "shr";
+    case 0x26: return "shra";
+    case 0x27: return "xor";
+    case 0x2f: return "skip";
+    case 0x28: return "bra";
+    case 0x29: return "eq";
+    case 0x2a: return "ge";
+    case 0x2b: return "gt";
+    case 0x2c: return "le";
+    case 0x2d: return "lt";
+    case 0x2e: return "ne";
+    case 0x30: return "lit0";
+    case 0x31: return "lit1";
+    case 0x32: return "lit2";
+    case 0x33: return "lit3";
+    case 0x34: return "lit4";
+    case 0x35: return "lit5";
+    case 0x36: return "lit6";
+    case 0x37: return "lit7";
+    case 0x38: return "lit8";
+    case 0x39: return "lit9";
+    case 0x3a: return "lit10";
+    case 0x3b: return "lit11";
+    case 0x3c: return "lit12";
+    case 0x3d: return "lit13";
+    case 0x3e: return "lit14";
+    case 0x3f: return "lit15";
+    case 0x40: return "lit16";
+    case 0x41: return "lit17";
+    case 0x42: return "lit18";
+    case 0x43: return "lit19";
+    case 0x44: return "lit20";
+    case 0x45: return "lit21";
+    case 0x46: return "lit22";
+    case 0x47: return "lit23";
+    case 0x48: return "lit24";
+    case 0x49: return "lit25";
+    case 0x4a: return "lit26";
+    case 0x4b: return "lit27";
+    case 0x4c: return "lit28";
+    case 0x4d: return "lit29";
+    case 0x4e: return "lit30";
+    case 0x4f: return "lit31";
+    case 0x50: return "reg0";
+    case 0x51: return "reg1";
+    case 0x52: return "reg2";
+    case 0x53: return "reg3";
+    case 0x54: return "reg4";
+    case 0x55: return "reg5";
+    case 0x56: return "reg6";
+    case 0x57: return "reg7";
+    case 0x58: return "reg8";
+    case 0x59: return "reg9";
+    case 0x5a: return "reg10";
+    case 0x5b: return "reg11";
+    case 0x5c: return "reg12";
+    case 0x5d: return "reg13";
+    case 0x5e: return "reg14";
+    case 0x5f: return "reg15";
+    case 0x60: return "reg16";
+    case 0x61: return "reg17";
+    case 0x62: return "reg18";
+    case 0x63: return "reg19";
+    case 0x64: return "reg20";
+    case 0x65: return "reg21";
+    case 0x66: return "reg22";
+    case 0x67: return "reg23";
+    case 0x68: return "reg24";
+    case 0x69: return "reg25";
+    case 0x6a: return "reg26";
+    case 0x6b: return "reg27";
+    case 0x6c: return "reg28";
+    case 0x6d: return "reg29";
+    case 0x6e: return "reg30";
+    case 0x6f: return "reg31";
+    case 0x70: return "breg0";
+    case 0x71: return "breg1";
+    case 0x72: return "breg2";
+    case 0x73: return "breg3";
+    case 0x74: return "breg4";
+    case 0x75: return "breg5";
+    case 0x76: return "breg6";
+    case 0x77: return "breg7";
+    case 0x78: return "breg8";
+    case 0x79: return "breg9";
+    case 0x7a: return "breg10";
+    case 0x7b: return "breg11";
+    case 0x7c: return "breg12";
+    case 0x7d: return "breg13";
+    case 0x7e: return "breg14";
+    case 0x7f: return "breg15";
+    case 0x80: return "breg16";
+    case 0x81: return "breg17";
+    case 0x82: return "breg18";
+    case 0x83: return "breg19";
+    case 0x84: return "breg20";
+    case 0x85: return "breg21";
+    case 0x86: return "breg22";
+    case 0x87: return "breg23";
+    case 0x88: return "breg24";
+    case 0x89: return "breg25";
+    case 0x8a: return "breg26";
+    case 0x8b: return "breg27";
+    case 0x8c: return "breg28";
+    case 0x8d: return "breg29";
+    case 0x8e: return "breg30";
+    case 0x8f: return "breg31";
+    case 0x90: return "regx";
+    case 0x91: return "fbreg";
+    case 0x92: return "bregx";
+    case 0x93: return "piece";
+    case 0x94: return "deref size";
+    case 0x95: return "xderef size";
+    case 0x96: return "nop";
+    case 0x97: return "push object address";
+    case 0x98: return "call2";
+    case 0x99: return "call4";
+    case 0x9a: return "call ref";
+    case 0xf0: return "uninitialized";
+    case 0xe0: return "lo user";
+    case 0xff: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_OP_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x03: return DRC_ONEOPERAND;
+    case 0x06: return DRC_ZEROOPERANDS;
+    case 0x08: return DRC_ONEOPERAND;
+    case 0x09: return DRC_ONEOPERAND;
+    case 0x0a: return DRC_ONEOPERAND;
+    case 0x0b: return DRC_ONEOPERAND;
+    case 0x0c: return DRC_ONEOPERAND;
+    case 0x0d: return DRC_ONEOPERAND;
+    case 0x0e: return DRC_ONEOPERAND;
+    case 0x0f: return DRC_ONEOPERAND;
+    case 0x10: return DRC_ONEOPERAND;
+    case 0x11: return DRC_ONEOPERAND;
+    case 0x12: return DRC_ZEROOPERANDS;
+    case 0x13: return DRC_ZEROOPERANDS;
+    case 0x14: return DRC_ZEROOPERANDS;
+    case 0x15: return DRC_ONEOPERAND;
+    case 0x16: return DRC_ZEROOPERANDS;
+    case 0x17: return DRC_ZEROOPERANDS;
+    case 0x18: return DRC_ZEROOPERANDS;
+    case 0x19: return DRC_ZEROOPERANDS;
+    case 0x1a: return DRC_ZEROOPERANDS;
+    case 0x1b: return DRC_ZEROOPERANDS;
+    case 0x1c: return DRC_ZEROOPERANDS;
+    case 0x1d: return DRC_ZEROOPERANDS;
+    case 0x1e: return DRC_ZEROOPERANDS;
+    case 0x1f: return DRC_ZEROOPERANDS;
+    case 0x20: return DRC_ZEROOPERANDS;
+    case 0x21: return DRC_ZEROOPERANDS;
+    case 0x22: return DRC_ZEROOPERANDS;
+    case 0x23: return DRC_ONEOPERAND;
+    case 0x24: return DRC_ZEROOPERANDS;
+    case 0x25: return DRC_ZEROOPERANDS;
+    case 0x26: return DRC_ZEROOPERANDS;
+    case 0x27: return DRC_ZEROOPERANDS;
+    case 0x2f: return DRC_ONEOPERAND;
+    case 0x28: return DRC_ONEOPERAND;
+    case 0x29: return DRC_ZEROOPERANDS;
+    case 0x2a: return DRC_ZEROOPERANDS;
+    case 0x2b: return DRC_ZEROOPERANDS;
+    case 0x2c: return DRC_ZEROOPERANDS;
+    case 0x2d: return DRC_ZEROOPERANDS;
+    case 0x2e: return DRC_ZEROOPERANDS;
+    case 0x30: return DRC_ZEROOPERANDS;
+    case 0x31: return DRC_ZEROOPERANDS;
+    case 0x32: return DRC_ZEROOPERANDS;
+    case 0x33: return DRC_ZEROOPERANDS;
+    case 0x34: return DRC_ZEROOPERANDS;
+    case 0x35: return DRC_ZEROOPERANDS;
+    case 0x36: return DRC_ZEROOPERANDS;
+    case 0x37: return DRC_ZEROOPERANDS;
+    case 0x38: return DRC_ZEROOPERANDS;
+    case 0x39: return DRC_ZEROOPERANDS;
+    case 0x3a: return DRC_ZEROOPERANDS;
+    case 0x3b: return DRC_ZEROOPERANDS;
+    case 0x3c: return DRC_ZEROOPERANDS;
+    case 0x3d: return DRC_ZEROOPERANDS;
+    case 0x3e: return DRC_ZEROOPERANDS;
+    case 0x3f: return DRC_ZEROOPERANDS;
+    case 0x40: return DRC_ZEROOPERANDS;
+    case 0x41: return DRC_ZEROOPERANDS;
+    case 0x42: return DRC_ZEROOPERANDS;
+    case 0x43: return DRC_ZEROOPERANDS;
+    case 0x44: return DRC_ZEROOPERANDS;
+    case 0x45: return DRC_ZEROOPERANDS;
+    case 0x46: return DRC_ZEROOPERANDS;
+    case 0x47: return DRC_ZEROOPERANDS;
+    case 0x48: return DRC_ZEROOPERANDS;
+    case 0x49: return DRC_ZEROOPERANDS;
+    case 0x4a: return DRC_ZEROOPERANDS;
+    case 0x4b: return DRC_ZEROOPERANDS;
+    case 0x4c: return DRC_ZEROOPERANDS;
+    case 0x4d: return DRC_ZEROOPERANDS;
+    case 0x4e: return DRC_ZEROOPERANDS;
+    case 0x4f: return DRC_ZEROOPERANDS;
+    case 0x50: return DRC_ZEROOPERANDS;
+    case 0x51: return DRC_ZEROOPERANDS;
+    case 0x52: return DRC_ZEROOPERANDS;
+    case 0x53: return DRC_ZEROOPERANDS;
+    case 0x54: return DRC_ZEROOPERANDS;
+    case 0x55: return DRC_ZEROOPERANDS;
+    case 0x56: return DRC_ZEROOPERANDS;
+    case 0x57: return DRC_ZEROOPERANDS;
+    case 0x58: return DRC_ZEROOPERANDS;
+    case 0x59: return DRC_ZEROOPERANDS;
+    case 0x5a: return DRC_ZEROOPERANDS;
+    case 0x5b: return DRC_ZEROOPERANDS;
+    case 0x5c: return DRC_ZEROOPERANDS;
+    case 0x5d: return DRC_ZEROOPERANDS;
+    case 0x5e: return DRC_ZEROOPERANDS;
+    case 0x5f: return DRC_ZEROOPERANDS;
+    case 0x60: return DRC_ZEROOPERANDS;
+    case 0x61: return DRC_ZEROOPERANDS;
+    case 0x62: return DRC_ZEROOPERANDS;
+    case 0x63: return DRC_ZEROOPERANDS;
+    case 0x64: return DRC_ZEROOPERANDS;
+    case 0x65: return DRC_ZEROOPERANDS;
+    case 0x66: return DRC_ZEROOPERANDS;
+    case 0x67: return DRC_ZEROOPERANDS;
+    case 0x68: return DRC_ZEROOPERANDS;
+    case 0x69: return DRC_ZEROOPERANDS;
+    case 0x6a: return DRC_ZEROOPERANDS;
+    case 0x6b: return DRC_ZEROOPERANDS;
+    case 0x6c: return DRC_ZEROOPERANDS;
+    case 0x6d: return DRC_ZEROOPERANDS;
+    case 0x6e: return DRC_ZEROOPERANDS;
+    case 0x6f: return DRC_ZEROOPERANDS;
+    case 0x70: return DRC_ONEOPERAND;
+    case 0x71: return DRC_ONEOPERAND;
+    case 0x72: return DRC_ONEOPERAND;
+    case 0x73: return DRC_ONEOPERAND;
+    case 0x74: return DRC_ONEOPERAND;
+    case 0x75: return DRC_ONEOPERAND;
+    case 0x76: return DRC_ONEOPERAND;
+    case 0x77: return DRC_ONEOPERAND;
+    case 0x78: return DRC_ONEOPERAND;
+    case 0x79: return DRC_ONEOPERAND;
+    case 0x7a: return DRC_ONEOPERAND;
+    case 0x7b: return DRC_ONEOPERAND;
+    case 0x7c: return DRC_ONEOPERAND;
+    case 0x7d: return DRC_ONEOPERAND;
+    case 0x7e: return DRC_ONEOPERAND;
+    case 0x7f: return DRC_ONEOPERAND;
+    case 0x80: return DRC_ONEOPERAND;
+    case 0x81: return DRC_ONEOPERAND;
+    case 0x82: return DRC_ONEOPERAND;
+    case 0x83: return DRC_ONEOPERAND;
+    case 0x84: return DRC_ONEOPERAND;
+    case 0x85: return DRC_ONEOPERAND;
+    case 0x86: return DRC_ONEOPERAND;
+    case 0x87: return DRC_ONEOPERAND;
+    case 0x88: return DRC_ONEOPERAND;
+    case 0x89: return DRC_ONEOPERAND;
+    case 0x8a: return DRC_ONEOPERAND;
+    case 0x8b: return DRC_ONEOPERAND;
+    case 0x8c: return DRC_ONEOPERAND;
+    case 0x8d: return DRC_ONEOPERAND;
+    case 0x8e: return DRC_ONEOPERAND;
+    case 0x8f: return DRC_ONEOPERAND;
+    case 0x90: return DRC_ONEOPERAND;
+    case 0x91: return DRC_ONEOPERAND;
+    case 0x92: return DRC_TWOOPERANDS;
+    case 0x93: return DRC_ONEOPERAND;
+    case 0x94: return DRC_ONEOPERAND;
+    case 0x95: return DRC_ONEOPERAND;
+    case 0x96: return DRC_ZEROOPERANDS;
+    case 0x97: return DRC_DWARFv3 | DRC_ZEROOPERANDS;
+    case 0x98: return DRC_DWARFv3 | DRC_ONEOPERAND;
+    case 0x99: return DRC_DWARFv3 | DRC_ONEOPERAND;
+    case 0x9a: return DRC_DWARFv3 | DRC_ONEOPERAND;
+    case 0xf0: return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
+    case 0xe0: return 0;
+    case 0xff: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.8] Figure 23 "Base type encoding values" (pp. 140-141) in DWARFv3 draft 8 */
+
+const char *
+DW_ATE_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "DW_ATE_address";
+    case 0x02: return "DW_ATE_boolean";
+    case 0x03: return "DW_ATE_complex_float";
+    case 0x04: return "DW_ATE_float";
+    case 0x05: return "DW_ATE_signed";
+    case 0x06: return "DW_ATE_signed_char";
+    case 0x07: return "DW_ATE_unsigned";
+    case 0x08: return "DW_ATE_unsigned_char";
+    case 0x09: return "DW_ATE_imaginary_float";
+    case 0x80: return "DW_ATE_lo_user";
+    case 0xff: return "DW_ATE_hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ATE constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_ATE_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "address";
+    case 0x02: return "boolean";
+    case 0x03: return "complex float";
+    case 0x04: return "float";
+    case 0x05: return "signed";
+    case 0x06: return "signed char";
+    case 0x07: return "unsigned";
+    case 0x08: return "unsigned char";
+    case 0x09: return "imaginary float";
+    case 0x80: return "lo user";
+    case 0xff: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ATE constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_ATE_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x01: return 0;
+    case 0x02: return 0;
+    case 0x03: return 0;
+    case 0x04: return 0;
+    case 0x05: return 0;
+    case 0x06: return 0;
+    case 0x07: return 0;
+    case 0x08: return 0;
+    case 0x09: return DRC_DWARFv3;
+    case 0x80: return 0;
+    case 0xff: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.9] Figure 24 "Accessibility encodings" (p. 141) in DWARFv3 draft 8 */
+
+const char *
+DW_ACCESS_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x1: return "DW_ACCESS_public";
+    case 0x2: return "DW_ACCESS_protected";
+    case 0x3: return "DW_ACCESS_private";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ACCESS constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_ACCESS_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x1: return "public";
+    case 0x2: return "protected";
+    case 0x3: return "private";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ACCESS constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_ACCESS_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x1: return 0;
+    case 0x2: return 0;
+    case 0x3: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.10] Figure 25 "Visibility encodings" (p. 142) in DWARFv3 draft 8 */
+
+const char *
+DW_VIS_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x1: return "DW_VIS_local";
+    case 0x2: return "DW_VIS_exported";
+    case 0x3: return "DW_VIS_qualified";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_VIS constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_VIS_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x1: return "local";
+    case 0x2: return "exported";
+    case 0x3: return "qualified";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_VIS constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_VIS_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x1: return 0;
+    case 0x2: return 0;
+    case 0x3: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.11] Figure 26 "Virtuality encodings" (p. 142) in DWARFv3 draft 8 */
+
+const char *
+DW_VIRTUALITY_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_VIRTUALITY_none";
+    case 0x1: return "DW_VIRTUALITY_virtual";
+    case 0x2: return "DW_VIRTUALITY_pure_virtual";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_VIRTUALITY constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_VIRTUALITY_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "none";
+    case 0x1: return "virtual";
+    case 0x2: return "pure virtual";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_VIRTUALITY constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_VIRTUALITY_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    case 0x1: return 0;
+    case 0x2: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.12] Figure 27 "Language encodings" (p. 143) in DWARFv3 draft 8 */
+
+const char *
+DW_LANG_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0001: return "DW_LANG_C89";
+    case 0x0002: return "DW_LANG_C";
+    case 0x0003: return "DW_LANG_Ada83";
+    case 0x0004: return "DW_LANG_C_plus_plus";
+    case 0x0005: return "DW_LANG_Cobol74";
+    case 0x0006: return "DW_LANG_Cobol85";
+    case 0x0007: return "DW_LANG_Fortran77";
+    case 0x0008: return "DW_LANG_Fortran90";
+    case 0x0009: return "DW_LANG_Pascal83";
+    case 0x000a: return "DW_LANG_Modula2";
+    case 0x000b: return "DW_LANG_Java";
+    case 0x000c: return "DW_LANG_C99";
+    case 0x000d: return "DW_LANG_Ada95";
+    case 0x000e: return "DW_LANG_Fortran95";
+    case 0x000f: return "DW_LANG_PLI";
+    case 0x0010: return "DW_LANG_ObjC";
+    case 0x0011: return "DW_LANG_ObjC_plus_plus";
+    case 0x0012: return "DW_LANG_UPC";
+    case 0x0013: return "DW_LANG_D";
+    case 0x8000: return "DW_LANG_lo_user";
+    case 0x8001: return "DW_LANG_Mips_Assembler";
+    case 0x8765: return "DW_LANG_Upc";
+    case 0xffff: return "DW_LANG_hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_LANG constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_LANG_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0001: return "C89";
+    case 0x0002: return "C";
+    case 0x0003: return "Ada83";
+    case 0x0004: return "C++";
+    case 0x0005: return "Cobol74";
+    case 0x0006: return "Cobol85";
+    case 0x0007: return "Fortran77";
+    case 0x0008: return "Fortran90";
+    case 0x0009: return "Pascal83";
+    case 0x000a: return "Modula2";
+    case 0x000b: return "Java";
+    case 0x000c: return "C99";
+    case 0x000d: return "Ada95";
+    case 0x000e: return "Fortran95";
+    case 0x000f: return "PLI";
+    case 0x0010: return "Objective C";
+    case 0x0011: return "Objective C++";
+    case 0x0012: return "UPC";
+    case 0x0013: return "D";
+    case 0x8000: return "lo user";
+    case 0x8001: return "MIPS Assembler";
+    case 0x8765: return "UPC";
+    case 0xffff: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_LANG constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_LANG_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0001: return 0;
+    case 0x0002: return 0;
+    case 0x0003: return 0;
+    case 0x0004: return 0;
+    case 0x0005: return 0;
+    case 0x0006: return 0;
+    case 0x0007: return 0;
+    case 0x0008: return 0;
+    case 0x0009: return 0;
+    case 0x000a: return 0;
+    case 0x000b: return DRC_DWARFv3;
+    case 0x000c: return DRC_DWARFv3;
+    case 0x000d: return DRC_DWARFv3;
+    case 0x000e: return DRC_DWARFv3;
+    case 0x000f: return DRC_DWARFv3;
+    case 0x0010: return DRC_DWARFv3;
+    case 0x0011: return DRC_DWARFv3;
+    case 0x0012: return DRC_DWARFv3;
+    case 0x0013: return DRC_DWARFv3;
+    case 0x8000: return 0;
+    case 0x8001: return 0;
+    case 0x8765: return 0;
+    case 0xffff: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.13], "Address Class Encodings" (p. 144) in DWARFv3 draft 8 */
+
+const char *
+DW_ADDR_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_ADDR_none";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ADDR constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_ADDR_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "none";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ADDR constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_ADDR_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.14] Figure 28 "Identifier case encodings" (p. 144) in DWARFv3 draft 8 */
+
+const char *
+DW_ID_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_ID_case_sensitive";
+    case 0x1: return "DW_ID_up_case";
+    case 0x2: return "DW_ID_down_case";
+    case 0x3: return "DW_ID_case_insensitive";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ID constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_ID_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "case sensitive";
+    case 0x1: return "up case";
+    case 0x2: return "down case";
+    case 0x3: return "case insensitive";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ID constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_ID_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    case 0x1: return 0;
+    case 0x2: return 0;
+    case 0x3: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.15] Figure 29 "Calling convention encodings" (p. 144) in DWARFv3 draft 8 */
+
+const char *
+DW_CC_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "DW_CC_normal";
+    case 0x02: return "DW_CC_program";
+    case 0x03: return "DW_CC_nocall";
+    case 0x40: return "DW_CC_lo_user";
+    case 0xff: return "DW_CC_hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_CC constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_CC_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "normal";
+    case 0x02: return "program";
+    case 0x03: return "nocall";
+    case 0x40: return "lo user";
+    case 0xff: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_CC constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_CC_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x01: return 0;
+    case 0x02: return 0;
+    case 0x03: return 0;
+    case 0x40: return 0;
+    case 0xff: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.16] Figure 30 "Inline encodings" (p. 145) in DWARFv3 draft 8 */
+
+const char *
+DW_INL_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_INL_not_inlined";
+    case 0x1: return "DW_INL_inlined";
+    case 0x2: return "DW_INL_declared_not_inlined";
+    case 0x3: return "DW_INL_declared_inlined";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_INL constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_INL_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "not inlined";
+    case 0x1: return "inlined";
+    case 0x2: return "declared not inlined";
+    case 0x3: return "declared inlined";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_INL constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_INL_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    case 0x1: return 0;
+    case 0x2: return 0;
+    case 0x3: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.17] Figure 31 "Ordering encodings" (p. 145) in DWARFv3 draft 8 */
+
+const char *
+DW_ORD_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_ORD_row_major";
+    case 0x1: return "DW_ORD_col_major";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ORD constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_ORD_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "row major";
+    case 0x1: return "col major";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_ORD constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_ORD_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    case 0x1: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.18] Figure 32 "Discriminant descriptor encodings" (p. 146) in DWARFv3 draft 8 */
+
+const char *
+DW_DSC_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "DW_DSC_label";
+    case 0x1: return "DW_DSC_range";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_DSC constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_DSC_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x0: return "label";
+    case 0x1: return "range";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_DSC constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_DSC_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x0: return 0;
+    case 0x1: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.21] Figure 33 "Line Number Standard Opcode Encodings" (pp. 148-149) in DWARFv3 draft 8 */
+
+const char *
+DW_LNS_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x1: return "DW_LNS_copy";
+    case 0x2: return "DW_LNS_advance_pc";
+    case 0x3: return "DW_LNS_advance_line";
+    case 0x4: return "DW_LNS_set_file";
+    case 0x5: return "DW_LNS_set_column";
+    case 0x6: return "DW_LNS_negate_stmt";
+    case 0x7: return "DW_LNS_set_basic_block";
+    case 0x8: return "DW_LNS_const_add_pc";
+    case 0x9: return "DW_LNS_fixed_advance_pc";
+    case 0xa: return "DW_LNS_set_prologue_end";
+    case 0xb: return "DW_LNS_set_epilogue_begin";
+    case 0xc: return "DW_LNS_set_isa";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_LNS constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_LNS_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x1: return "copy";
+    case 0x2: return "advance pc";
+    case 0x3: return "advance line";
+    case 0x4: return "set file";
+    case 0x5: return "set column";
+    case 0x6: return "negate stmt";
+    case 0x7: return "set basic block";
+    case 0x8: return "const add pc";
+    case 0x9: return "fixed advance pc";
+    case 0xa: return "set prologue end";
+    case 0xb: return "set epilogue begin";
+    case 0xc: return "set isa";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_LNS constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_LNS_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x1: return 0;
+    case 0x2: return 0;
+    case 0x3: return 0;
+    case 0x4: return 0;
+    case 0x5: return 0;
+    case 0x6: return 0;
+    case 0x7: return 0;
+    case 0x8: return 0;
+    case 0x9: return 0;
+    case 0xa: return DRC_DWARFv3;
+    case 0xb: return DRC_DWARFv3;
+    case 0xc: return DRC_DWARFv3;
+    default: return 0;
+  }
+}
+
+/* [7.21] Figure 34 "Line Number Extended Opcode Encodings" (p. 149) in DWARFv3 draft 8 */
+
+const char *
+DW_LNE_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "DW_LNE_end_sequence";
+    case 0x02: return "DW_LNE_set_address";
+    case 0x03: return "DW_LNE_define_file";
+    case 0x80: return "DW_LNE_lo_user";
+    case 0xff: return "DW_LNE_hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_LNE constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_LNE_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "end sequence";
+    case 0x02: return "set address";
+    case 0x03: return "define file";
+    case 0x80: return "lo user";
+    case 0xff: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_LNE constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_LNE_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x01: return 0;
+    case 0x02: return 0;
+    case 0x03: return 0;
+    case 0x80: return DRC_DWARFv3;
+    case 0xff: return DRC_DWARFv3;
+    default: return 0;
+  }
+}
+
+/* [7.22] Figure 35 "Macinfo Type Encodings" (p. 150) in DWARFv3 draft 8 */
+
+const char *
+DW_MACINFO_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "DW_MACINFO_define";
+    case 0x02: return "DW_MACINFO_undef";
+    case 0x03: return "DW_MACINFO_start_file";
+    case 0x04: return "DW_MACINFO_end_file";
+    case 0xff: return "DW_MACINFO_vendor_ext";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_MACINFO constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_MACINFO_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x01: return "define";
+    case 0x02: return "undef";
+    case 0x03: return "start file";
+    case 0x04: return "end file";
+    case 0xff: return "vendor ext";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_MACINFO constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_MACINFO_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x01: return 0;
+    case 0x02: return 0;
+    case 0x03: return 0;
+    case 0x04: return 0;
+    case 0xff: return 0;
+    default: return 0;
+  }
+}
+
+/* [7.23] Figure 36 "Call frame instruction encodings" (pp. 151-152) in DWARFv3 draft 8 */
+
+const char *
+DW_CFA_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x40: return "DW_CFA_advance_loc";
+    case 0x80: return "DW_CFA_offset";
+    case 0xc0: return "DW_CFA_restore";
+    case 0x00: return "DW_CFA_nop";
+    case 0x01: return "DW_CFA_set_loc";
+    case 0x02: return "DW_CFA_advance_loc1";
+    case 0x03: return "DW_CFA_advance_loc2";
+    case 0x04: return "DW_CFA_advance_loc4";
+    case 0x05: return "DW_CFA_offset_extended";
+    case 0x06: return "DW_CFA_restore_extended";
+    case 0x07: return "DW_CFA_undefined";
+    case 0x08: return "DW_CFA_same_value";
+    case 0x09: return "DW_CFA_register";
+    case 0x0a: return "DW_CFA_remember_state";
+    case 0x0b: return "DW_CFA_restore_state";
+    case 0x0c: return "DW_CFA_def_cfa";
+    case 0x0d: return "DW_CFA_def_cfa_register";
+    case 0x0e: return "DW_CFA_def_cfa_offset";
+    case 0x0f: return "DW_CFA_def_cfa_expression";
+    case 0x10: return "DW_CFA_expression";
+    case 0x11: return "DW_CFA_offset_extended_sf";
+    case 0x12: return "DW_CFA_def_cfa_sf";
+    case 0x13: return "DW_CFA_def_cfa_offset_sf";
+    case 0x1c: return "DW_CFA_lo_user";
+    case 0x3f: return "DW_CFA_hi_user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_CFA_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x40: return "advance loc";
+    case 0x80: return "offset";
+    case 0xc0: return "restore";
+    case 0x00: return "nop";
+    case 0x01: return "set loc";
+    case 0x02: return "advance loc1";
+    case 0x03: return "advance loc2";
+    case 0x04: return "advance loc4";
+    case 0x05: return "offset extended";
+    case 0x06: return "restore extended";
+    case 0x07: return "undefined";
+    case 0x08: return "same value";
+    case 0x09: return "register";
+    case 0x0a: return "remember state";
+    case 0x0b: return "restore state";
+    case 0x0c: return "def cfa";
+    case 0x0d: return "def cfa register";
+    case 0x0e: return "def cfa offset";
+    case 0x0f: return "def cfa expression";
+    case 0x10: return "expression";
+    case 0x11: return "offset extended sf";
+    case 0x12: return "def cfa sf";
+    case 0x13: return "def cfa offset sf";
+    case 0x1c: return "lo user";
+    case 0x3f: return "hi user";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_CFA_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x40: return DRC_ZEROOPERANDS;
+    case 0x80: return DRC_ONEOPERAND | DRC_OPERANDONE_ULEB128_OFFSET;
+    case 0xc0: return DRC_ZEROOPERANDS;
+    case 0x00: return DRC_ZEROOPERANDS;
+    case 0x01: return DRC_ONEOPERAND | DRC_OPERANDONE_ADDRESS;
+    case 0x02: return DRC_ONEOPERAND | DRC_OPERANDONE_1BYTE_DELTA;
+    case 0x03: return DRC_ONEOPERAND | DRC_OPERANDONE_2BYTE_DELTA;
+    case 0x04: return DRC_ONEOPERAND | DRC_OPERANDONE_4BYTE_DELTA;
+    case 0x05: return DRC_OPERANDTWO_ULEB128_OFFSET | DRC_OPERNADONE_ULEB128_REGISTER | DRC_TWOOPERANDS;
+    case 0x06: return DRC_ONEOPERAND | DRC_OPERANDONE_ULEB128_REGISTER;
+    case 0x07: return DRC_ONEOPERAND | DRC_OPERANDONE_ULEB128_REGISTER;
+    case 0x08: return DRC_ONEOPERAND | DRC_OPERANDONE_ULEB128_REGISTER;
+    case 0x09: return DRC_OPERANDONE_ULEB128_REGISTER | DRC_OPERANDTWO_ULEB128_REGISTER | DRC_TWOOPERANDS;
+    case 0x0a: return DRC_ZEROOPERANDS;
+    case 0x0b: return DRC_ZEROOPERANDS;
+    case 0x0c: return DRC_OPERANDONE_ULEB128_REGISTER | DRC_OPERANDTWO_ULEB128_OFFSET | DRC_TWOOPERANDS;
+    case 0x0d: return DRC_ONEOPERAND | DRC_OPERANDONE_ULEB128_REGISTER;
+    case 0x0e: return DRC_ONEOPERAND | DRC_OPERANDONE_ULEB128_OFFSET;
+    case 0x0f: return DRC_DWARFv3 | DRC_ONEOPERAND | DRC_OPERANDONE_BLOCK;
+    case 0x10: return DRC_DWARFv3 | DRC_OPERANDONE_ULEB128_REGISTER | DRC_OPERANDTWO_BLOCK | DRC_TWOOPERANDS;
+    case 0x11: return DRC_DWARFv3 | DRC_OPERANDONE_ULEB128_REGISTER | DRC_OPERANDTWO_SLEB128_OFFSET | DRC_TWOOPERANDS;
+    case 0x12: return DRC_DWARFv3 | DRC_OPERANDONE_ULEB128_REGISTER | DRC_OPERANDTWO_SLEB128_OFFSET | DRC_TWOOPERANDS;
+    case 0x13: return DRC_DWARFv3 | DRC_ONEOPERAND | DRC_OPERANDONE_SLEB128_OFFSET;
+    case 0x1c: return 0;
+    case 0x3f: return 0;
+    default: return 0;
+  }
+}
+
+/* FSF exception handling Pointer-Encoding constants (CFI augmentation) -- "DW_EH_PE_..." in the FSF sources */
+
+const char *
+DW_GNU_EH_PE_value_to_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x00: return "DW_GNU_EH_PE_absptr";
+    case 0x01: return "DW_GNU_EH_PE_uleb128";
+    case 0x02: return "DW_GNU_EH_PE_udata2";
+    case 0x03: return "DW_GNU_EH_PE_udata4";
+    case 0x04: return "DW_GNU_EH_PE_udata8";
+    case 0x09: return "DW_GNU_EH_PE_sleb128";
+    case 0x0a: return "DW_GNU_EH_PE_sdata2";
+    case 0x0b: return "DW_GNU_EH_PE_sdata4";
+    case 0x0c: return "DW_GNU_EH_PE_sdata8";
+    case 0x08: return "DW_GNU_EH_PE_signed";
+    case 0x10: return "DW_GNU_EH_PE_pcrel";
+    case 0x20: return "DW_GNU_EH_PE_textrel";
+    case 0x30: return "DW_GNU_EH_PE_datarel";
+    case 0x40: return "DW_GNU_EH_PE_funcrel";
+    case 0x50: return "DW_GNU_EH_PE_aligned";
+    case 0x80: return "DW_GNU_EH_PE_indirect";
+    case 0xff: return "DW_GNU_EH_PE_omit";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_GNU_EH_PE constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+const char *
+DW_GNU_EH_PE_value_to_englishy_name (uint32_t val)
+{
+  static char invalid[100];
+  switch (val) {
+    case 0x00: return "absptr";
+    case 0x01: return "uleb128";
+    case 0x02: return "udata2";
+    case 0x03: return "udata4";
+    case 0x04: return "udata8";
+    case 0x09: return "sleb128";
+    case 0x0a: return "sdata2";
+    case 0x0b: return "sdata4";
+    case 0x0c: return "sdata8";
+    case 0x08: return "signed";
+    case 0x10: return "pcrel";
+    case 0x20: return "textrel";
+    case 0x30: return "datarel";
+    case 0x40: return "funcrel";
+    case 0x50: return "aligned";
+    case 0x80: return "indirect";
+    case 0xff: return "omit";
+    default:
+       snprintf (invalid, sizeof(invalid), "Unknown DW_GNU_EH_PE constant: 0x%x", val);
+       return invalid;
+  }
+}
+
+DRC_class
+DW_GNU_EH_PE_value_to_class (uint32_t val)
+{
+  switch (val) {
+    case 0x00: return DRC_VENDOR_GNU;
+    case 0x01: return DRC_VENDOR_GNU;
+    case 0x02: return DRC_VENDOR_GNU;
+    case 0x03: return DRC_VENDOR_GNU;
+    case 0x04: return DRC_VENDOR_GNU;
+    case 0x09: return DRC_VENDOR_GNU;
+    case 0x0a: return DRC_VENDOR_GNU;
+    case 0x0b: return DRC_VENDOR_GNU;
+    case 0x0c: return DRC_VENDOR_GNU;
+    case 0x08: return DRC_VENDOR_GNU;
+    case 0x10: return DRC_VENDOR_GNU;
+    case 0x20: return DRC_VENDOR_GNU;
+    case 0x30: return DRC_VENDOR_GNU;
+    case 0x40: return DRC_VENDOR_GNU;
+    case 0x50: return DRC_VENDOR_GNU;
+    case 0x80: return DRC_VENDOR_GNU;
+    case 0xff: return DRC_VENDOR_GNU;
+    default: return 0;
+  }
+}
+
+bool
+is_type_tag (uint16_t tag)
+{
+  switch (tag)
+    {
+      case DW_TAG_array_type:
+      case DW_TAG_base_type:
+      case DW_TAG_class_type:
+      case DW_TAG_const_type:
+      case DW_TAG_enumeration_type:
+      case DW_TAG_file_type:
+      case DW_TAG_interface_type:
+      case DW_TAG_packed_type:
+      case DW_TAG_pointer_type:
+      case DW_TAG_ptr_to_member_type:
+      case DW_TAG_reference_type:
+      case DW_TAG_restrict_type:
+      case DW_TAG_set_type:
+      case DW_TAG_shared_type:
+      case DW_TAG_string_type:
+      case DW_TAG_structure_type:
+      case DW_TAG_subrange_type:
+      case DW_TAG_subroutine_type:
+      case DW_TAG_thrown_type:
+      case DW_TAG_union_type:
+      case DW_TAG_unspecified_type:
+      case DW_TAG_volatile_type:
+        return true;
+      default:
+        return false;
+    }
+}
+
+bool
+is_pubtype_tag (uint16_t tag)
+{
+  switch (tag)
+    {
+      case DW_TAG_array_type:
+      case DW_TAG_class_type:
+      case DW_TAG_enumeration_type:
+      case DW_TAG_file_type:
+      case DW_TAG_interface_type:
+      case DW_TAG_set_type:
+      case DW_TAG_string_type:
+      case DW_TAG_structure_type:
+      case DW_TAG_subrange_type:
+      case DW_TAG_subroutine_type:
+      case DW_TAG_thrown_type:
+      case DW_TAG_typedef:
+      case DW_TAG_union_type:
+      case DW_TAG_unspecified_type:
+        return true;
+      default:
+        break;
+    }
+  return false;
+}
+
+DW_TAG_CategoryEnum
+get_tag_category (uint16_t tag)
+{
+  switch (tag)
+    {
+      case DW_TAG_array_type                 : return TagCategoryType;
+      case DW_TAG_class_type                 : return TagCategoryType;
+      case DW_TAG_entry_point                : return TagCategoryProgram;
+      case DW_TAG_enumeration_type           : return TagCategoryType;
+      case DW_TAG_formal_parameter           : return TagCategoryVariable;
+      case DW_TAG_imported_declaration       : return TagCategoryProgram;
+      case DW_TAG_label                      : return TagCategoryProgram;
+      case DW_TAG_lexical_block              : return TagCategoryProgram;
+      case DW_TAG_member                     : return TagCategoryType;
+      case DW_TAG_pointer_type               : return TagCategoryType;
+      case DW_TAG_reference_type             : return TagCategoryType;
+      case DW_TAG_compile_unit               : return TagCategoryProgram;
+      case DW_TAG_string_type                : return TagCategoryType;
+      case DW_TAG_structure_type             : return TagCategoryType;
+      case DW_TAG_subroutine_type            : return TagCategoryType;
+      case DW_TAG_typedef                    : return TagCategoryType;
+      case DW_TAG_union_type                 : return TagCategoryType;
+      case DW_TAG_unspecified_parameters     : return TagCategoryVariable;
+      case DW_TAG_variant                    : return TagCategoryType;
+      case DW_TAG_common_block               : return TagCategoryProgram;
+      case DW_TAG_common_inclusion           : return TagCategoryProgram;
+      case DW_TAG_inheritance                : return TagCategoryType;
+      case DW_TAG_inlined_subroutine         : return TagCategoryProgram;
+      case DW_TAG_module                     : return TagCategoryProgram;
+      case DW_TAG_ptr_to_member_type         : return TagCategoryType;
+      case DW_TAG_set_type                   : return TagCategoryType;
+      case DW_TAG_subrange_type              : return TagCategoryType;
+      case DW_TAG_with_stmt                  : return TagCategoryProgram;
+      case DW_TAG_access_declaration         : return TagCategoryProgram;
+      case DW_TAG_base_type                  : return TagCategoryType;
+      case DW_TAG_catch_block                : return TagCategoryProgram;
+      case DW_TAG_const_type                 : return TagCategoryType;
+      case DW_TAG_constant                   : return TagCategoryVariable;
+      case DW_TAG_enumerator                 : return TagCategoryType;
+      case DW_TAG_file_type                  : return TagCategoryType;
+      case DW_TAG_friend                     : return TagCategoryType;
+      case DW_TAG_namelist                   : return TagCategoryVariable;
+      case DW_TAG_namelist_item              : return TagCategoryVariable;
+      case DW_TAG_packed_type                : return TagCategoryType;
+      case DW_TAG_subprogram                 : return TagCategoryProgram;
+      case DW_TAG_template_type_parameter    : return TagCategoryType;
+      case DW_TAG_template_value_parameter   : return TagCategoryType;
+      case DW_TAG_thrown_type                : return TagCategoryType;
+      case DW_TAG_try_block                  : return TagCategoryProgram;
+      case DW_TAG_variant_part               : return TagCategoryType;
+      case DW_TAG_variable                   : return TagCategoryVariable;
+      case DW_TAG_volatile_type              : return TagCategoryType;
+      case DW_TAG_dwarf_procedure            : return TagCategoryProgram;
+      case DW_TAG_restrict_type              : return TagCategoryType;
+      case DW_TAG_interface_type             : return TagCategoryType;
+      case DW_TAG_namespace                  : return TagCategoryProgram;
+      case DW_TAG_imported_module            : return TagCategoryProgram;
+      case DW_TAG_unspecified_type           : return TagCategoryType;
+      case DW_TAG_partial_unit               : return TagCategoryProgram;
+      case DW_TAG_imported_unit              : return TagCategoryProgram;
+      case DW_TAG_shared_type                : return TagCategoryType;
+      default: break;
+    }
+    return TagCategoryProgram;
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
new file mode 100644
index 0000000..dafe8a7
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -0,0 +1,252 @@
+//===-- DWARFDefines.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFDefines_h_
+#define liblldb_DWARFDefines_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "lldb/Core/dwarf.h"
+
+/* DWARF constants generated on Wed Sep  7 16:41:50 2005 */
+
+typedef uint32_t DRC_class;          // Holds DRC_* class bitfields
+
+/* [7.5.4] Figure 16 "Tag Encodings" (pp. 125-127) in DWARFv3 draft 8 */
+
+
+enum DW_TAG_Category
+{
+    TagCategoryVariable,
+    TagCategoryType,
+    TagCategoryProgram,
+    kNumTagCategories
+};
+
+typedef enum DW_TAG_Category DW_TAG_CategoryEnum;
+const char *DW_TAG_value_to_name (uint32_t val);
+const char *DW_TAG_value_to_englishy_name (uint32_t val);
+DRC_class DW_TAG_value_to_class (uint32_t val);
+DW_TAG_CategoryEnum get_tag_category (uint16_t tag);
+#define DW_TAG_MAX_NAME_LENGTH 31
+
+
+/* [7.5.4] Figure 17 "Child determination encodings" (p. 128) in DWARFv3 draft 8 */
+
+const char *DW_CHILDREN_value_to_name (uint8_t val);
+const char *DW_CHILDREN_value_to_englishy_name (uint8_t val);
+DRC_class DW_CHILDREN_value_to_class (uint32_t val);
+#define DW_CHILDREN_MAX_NAME_LENGTH 15
+
+
+/* [7.5.4] Figure 18 "Attribute encodings" (pp. 129-132) in DWARFv3 draft 8 */
+
+
+const char *DW_AT_value_to_name (uint32_t val);
+const char *DW_AT_value_to_englishy_name (uint32_t val);
+DRC_class DW_AT_value_to_class (uint32_t val);
+#define DW_AT_MAX_NAME_LENGTH 34
+
+
+/* [7.5.4] Figure 19 "Attribute form encodings" (pp. 133-134) in DWARFv3 draft 8 */
+
+const char *DW_FORM_value_to_name (uint32_t val);
+const char *DW_FORM_value_to_englishy_name (uint32_t val);
+DRC_class DW_FORM_value_to_class (uint32_t val);
+#define DW_FORM_MAX_NAME_LENGTH 17
+
+
+/* [7.7.1] Figure 22 "DWARF operation encodings" (pp. 136-139) in DWARFv3 draft 8 */
+
+const char *DW_OP_value_to_name (uint32_t val);
+const char *DW_OP_value_to_englishy_name (uint32_t val);
+DRC_class DW_OP_value_to_class (uint32_t val);
+#define DW_OP_MAX_NAME_LENGTH 25
+
+
+/* [7.8] Figure 23 "Base type encoding values" (pp. 140-141) in DWARFv3 draft 8 */
+
+const char *DW_ATE_value_to_name (uint32_t val);
+const char *DW_ATE_value_to_englishy_name (uint32_t val);
+DRC_class DW_ATE_value_to_class (uint32_t val);
+#define DW_ATE_MAX_NAME_LENGTH 22
+
+
+/* [7.9] Figure 24 "Accessibility encodings" (p. 141) in DWARFv3 draft 8 */
+
+const char *DW_ACCESS_value_to_name (uint32_t val);
+const char *DW_ACCESS_value_to_englishy_name (uint32_t val);
+DRC_class DW_ACCESS_value_to_class (uint32_t val);
+#define DW_ACCESS_MAX_NAME_LENGTH 19
+
+
+/* [7.10] Figure 25 "Visibility encodings" (p. 142) in DWARFv3 draft 8 */
+
+const char *DW_VIS_value_to_name (uint32_t val);
+const char *DW_VIS_value_to_englishy_name (uint32_t val);
+DRC_class DW_VIS_value_to_class (uint32_t val);
+#define DW_VIS_MAX_NAME_LENGTH 16
+
+
+/* [7.11] Figure 26 "Virtuality encodings" (p. 142) in DWARFv3 draft 8 */
+
+const char *DW_VIRTUALITY_value_to_name (uint32_t val);
+const char *DW_VIRTUALITY_value_to_englishy_name (uint32_t val);
+DRC_class DW_VIRTUALITY_value_to_class (uint32_t val);
+#define DW_VIRTUALITY_MAX_NAME_LENGTH 26
+
+
+/* [7.12] Figure 27 "Language encodings" (p. 143) in DWARFv3 draft 8 */
+
+const char *DW_LANG_value_to_name (uint32_t val);
+const char *DW_LANG_value_to_englishy_name (uint32_t val);
+DRC_class DW_LANG_value_to_class (uint32_t val);
+#define DW_LANG_MAX_NAME_LENGTH 19
+
+
+/* [7.13], "Address Class Encodings" (p. 144) in DWARFv3 draft 8 */
+
+const char *DW_ADDR_value_to_name (uint32_t val);
+const char *DW_ADDR_value_to_englishy_name (uint32_t val);
+DRC_class DW_ADDR_value_to_class (uint32_t val);
+#define DW_ADDR_MAX_NAME_LENGTH 12
+
+
+/* [7.14] Figure 28 "Identifier case encodings" (p. 144) in DWARFv3 draft 8 */
+
+const char *DW_ID_value_to_name (uint32_t val);
+const char *DW_ID_value_to_englishy_name (uint32_t val);
+DRC_class DW_ID_value_to_class (uint32_t val);
+#define DW_ID_MAX_NAME_LENGTH 22
+
+
+/* [7.15] Figure 29 "Calling convention encodings" (p. 144) in DWARFv3 draft 8 */
+
+const char *DW_CC_value_to_name (uint32_t val);
+const char *DW_CC_value_to_englishy_name (uint32_t val);
+DRC_class DW_CC_value_to_class (uint32_t val);
+#define DW_CC_MAX_NAME_LENGTH 13
+
+
+/* [7.16] Figure 30 "Inline encodings" (p. 145) in DWARFv3 draft 8 */
+
+const char *DW_INL_value_to_name (uint32_t val);
+const char *DW_INL_value_to_englishy_name (uint32_t val);
+DRC_class DW_INL_value_to_class (uint32_t val);
+#define DW_INL_MAX_NAME_LENGTH 27
+
+
+/* [7.17] Figure 31 "Ordering encodings" (p. 145) in DWARFv3 draft 8 */
+
+const char *DW_ORD_value_to_name (uint32_t val);
+const char *DW_ORD_value_to_englishy_name (uint32_t val);
+DRC_class DW_ORD_value_to_class (uint32_t val);
+#define DW_ORD_MAX_NAME_LENGTH 16
+
+
+/* [7.18] Figure 32 "Discriminant descriptor encodings" (p. 146) in DWARFv3 draft 8 */
+
+const char *DW_DSC_value_to_name (uint32_t val);
+const char *DW_DSC_value_to_englishy_name (uint32_t val);
+DRC_class DW_DSC_value_to_class (uint32_t val);
+#define DW_DSC_MAX_NAME_LENGTH 12
+
+
+/* [7.21] Figure 33 "Line Number Standard Opcode Encodings" (pp. 148-149) in DWARFv3 draft 8 */
+
+const char *DW_LNS_value_to_name (uint32_t val);
+const char *DW_LNS_value_to_englishy_name (uint32_t val);
+DRC_class DW_LNS_value_to_class (uint32_t val);
+#define DW_LNS_MAX_NAME_LENGTH 25
+
+
+/* [7.21] Figure 34 "Line Number Extended Opcode Encodings" (p. 149) in DWARFv3 draft 8 */
+
+const char *DW_LNE_value_to_name (uint32_t val);
+const char *DW_LNE_value_to_englishy_name (uint32_t val);
+DRC_class DW_LNE_value_to_class (uint32_t val);
+#define DW_LNE_MAX_NAME_LENGTH 19
+
+
+/* [7.22] Figure 35 "Macinfo Type Encodings" (p. 150) in DWARFv3 draft 8 */
+
+const char *DW_MACINFO_value_to_name (uint32_t val);
+const char *DW_MACINFO_value_to_englishy_name (uint32_t val);
+DRC_class DW_MACINFO_value_to_class (uint32_t val);
+#define DW_MACINFO_MAX_NAME_LENGTH 21
+
+
+/* [7.23] Figure 36 "Call frame instruction encodings" (pp. 151-152) in DWARFv3 draft 8 */
+
+const char *DW_CFA_value_to_name (uint32_t val);
+const char *DW_CFA_value_to_englishy_name (uint32_t val);
+DRC_class DW_CFA_value_to_class (uint32_t val);
+#define DW_CFA_MAX_NAME_LENGTH 25
+
+
+/* FSF exception handling Pointer-Encoding constants (CFI augmentation) -- "DW_EH_PE_..." in the FSF sources */
+
+const char *DW_GNU_EH_PE_value_to_name (uint32_t val);
+const char *DW_GNU_EH_PE_value_to_englishy_name (uint32_t val);
+DRC_class DW_GNU_EH_PE_value_to_class (uint32_t val);
+#define DW_GNU_EH_PE_MAX_NAME_LENGTH 21
+
+
+/* These DRC are entirely our own construction,
+    although they are derived from various comments in the DWARF standard.
+    Most of these are not useful to the parser, but the DW_AT and DW_FORM
+    classes should prove to be usable in some fashion.  */
+
+#define DRC_0x65                               0x1
+#define DRC_ADDRESS                            0x2
+#define DRC_BLOCK                              0x4
+#define DRC_CONSTANT                           0x8
+#define DRC_DWARFv3                           0x10
+#define DRC_FLAG                              0x20
+#define DRC_INDIRECT_SPECIAL                  0x40
+#define DRC_LINEPTR                           0x80
+#define DRC_LOCEXPR                          0x100
+#define DRC_LOCLISTPTR                       0x200
+#define DRC_MACPTR                           0x400
+#define DRC_ONEOPERAND                       0x800
+#define DRC_OPERANDONE_1BYTE_DELTA          0x1000
+#define DRC_OPERANDONE_2BYTE_DELTA          0x2000
+#define DRC_OPERANDONE_4BYTE_DELTA          0x4000
+#define DRC_OPERANDONE_ADDRESS              0x8000
+#define DRC_OPERANDONE_BLOCK               0x10000
+#define DRC_OPERANDONE_SLEB128_OFFSET      0x20000
+#define DRC_OPERANDONE_ULEB128_OFFSET      0x40000
+#define DRC_OPERANDONE_ULEB128_REGISTER    0x80000
+#define DRC_OPERANDTWO_BLOCK              0x100000
+#define DRC_OPERANDTWO_SLEB128_OFFSET     0x200000
+#define DRC_OPERANDTWO_ULEB128_OFFSET     0x400000
+#define DRC_OPERANDTWO_ULEB128_REGISTER   0x800000
+#define DRC_OPERNADONE_ULEB128_REGISTER  0x1000000
+#define DRC_RANGELISTPTR                 0x2000000
+#define DRC_REFERENCE                    0x4000000
+#define DRC_STRING                       0x8000000
+#define DRC_TWOOPERANDS                 0x10000000
+#define DRC_VENDOR_GNU                  0x20000000
+#define DRC_VENDOR_MIPS                 0x40000000
+#define DRC_ZEROOPERANDS                0x80000000
+
+bool is_type_tag (uint16_t tag);
+bool is_pubtype_tag (uint16_t tag);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif  // liblldb_DWARFDefines_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
new file mode 100644
index 0000000..d2c137b
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -0,0 +1,571 @@
+//===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <assert.h>
+
+#include "lldb/Core/dwarf.h"
+#include "lldb/Core/Stream.h"
+
+#include "DWARFFormValue.h"
+#include "DWARFCompileUnit.h"
+
+class DWARFCompileUnit;
+
+using namespace lldb_private;
+
+DWARFFormValue::DWARFFormValue(dw_form_t form) :
+    m_form(form),
+    m_value()
+{
+}
+
+bool
+DWARFFormValue::ExtractValue(const DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu)
+{
+    bool indirect = false;
+    bool is_block = false;
+    m_value.data = NULL;
+    // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
+    do
+    {
+        indirect = false;
+        switch (m_form)
+        {
+        case DW_FORM_addr:      m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));  break;
+        case DW_FORM_block2:    m_value.value.uval = data.GetU16(offset_ptr); is_block = true;          break;
+        case DW_FORM_block4:    m_value.value.uval = data.GetU32(offset_ptr); is_block = true;          break;
+        case DW_FORM_data2:     m_value.value.uval = data.GetU16(offset_ptr);                           break;
+        case DW_FORM_data4:     m_value.value.uval = data.GetU32(offset_ptr);                           break;
+        case DW_FORM_data8:     m_value.value.uval = data.GetU64(offset_ptr);                           break;
+        case DW_FORM_string:    m_value.value.cstr = data.GetCStr(offset_ptr);
+                                // Set the string value to also be the data for inlined cstr form values only
+                                // so we can tell the differnence between DW_FORM_string and DW_FORM_strp form
+                                // values;
+                                m_value.data = (uint8_t*)m_value.value.cstr;                            break;
+        case DW_FORM_block:     m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true;      break;
+        case DW_FORM_block1:    m_value.value.uval = data.GetU8(offset_ptr); is_block = true;           break;
+        case DW_FORM_data1:     m_value.value.uval = data.GetU8(offset_ptr);                            break;
+        case DW_FORM_flag:      m_value.value.uval = data.GetU8(offset_ptr);                            break;
+        case DW_FORM_sdata:     m_value.value.sval = data.GetSLEB128(offset_ptr);                       break;
+        case DW_FORM_strp:      m_value.value.uval = data.GetU32(offset_ptr);                           break;
+    //  case DW_FORM_APPLE_db_str:
+        case DW_FORM_udata:     m_value.value.uval = data.GetULEB128(offset_ptr);                       break;
+        case DW_FORM_ref_addr:  m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));  break;
+        case DW_FORM_ref1:      m_value.value.uval = data.GetU8(offset_ptr);                            break;
+        case DW_FORM_ref2:      m_value.value.uval = data.GetU16(offset_ptr);                           break;
+        case DW_FORM_ref4:      m_value.value.uval = data.GetU32(offset_ptr);                           break;
+        case DW_FORM_ref8:      m_value.value.uval = data.GetU64(offset_ptr);                           break;
+        case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr);                       break;
+        case DW_FORM_indirect:
+            m_form = data.GetULEB128(offset_ptr);
+            indirect = true;
+            break;
+
+        default:
+            return false;
+            break;
+        }
+    } while (indirect);
+
+    if (is_block)
+    {
+        m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
+        if (m_value.data != NULL)
+        {
+            *offset_ptr += m_value.value.uval;
+        }
+    }
+
+    return true;
+}
+
+bool
+DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu) const
+{
+    return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu);
+}
+
+bool
+DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu)
+{
+    bool indirect = false;
+    do
+    {
+        indirect = false;
+        switch (form)
+        {
+        // Blocks if inlined data that have a length field and the data bytes
+        // inlined in the .debug_info
+        case DW_FORM_block      : { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true;
+        case DW_FORM_block1     : { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);          *offset_ptr += size; } return true;
+        case DW_FORM_block2     : { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);         *offset_ptr += size; } return true;
+        case DW_FORM_block4     : { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);         *offset_ptr += size; } return true;
+
+        // Inlined NULL terminated C-strings
+        case DW_FORM_string     :
+            debug_info_data.GetCStr(offset_ptr);
+            return true;
+
+        // Compile unit address sized values
+        case DW_FORM_addr       :
+        case DW_FORM_ref_addr   :
+            *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
+            return true;
+
+        // 1 byte values
+        case DW_FORM_data1      :
+        case DW_FORM_flag       :
+        case DW_FORM_ref1       :
+            *offset_ptr += 1;
+            return true;
+
+        // 2 byte values
+        case DW_FORM_data2      :
+        case DW_FORM_ref2       :
+            *offset_ptr += 2;
+            return true;
+
+        // 4 byte values
+        case DW_FORM_strp       :
+        case DW_FORM_data4      :
+        case DW_FORM_ref4       :
+            *offset_ptr += 4;
+            return true;
+
+        // 8 byte values
+        case DW_FORM_data8      :
+        case DW_FORM_ref8       :
+            *offset_ptr += 8;
+            return true;
+
+        // signed or unsigned LEB 128 values
+    //  case DW_FORM_APPLE_db_str:
+        case DW_FORM_sdata      :
+        case DW_FORM_udata      :
+        case DW_FORM_ref_udata  :
+            debug_info_data.Skip_LEB128(offset_ptr);
+            return true;
+
+        case DW_FORM_indirect   :
+            indirect = true;
+            form = debug_info_data.GetULEB128(offset_ptr);
+            break;
+        default:
+            return false;
+        }
+    } while (indirect);
+    return true;
+}
+
+//bool
+//DWARFFormValue::PutUnsigned(dw_form_t form, dw_offset_t offset, uint64_t value, BinaryStreamBuf& out_buff, const DWARFCompileUnit* cu, bool fixup_cu_relative_refs)
+//{
+//  assert(offset != DW_INVALID_OFFSET);
+////    printf("PutUnsigned(%s, 0x%8.8x, 0x%16.16llx, %d)\n", DW_FORM_value_to_name(form), offset, value, fixup_cu_relative_refs);
+//  // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
+//  switch (form)
+//  {
+//  case DW_FORM_addr:      offset = out_buff.PutMax64(offset, value, DWARFCompileUnit::GetAddressByteSize(cu));    break;
+//
+//  case DW_FORM_flag:
+//  case DW_FORM_data1:     offset = out_buff.Put8(offset, value);                  break;
+//  case DW_FORM_data2:     offset = out_buff.Put16(offset, value);                 break;
+//  case DW_FORM_data4:     offset = out_buff.Put32(offset, value);                 break;
+//  case DW_FORM_data8:     offset = out_buff.Put64(offset, value);                 break;
+////    case DW_FORM_udata:     offset = out_buff.Put32_as_ULEB128(offset, value);      break;
+////    case DW_FORM_sdata:     offset = out_buff.Put32_as_SLEB128(offset, value);      break;
+//  case DW_FORM_strp:      offset = out_buff.Put32(offset, value);                 break;
+////    case DW_FORM_APPLE_db_str:
+////                            offset = out_buff.Put32_as_ULEB128(offset, value);      break;
+//
+//  case DW_FORM_ref1:
+//      if (fixup_cu_relative_refs) value -= cu->GetOffset();
+//      offset = out_buff.Put8(offset, value);
+//      break;
+//  case DW_FORM_ref2:
+//      if (fixup_cu_relative_refs) value -= cu->GetOffset();
+//      offset = out_buff.Put16(offset, value);
+//      break;
+//  case DW_FORM_ref4:
+//      if (fixup_cu_relative_refs) value -= cu->GetOffset();
+//      offset = out_buff.Put32(offset, value);
+//      break;
+//  case DW_FORM_ref8:
+//      if (fixup_cu_relative_refs) value -= cu->GetOffset();
+//      offset = out_buff.Put64(offset, value);
+//      break;
+////    case DW_FORM_ref_udata:
+////        if (fixup_cu_relative_refs) value -= cu->GetOffset();
+////        offset = out_buff.Put32_as_ULEB128(offset, value);
+////        break;
+//  case DW_FORM_ref_addr:
+//      // TODO: Add support for DWARF3 if we ever start emitting DWARF3. The DW_FORM_ref_addr
+//      // is always the same size as an address prior to DWARF3, and with DWARF3 or later it
+//      // is 4 hard coded to bytes.
+//      offset = out_buff.PutMax64(offset, value, DWARFCompileUnit::GetAddressByteSize(cu));
+//      break;
+//
+//  default:
+//      return false;
+//  }
+//
+//  return true;
+//}
+
+//bool
+//DWARFFormValue::TransferValue(dw_form_t form, const DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff)
+//{
+//  DWARFFormValue formValue(form);
+//  if (formValue.ExtractValue(data, offset_ptr,cu))
+//      return TransferValue(formValue, cu, out_buff);
+//  return false;
+//}
+
+//bool
+//DWARFFormValue::TransferValue(const DWARFFormValue& formValue, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff)
+//{
+//  // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
+//  dw_form_t form = formValue.Form();
+//  switch (form)
+//  {
+//  case DW_FORM_addr:
+//  case DW_FORM_ref_addr:
+//      {
+//          uint8_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu);
+//          out_buff.AppendMax64(formValue.Unsigned(), addr_size);
+//      }
+//      break;
+//
+//  case DW_FORM_block:     out_buff.Append32_as_ULEB128(formValue.Unsigned()); break;
+//  case DW_FORM_block1:    out_buff.Append8(formValue.Unsigned());             break;
+//  case DW_FORM_block2:    out_buff.Append16(formValue.Unsigned());            break;
+//  case DW_FORM_block4:    out_buff.Append32(formValue.Unsigned());            break;
+//
+//  case DW_FORM_flag:
+//  case DW_FORM_data1:     out_buff.Append8(formValue.Unsigned());             break;
+//  case DW_FORM_data2:     out_buff.Append16(formValue.Unsigned());            break;
+//  case DW_FORM_data4:     out_buff.Append32(formValue.Unsigned());            break;
+//  case DW_FORM_data8:     out_buff.Append64(formValue.Unsigned());            break;
+//  case DW_FORM_udata:     out_buff.Append32_as_ULEB128(formValue.Unsigned()); break;
+//  case DW_FORM_sdata:     out_buff.Append32_as_SLEB128(formValue.Signed());   break;
+//
+//  case DW_FORM_string:    out_buff.AppendCStr(formValue.m_value.value.cstr);      break;
+//  case DW_FORM_strp:      out_buff.Append32(formValue.Unsigned());            break;
+////    case DW_FORM_APPLE_db_str:
+////                            out_buff.Append32_as_ULEB128(formValue.Unsigned()); break;
+//
+//  case DW_FORM_ref1:      out_buff.Append8(formValue.Unsigned());             break;
+//  case DW_FORM_ref2:      out_buff.Append16(formValue.Unsigned());            break;
+//  case DW_FORM_ref4:      out_buff.Append32(formValue.Unsigned());            break;
+//  case DW_FORM_ref8:      out_buff.Append64(formValue.Unsigned());            break;
+//  case DW_FORM_ref_udata: out_buff.Append32_as_ULEB128(formValue.Unsigned()); break;
+//
+//  case DW_FORM_indirect:
+//      assert(!"DW_FORM_indirect found in DWARFFormValue::TransferValue() for an extracted form...");
+//      break;
+//
+//  default:
+//      Log::Error("DWARFFormValue::TransferValue() Unrecognized form: 0x%4.4x", form);
+//      return false;
+//      break;
+//  }
+//
+//  const uint8_t* block_data = formValue.BlockData();
+//  if (block_data)
+//      out_buff.AppendData(block_data, formValue.Unsigned());
+//  return true;
+//}
+
+void
+DWARFFormValue::Dump(Stream *s, const DataExtractor* debug_str_data, const DWARFCompileUnit* cu) const
+{
+    uint64_t uvalue = Unsigned();
+    bool cu_relative_offset = false;
+
+    bool verbose = s->GetVerbose();
+
+    switch (m_form)
+    {
+    case DW_FORM_addr:      s->Address(uvalue, sizeof (uint64_t)); break;
+    case DW_FORM_flag:
+    case DW_FORM_data1:     s->PutHex8(uvalue);     break;
+    case DW_FORM_data2:     s->PutHex16(uvalue);        break;
+    case DW_FORM_data4:     s->PutHex32(uvalue);        break;
+    case DW_FORM_data8:     s->PutHex64(uvalue);        break;
+    case DW_FORM_string:    s->QuotedCString(AsCString(NULL));          break;
+    case DW_FORM_block:
+    case DW_FORM_block1:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+        if (uvalue > 0)
+        {
+            switch (m_form)
+            {
+            case DW_FORM_block:  s->Printf("<0x%llx> ", uvalue);                break;
+            case DW_FORM_block1: s->Printf("<0x%2.2x> ", (uint8_t)uvalue);      break;
+            case DW_FORM_block2: s->Printf("<0x%4.4x> ", (uint16_t)uvalue);     break;
+            case DW_FORM_block4: s->Printf("<0x%8.8x> ", (uint32_t)uvalue);     break;
+            default:                                                            break;
+            }
+
+            const uint8_t* data_ptr = m_value.data;
+            if (data_ptr)
+            {
+                const uint8_t* end_data_ptr = data_ptr + uvalue;    // uvalue contains size of block
+                while (data_ptr < end_data_ptr)
+                {
+                    s->Printf("%2.2x ", *data_ptr);
+                    ++data_ptr;
+                }
+            }
+            else
+                s->PutCString("NULL");
+        }
+        break;
+
+    case DW_FORM_sdata:     s->PutSLEB128(uvalue); break;
+    case DW_FORM_udata:     s->PutULEB128(uvalue); break;
+    case DW_FORM_strp:
+        if (debug_str_data)
+        {
+            if (verbose)
+                s->Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
+
+            const char* dbg_str = AsCString(debug_str_data);
+            if (dbg_str)
+                s->QuotedCString(dbg_str);
+        }
+        else
+        {
+            s->PutHex32(uvalue);
+        }
+        break;
+
+    case DW_FORM_ref_addr:
+    {
+        s->Address(uvalue, sizeof (uint64_t) * 2);
+        break;
+    }
+    case DW_FORM_ref1:      cu_relative_offset = true;  if (verbose) s->Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
+    case DW_FORM_ref2:      cu_relative_offset = true;  if (verbose) s->Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
+    case DW_FORM_ref4:      cu_relative_offset = true;  if (verbose) s->Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
+    case DW_FORM_ref8:      cu_relative_offset = true;  if (verbose) s->Printf("cu + 0x%8.8llx", uvalue); break;
+    case DW_FORM_ref_udata: cu_relative_offset = true;  if (verbose) s->Printf("cu + 0x%llx", uvalue); break;
+
+    // All DW_FORM_indirect attributes should be resolved prior to calling this function
+    case DW_FORM_indirect:  s->PutCString("DW_FORM_indirect"); break;
+    default:
+        s->Printf("DW_FORM(0x%4.4x)", m_form);
+        break;
+    }
+
+    if (cu_relative_offset)
+    {
+        if (verbose)
+            s->PutCString(" => ");
+
+        s->Printf("{0x%8.8x}", (uvalue + (cu ? cu->GetOffset() : 0)));
+    }
+}
+
+const char*
+DWARFFormValue::AsCString(const DataExtractor* debug_str_data_ptr) const
+{
+    if (IsInlinedCStr())
+        return m_value.value.cstr;
+    else if (debug_str_data_ptr)
+        return debug_str_data_ptr->PeekCStr(m_value.value.uval);
+    return NULL;
+}
+
+uint64_t
+DWARFFormValue::Reference(const DWARFCompileUnit* cu) const
+{
+    uint64_t die_offset = m_value.value.uval;
+    switch (m_form)
+    {
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_udata:
+        die_offset += (cu ? cu->GetOffset() : 0);
+        break;
+
+    default:
+        break;
+    }
+
+    return die_offset;
+}
+
+//----------------------------------------------------------------------
+// Resolve any compile unit specific references so that we don't need
+// the compile unit at a later time in order to work with the form
+// value.
+//----------------------------------------------------------------------
+bool
+DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu)
+{
+    switch (m_form)
+    {
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_udata:
+        m_value.value.uval += cu->GetOffset();
+        m_form = DW_FORM_ref_addr;
+        return true;
+        break;
+
+    default:
+        break;
+    }
+
+    return false;
+}
+
+const uint8_t*
+DWARFFormValue::BlockData() const
+{
+    if (!IsInlinedCStr())
+        return m_value.data;
+    return NULL;
+}
+
+
+bool
+DWARFFormValue::IsBlockForm(const dw_form_t form)
+{
+    switch (form)
+    {
+    case DW_FORM_block:
+    case DW_FORM_block1:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+        return true;
+    }
+    return false;
+}
+
+bool
+DWARFFormValue::IsDataForm(const dw_form_t form)
+{
+    switch (form)
+    {
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+        return true;
+    }
+    return false;
+}
+
+int
+DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DataExtractor* debug_str_data_ptr)
+{
+    dw_form_t a_form = a_value.Form();
+    dw_form_t b_form = b_value.Form();
+    if (a_form < b_form)
+        return -1;
+    if (a_form > b_form)
+        return 1;
+    switch (a_form)
+    {
+    case DW_FORM_addr:
+    case DW_FORM_flag:
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+    case DW_FORM_udata:
+    case DW_FORM_ref_addr:
+        {
+            uint64_t a = a_value.Unsigned();
+            uint64_t b = b_value.Unsigned();
+            if (a < b)
+                return -1;
+            if (a > b)
+                return 1;
+            return 0;
+        }
+
+    case DW_FORM_sdata:
+        {
+            int64_t a = a_value.Signed();
+            int64_t b = b_value.Signed();
+            if (a < b)
+                return -1;
+            if (a > b)
+                return 1;
+            return 0;
+        }
+
+    case DW_FORM_string:
+    case DW_FORM_strp:
+        {
+            const char *a_string = a_value.AsCString(debug_str_data_ptr);
+            const char *b_string = b_value.AsCString(debug_str_data_ptr);
+            if (a_string == b_string)
+                return 0;
+            else if (a_string && b_string)
+                return strcmp(a_string, b_string);
+            else if (a_string == NULL)
+                return -1;  // A string is NULL, and B is valid
+            else
+                return 1;   // A string valid, and B is NULL
+        }
+
+
+    case DW_FORM_block:
+    case DW_FORM_block1:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+        {
+            uint64_t a_len = a_value.Unsigned();
+            uint64_t b_len = b_value.Unsigned();
+            if (a_len < b_len)
+                return -1;
+            if (a_len > b_len)
+                return 1;
+            // The block lengths are the same
+            return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
+        }
+        break;
+
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_udata:
+        {
+            uint64_t a = a_value.Reference(a_cu);
+            uint64_t b = b_value.Reference(b_cu);
+            if (a < b)
+                return -1;
+            if (a > b)
+                return 1;
+            return 0;
+        }
+
+    case DW_FORM_indirect:
+        assert(!"This shouldn't happen after the form has been extracted...");
+        break;
+
+    default:
+        assert(!"Unhandled DW_FORM");
+        break;
+    }
+    return -1;
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
new file mode 100644
index 0000000..3db6366
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -0,0 +1,81 @@
+//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+
+//
+//===----------------------------------------------------------------------===//
+
+ #ifndef liblldb_DWARFFormValue_h_
+ #define SymbolFileDWARF_DWARFFormValue_h_
+
+#include "SymbolFileDWARF.h"
+#include <stddef.h> // for NULL
+
+class DWARFFormValue
+{
+public:
+    typedef struct ValueTypeTag
+    {
+        ValueTypeTag() :
+            data(NULL),
+            value()
+        {
+            value.uval = 0;
+        }
+
+        union
+        {
+            uint64_t uval;
+            int64_t sval;
+            const char* cstr;
+        } value;
+        const uint8_t* data;
+    } ValueType;
+
+    enum
+    {
+        eValueTypeInvalid = 0,
+        eValueTypeUnsigned,
+        eValueTypeSigned,
+        eValueTypeCStr,
+        eValueTypeBlock
+    };
+
+    DWARFFormValue(dw_form_t form = 0);
+    dw_form_t           Form()  const { return m_form; }
+    void                SetForm(dw_form_t form) { m_form = form; }
+    const ValueType&    Value() const { return m_value; }
+    void                Dump(lldb_private::Stream *s, const lldb_private::DataExtractor* debug_str_data, const DWARFCompileUnit* cu) const;
+    bool                ExtractValue(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu);
+    bool                IsInlinedCStr() const { return (m_value.data != NULL) && m_value.data == (uint8_t*)m_value.value.cstr; }
+    const uint8_t*      BlockData() const;
+    uint64_t            Reference(const DWARFCompileUnit* cu) const;
+    bool                ResolveCompileUnitReferences(const DWARFCompileUnit* cu);
+    uint64_t            Unsigned() const { return m_value.value.uval; }
+    void                SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
+    int64_t             Signed() const { return m_value.value.sval; }
+    void                SetSigned(int64_t sval) { m_value.value.sval = sval; }
+    const char*         AsCString(const lldb_private::DataExtractor* debug_str_data_ptr) const;
+    bool                SkipValue(const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu) const;
+    static bool         SkipValue(const dw_form_t form, const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu);
+//  static bool         TransferValue(dw_form_t form, const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
+//  static bool         TransferValue(const DWARFFormValue& formValue, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
+//  static bool         PutUnsigned(dw_form_t form, dw_offset_t offset, uint64_t value, BinaryStreamBuf& out_buff, const DWARFCompileUnit* cu, bool fixup_cu_relative_refs);
+    static bool         IsBlockForm(const dw_form_t form);
+    static bool         IsDataForm(const dw_form_t form);
+
+    static int          Compare (const DWARFFormValue& a, const DWARFFormValue& b, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const lldb_private::DataExtractor* debug_str_data_ptr);
+protected:
+    dw_form_t   m_form;     // Form for this value
+    ValueType   m_value;    // Contains all data for the form
+};
+
+
+#endif  // SymbolFileDWARF_DWARFFormValue_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp b/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
new file mode 100644
index 0000000..9229c2a
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
@@ -0,0 +1,172 @@
+//===-- DWARFLocationDescription.cpp ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFLocationDescription.h"
+#include "DWARFDefines.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Stream.h"
+
+
+using namespace lldb_private;
+
+static int print_dwarf_exp_op (Stream *s, const DataExtractor& data, uint32_t* offset_ptr, int address_size, int dwarf_ref_size);
+
+int
+print_dwarf_expression (Stream *s,
+                        const DataExtractor& data,
+                        int address_size,
+                        int dwarf_ref_size,
+                        bool location_expression)
+{
+    int op_count = 0;
+    uint32_t offset = 0;
+    while (data.ValidOffset(offset))
+    {
+        if (location_expression && op_count > 0)
+        {
+            //  err (baton, "Dwarf location expressions may only have one operand!");
+            return 1;
+        }
+        if (op_count > 0)
+        {
+            s->PutCString(", ");
+        }
+        if (print_dwarf_exp_op (s, data, &offset, address_size, dwarf_ref_size) == 1)
+            return 1;
+        op_count++;
+    }
+
+    return 0;
+}
+
+static int
+print_dwarf_exp_op (Stream *s,
+                    const DataExtractor& data,
+                    uint32_t* offset_ptr,
+                    int address_size,
+                    int dwarf_ref_size)
+{
+    uint8_t opcode = data.GetU8(offset_ptr);
+    DRC_class opcode_class;
+    uint64_t  uint;
+    int64_t   sint;
+
+    int size;
+
+    opcode_class = DW_OP_value_to_class (opcode) & (~DRC_DWARFv3);
+
+    s->Printf("%s ", DW_OP_value_to_englishy_name (opcode));
+
+    /* Does this take zero parameters?  If so we can shortcut this function.  */
+    if (opcode_class == DRC_ZEROOPERANDS)
+        return 0;
+
+    if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx)
+    {
+        uint = data.GetULEB128(offset_ptr);
+        sint = data.GetSLEB128(offset_ptr);
+        s->Printf("%llu %lli", uint, sint);
+        return 0;
+    }
+    if (opcode_class != DRC_ONEOPERAND)
+    {
+        s->Printf("UNKNOWN OP %u", opcode);
+        return 1;
+    }
+
+    switch (opcode)
+    {
+        case DW_OP_addr:    size = address_size;    break;
+        case DW_OP_const1u: size = 1;               break;
+        case DW_OP_const1s: size = -1;              break;
+        case DW_OP_const2u: size = 2;               break;
+        case DW_OP_const2s: size = -2;              break;
+        case DW_OP_const4u: size = 4;               break;
+        case DW_OP_const4s: size = -4;              break;
+        case DW_OP_const8u: size = 8;               break;
+        case DW_OP_const8s: size = -8;              break;
+        case DW_OP_constu:  size = 128;             break;
+        case DW_OP_consts:  size = -128;            break;
+        case DW_OP_fbreg:   size = -128;            break;
+        case DW_OP_breg0:
+        case DW_OP_breg1:
+        case DW_OP_breg2:
+        case DW_OP_breg3:
+        case DW_OP_breg4:
+        case DW_OP_breg5:
+        case DW_OP_breg6:
+        case DW_OP_breg7:
+        case DW_OP_breg8:
+        case DW_OP_breg9:
+        case DW_OP_breg10:
+        case DW_OP_breg11:
+        case DW_OP_breg12:
+        case DW_OP_breg13:
+        case DW_OP_breg14:
+        case DW_OP_breg15:
+        case DW_OP_breg16:
+        case DW_OP_breg17:
+        case DW_OP_breg18:
+        case DW_OP_breg19:
+        case DW_OP_breg20:
+        case DW_OP_breg21:
+        case DW_OP_breg22:
+        case DW_OP_breg23:
+        case DW_OP_breg24:
+        case DW_OP_breg25:
+        case DW_OP_breg26:
+        case DW_OP_breg27:
+        case DW_OP_breg28:
+        case DW_OP_breg29:
+        case DW_OP_breg30:
+        case DW_OP_breg31:
+            size = -128; break;
+        case DW_OP_pick:
+            size = 1;       break;
+        case DW_OP_deref_size:
+            size = 1;       break;
+        case DW_OP_xderef_size:
+            size = 1;       break;
+        case DW_OP_plus_uconst:
+            size = 128;     break;
+        case DW_OP_skip:
+            size = -2;      break;
+        case DW_OP_bra:
+            size = -2;      break;
+        case DW_OP_call2:
+            size = 2;       break;
+        case DW_OP_call4:
+            size = 4;       break;
+        case DW_OP_call_ref:
+            size = dwarf_ref_size;  break;
+        case DW_OP_piece:
+            size = 128; break;
+        case DW_OP_regx:
+            size = 128; break;
+        default:
+            s->Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode);
+            return 1;
+    }
+
+    switch (size)
+    {
+    case -1:    sint = (int8_t)     data.GetU8(offset_ptr);     s->Printf("%+lli", sint); break;
+    case -2:    sint = (int16_t)    data.GetU16(offset_ptr);    s->Printf("%+lli", sint); break;
+    case -4:    sint = (int32_t)    data.GetU32(offset_ptr);    s->Printf("%+lli", sint); break;
+    case -8:    sint = (int64_t)    data.GetU64(offset_ptr);    s->Printf("%+lli", sint); break;
+    case -128:  sint = data.GetSLEB128(offset_ptr);         s->Printf("%+lli", sint); break;
+    case 1:     uint = data.GetU8(offset_ptr);                  s->Printf("0x%2.2llx", uint); break;
+    case 2:     uint = data.GetU16(offset_ptr);                 s->Printf("0x%4.4llx", uint); break;
+    case 4:     uint = data.GetU32(offset_ptr);                 s->Printf("0x%8.8llx", uint); break;
+    case 8:     uint = data.GetU64(offset_ptr);                 s->Printf("0x%16.16llx", uint); break;
+    case 128:   uint = data.GetULEB128(offset_ptr);         s->Printf("0x%llx", uint); break;
+    }
+
+    return 0;
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h b/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h
new file mode 100644
index 0000000..413a95c
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h
@@ -0,0 +1,24 @@
+//===-- DWARFLocationDescription.h ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFLocationDescription_h_
+#define SymbolFileDWARF_DWARFLocationDescription_h_
+
+#include "SymbolFileDWARF.h"
+
+int
+print_dwarf_expression (lldb_private::Stream *s,
+                        const lldb_private::DataExtractor& data,
+                        int address_size,
+                        int dwarf_ref_size,
+                        bool location_expression);
+
+
+
+#endif  // SymbolFileDWARF_DWARFLocationDescription_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp b/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp
new file mode 100644
index 0000000..6a8359d
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp
@@ -0,0 +1,89 @@
+//===-- DWARFLocationList.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFLocationList.h"
+
+#include "lldb/Core/Stream.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFLocationDescription.h"
+
+using namespace lldb_private;
+
+dw_offset_t
+DWARFLocationList::Dump(Stream *s, const DWARFCompileUnit* cu, const DataExtractor& debug_loc_data, dw_offset_t offset)
+{
+    uint64_t start_addr, end_addr;
+    uint32_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu);
+    s->SetAddressByteSize(DWARFCompileUnit::GetAddressByteSize(cu));
+    dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
+    while (debug_loc_data.ValidOffset(offset))
+    {
+        start_addr = debug_loc_data.GetMaxU64(&offset,addr_size);
+        end_addr = debug_loc_data.GetMaxU64(&offset,addr_size);
+
+        if (start_addr == 0 && end_addr == 0)
+            break;
+
+        s->PutCString("\n            ");
+        s->Indent();
+        s->AddressRange(start_addr + base_addr, end_addr + base_addr, NULL, ": ");
+        uint32_t loc_length = debug_loc_data.GetU16(&offset);
+
+        DataExtractor locationData(debug_loc_data, offset, loc_length);
+    //  if ( dump_flags & DWARFDebugInfo::eDumpFlag_Verbose ) *ostrm_ptr << " ( ";
+        print_dwarf_expression (s, locationData, addr_size, 4, false);
+        offset += loc_length;
+    }
+
+    return offset;
+}
+
+bool
+DWARFLocationList::Extract(const DataExtractor& debug_loc_data, dw_offset_t* offset_ptr, DataExtractor& location_list_data)
+{
+    // Initialize with no data just in case we don't find anything
+    location_list_data.Clear();
+
+    size_t loc_list_length = Size(debug_loc_data, *offset_ptr);
+    if (loc_list_length > 0)
+    {
+        location_list_data.SetData(debug_loc_data, *offset_ptr, loc_list_length);
+        *offset_ptr += loc_list_length;
+        return true;
+    }
+
+    return false;
+}
+
+size_t
+DWARFLocationList::Size(const DataExtractor& debug_loc_data, dw_offset_t offset)
+{
+    const dw_offset_t debug_loc_offset = offset;
+
+    while (debug_loc_data.ValidOffset(offset))
+    {
+        dw_addr_t start_addr = debug_loc_data.GetAddress(&offset);
+        dw_addr_t end_addr = debug_loc_data.GetAddress(&offset);
+
+        if (start_addr == 0 && end_addr == 0)
+            break;
+
+        uint16_t loc_length = debug_loc_data.GetU16(&offset);
+        offset += loc_length;
+    }
+
+    if (offset > debug_loc_offset)
+        return offset - debug_loc_offset;
+    return 0;
+}
+
+
+
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h b/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h
new file mode 100644
index 0000000..3efd5c4
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h
@@ -0,0 +1,34 @@
+//===-- DWARFLocationList.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFLocationList_h_
+#define SymbolFileDWARF_DWARFLocationList_h_
+
+#include "SymbolFileDWARF.h"
+
+class DWARFLocationList
+{
+public:
+    static dw_offset_t
+    Dump (lldb_private::Stream *s,
+          const DWARFCompileUnit* cu,
+          const lldb_private::DataExtractor& debug_loc_data,
+          dw_offset_t offset);
+
+    static bool
+    Extract (const lldb_private::DataExtractor& debug_loc_data,
+             dw_offset_t* offset_ptr,
+             lldb_private::DataExtractor& location_list_data);
+
+    static size_t
+    Size (const lldb_private::DataExtractor& debug_loc_data,
+          dw_offset_t offset);
+
+};
+#endif  // SymbolFileDWARF_DWARFLocationList_h_
diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
new file mode 100644
index 0000000..571271b
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
@@ -0,0 +1,207 @@
+//===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LogChannelDWARF.h"
+
+#include "lldb/Core/Args.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamFile.h"
+#include "SymbolFileDWARF.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+// when the one and only logging channel is abled, then this will be non NULL.
+static LogChannelDWARF* g_log_channel = NULL;
+
+LogChannelDWARF::LogChannelDWARF () :
+    LogChannel ()
+{
+}
+
+LogChannelDWARF::~LogChannelDWARF ()
+{
+}
+
+
+void
+LogChannelDWARF::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   LogChannelDWARF::CreateInstance);
+}
+
+void
+LogChannelDWARF::Terminate()
+{
+    PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
+}
+
+LogChannel*
+LogChannelDWARF::CreateInstance ()
+{
+    return new LogChannelDWARF ();
+}
+
+const char *
+LogChannelDWARF::GetPluginNameStatic()
+{
+    static std::string g_plugin_name;
+    if (g_plugin_name.empty())
+    {
+        g_plugin_name = SymbolFileDWARF::GetPluginNameStatic();
+        g_plugin_name += LogChannel::GetPluginSuffix ();
+    }
+    return g_plugin_name.c_str();
+}
+
+
+const char *
+LogChannelDWARF::GetPluginDescriptionStatic()
+{
+    return "DWARF log channel for debugging plug-in issues.";
+}
+
+const char *
+LogChannelDWARF::GetPluginName()
+{
+    return GetPluginDescriptionStatic();
+}
+
+const char *
+LogChannelDWARF::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+LogChannelDWARF::GetPluginVersion()
+{
+    return 1;
+}
+
+
+void
+LogChannelDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+
+Error
+LogChannelDWARF::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorStringWithFormat("No commands are supported.\n");
+    return error;
+}
+
+
+Log *
+LogChannelDWARF::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
+
+void
+LogChannelDWARF::Disable ()
+{
+    g_log_channel = NULL;
+    m_log_sp.reset();
+}
+
+bool
+LogChannelDWARF::Enable
+(
+    StreamSP &log_stream_sp,
+    uint32_t log_options,
+    Stream *feedback_strm,  // Feedback stream for argument errors etc
+    const Args &categories  // The categories to enable within this logging stream, if empty, enable default set
+)
+{
+    Disable ();
+
+    m_log_sp.reset(new Log (log_stream_sp));
+    g_log_channel = this;
+    uint32_t flag_bits = 0;
+    bool got_unknown_category = false;
+    const size_t argc = categories.GetArgumentCount();
+    for (size_t i=0; i<argc; ++i)
+    {
+        const char *arg = categories.GetArgumentAtIndex(i);
+
+        if      (::strcasecmp (arg, "all")        == 0   ) flag_bits |= DWARF_LOG_ALL;
+        else if (::strcasecmp (arg, "info")       == 0   ) flag_bits |= DWARF_LOG_DEBUG_INFO;
+        else if (::strcasecmp (arg, "line")       == 0   ) flag_bits |= DWARF_LOG_DEBUG_LINE;
+        else if (::strcasecmp (arg, "pubnames")   == 0   ) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
+        else if (::strcasecmp (arg, "pubtypes")   == 0   ) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
+        else if (::strcasecmp (arg, "default")    == 0   ) flag_bits |= DWARF_LOG_DEFAULT;
+        else
+        {
+            feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+            if (got_unknown_category == false)
+            {
+                got_unknown_category = true;
+                ListCategories (feedback_strm);
+            }
+        }
+    }
+    if (flag_bits == 0)
+        flag_bits = DWARF_LOG_DEFAULT;
+    m_log_sp->GetMask().SetAllFlagBits(flag_bits);
+    m_log_sp->GetOptions().SetAllFlagBits(log_options);
+    return m_log_sp.get() != NULL;
+}
+
+void
+LogChannelDWARF::ListCategories (Stream *strm)
+{
+    strm->Printf("Logging categories for '%s':\n"
+        "   all - turn on all available logging categories\n"
+        "   info - log the parsing if .debug_info\n"
+        "   line - log the parsing if .debug_line\n"
+        "   pubnames - log the parsing if .debug_pubnames\n"
+        "   pubtypes - log the parsing if .debug_pubtypes\n\n",
+        SymbolFileDWARF::GetPluginNameStatic());
+}
+
+Log *
+LogChannelDWARF::GetLog ()
+{
+    if (g_log_channel)
+        return g_log_channel->m_log_sp.get();
+    else
+        return NULL;
+}
+
+Log *
+LogChannelDWARF::GetLogIfAll (uint32_t mask)
+{
+    Log *log = GetLog();
+    if (log)
+        if (log->GetMask().IsSet(mask))
+            return log;
+    return NULL;
+}
+
+
+void
+LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
+{
+    if (g_log_channel)
+    {
+        LogSP log_sp(g_log_channel->m_log_sp);
+        va_list args;
+        va_start (args, format);
+        log_sp->VAPrintf (format, args);
+        va_end (args);
+    }
+}
diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
new file mode 100644
index 0000000..943d1da
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -0,0 +1,91 @@
+//===-- LogChannelDWARF.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_LogChannelDWARF_h_
+#define liblldb_LogChannelDWARF_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/Core/Log.h"
+
+#define DWARF_LOG_VERBOSE           (1u << 0)
+#define DWARF_LOG_DEBUG_INFO        (1u << 1)
+#define DWARF_LOG_DEBUG_LINE        (1u << 2)
+#define DWARF_LOG_DEBUG_PUBNAMES    (1u << 3)
+#define DWARF_LOG_DEBUG_PUBTYPES    (1u << 4)
+#define DWARF_LOG_ALL               (UINT32_MAX)
+#define DWARF_LOG_DEFAULT           (DWARF_LOG_DEBUG_INFO)
+
+class LogChannelDWARF : public lldb_private::LogChannel
+{
+public:
+    LogChannelDWARF ();
+
+    virtual
+    ~LogChannelDWARF ();
+
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static lldb_private::LogChannel *
+    CreateInstance ();
+
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+    virtual void
+    Disable ();
+
+    virtual bool
+    Enable (lldb::StreamSP &log_stream_sp,
+            uint32_t log_options,
+            lldb_private::Stream *feedback_strm,      // Feedback stream for argument errors etc
+            const lldb_private::Args &categories);    // The categories to enable within this logging stream, if empty, enable default set
+
+    virtual void
+    ListCategories (lldb_private::Stream *strm);
+
+    static lldb_private::Log *
+    GetLog ();
+
+    static lldb_private::Log *
+    GetLogIfAll (uint32_t mask);
+
+    static void
+    LogIf (uint32_t mask, const char *format, ...);
+};
+
+#endif  // liblldb_LogChannelDWARF_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
new file mode 100644
index 0000000..ffee695
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -0,0 +1,3615 @@
+//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARF.h"
+
+// Other libraries and framework includes
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Specifiers.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Core/Value.h"
+
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/VariableList.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugAbbrev.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFDebugLine.h"
+#include "DWARFDebugPubnames.h"
+#include "DWARFDebugRanges.h"
+#include "DWARFDIECollection.h"
+#include "DWARFFormValue.h"
+#include "DWARFLocationList.h"
+#include "LogChannelDWARF.h"
+
+#include <map>
+
+#define DIE_IS_BEING_PARSED ((void*)1)
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+static const ConstString&
+GetSectionNameDebugInfo()
+{
+    static const ConstString g_sect_name("__debug_info");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugAbbrev()
+{
+    static const ConstString g_sect_name ("__debug_abbrev");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugAranges()
+{
+    static const ConstString g_sect_name ("__debug_aranges");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugFrame()
+{
+    static const ConstString g_sect_name ("__debug_frame");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugLine()
+{
+    static const ConstString g_sect_name ("__debug_line");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugLoc()
+{
+    static const ConstString g_sect_name ("__debug_loc");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugMacInfo()
+{
+    static const ConstString g_sect_name ("__debug_macinfo");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugPubNames()
+{
+    static const ConstString g_sect_name ("__debug_pubnames");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugPubTypes()
+{
+    static const ConstString g_sect_name ("__debug_pubtypes");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugRanges()
+{
+    static const ConstString g_sect_name ("__debug_ranges");
+    return g_sect_name;
+}
+
+static const ConstString&
+GetSectionNameDebugStr()
+{
+    static const ConstString g_sect_name ("__debug_str");
+    return g_sect_name;
+}
+
+static uint32_t
+DwarfToClangAccessibility (uint32_t dwarf_accessibility)
+{
+    switch (dwarf_accessibility)
+    {
+        case DW_ACCESS_public:
+            return clang::AS_public;
+        case DW_ACCESS_private:
+            return clang::AS_private;
+        case DW_ACCESS_protected:
+            return clang::AS_protected;
+        default:
+            return clang::AS_none;
+    }
+}
+
+void
+SymbolFileDWARF::Initialize()
+{
+    LogChannelDWARF::Initialize();
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+SymbolFileDWARF::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+    LogChannelDWARF::Initialize();
+}
+
+
+const char *
+SymbolFileDWARF::GetPluginNameStatic()
+{
+    return "symbol-file.dwarf2";
+}
+
+const char *
+SymbolFileDWARF::GetPluginDescriptionStatic()
+{
+    return "DWARF and DWARF3 debug symbol file reader.";
+}
+
+
+SymbolFile*
+SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
+{
+    return new SymbolFileDWARF(obj_file);
+}
+
+//----------------------------------------------------------------------
+// Gets the first parent that is a lexical block, function or inlined
+// subroutine, or compile unit.
+//----------------------------------------------------------------------
+static const DWARFDebugInfoEntry *
+GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
+{
+    const DWARFDebugInfoEntry *die;
+    for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_compile_unit:
+        case DW_TAG_subprogram:
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_lexical_block:
+            return die;
+        }
+    }
+    return NULL;
+}
+
+
+SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
+    SymbolFile(ofile),
+    m_flags(),
+    m_data_debug_abbrev(),
+    m_data_debug_aranges(),
+    m_data_debug_frame(),
+    m_data_debug_info(),
+    m_data_debug_line(),
+    m_data_debug_loc(),
+    m_data_debug_macinfo(),
+    m_data_debug_pubnames(),
+    m_data_debug_pubtypes(),
+    m_data_debug_ranges(),
+    m_data_debug_str(),
+    m_abbr(),
+    m_aranges(),
+    m_info(),
+    m_line(),
+    m_name_to_function_die(),
+    m_name_to_inlined_die(),
+    m_name_to_global_die(),
+    m_name_to_type_die(),
+    m_indexed(false),
+//    m_pubnames(),
+//    m_pubtypes(),
+//    m_pubbasetypes(),
+    m_ranges()//,
+//  m_type_fixups(),
+//  m_indirect_fixups()
+{
+}
+
+SymbolFileDWARF::~SymbolFileDWARF()
+{
+}
+
+bool
+SymbolFileDWARF::SupportedVersion(uint16_t version)
+{
+    return version == 2 || version == 3;
+}
+
+uint32_t
+SymbolFileDWARF::GetAbilities ()
+{
+    uint32_t abilities = 0;
+    if (m_obj_file != NULL)
+    {
+        const Section* section = NULL;
+        const SectionList *section_list = m_obj_file->GetSectionList();
+        if (section_list == NULL)
+            return 0;
+
+        uint64_t debug_abbrev_file_size = 0;
+        uint64_t debug_aranges_file_size = 0;
+        uint64_t debug_frame_file_size = 0;
+        uint64_t debug_info_file_size = 0;
+        uint64_t debug_line_file_size = 0;
+        uint64_t debug_loc_file_size = 0;
+        uint64_t debug_macinfo_file_size = 0;
+        uint64_t debug_pubnames_file_size = 0;
+        uint64_t debug_pubtypes_file_size = 0;
+        uint64_t debug_ranges_file_size = 0;
+        uint64_t debug_str_file_size = 0;
+
+        static ConstString g_dwarf_section_name ("__DWARF");
+
+        section = section_list->FindSectionByName(g_dwarf_section_name).get();
+        
+        if (section)
+            section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
+        
+        section = section_list->FindSectionByName (GetSectionNameDebugInfo()).get();
+        if (section != NULL)
+        {
+            debug_info_file_size = section->GetByteSize();
+
+            section = section_list->FindSectionByName (GetSectionNameDebugAbbrev()).get();
+            if (section)
+                debug_abbrev_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugAbbrevData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugAranges()).get();
+            if (section)
+                debug_aranges_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugArangesData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugFrame()).get();
+            if (section)
+                debug_frame_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugFrameData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugLine()).get();
+            if (section)
+                debug_line_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugLineData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugLoc()).get();
+            if (section)
+                debug_loc_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugLocData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugMacInfo()).get();
+            if (section)
+                debug_macinfo_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugMacInfoData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugPubNames()).get();
+            if (section)
+                debug_pubnames_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugPubNamesData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugPubTypes()).get();
+            if (section)
+                debug_pubtypes_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugPubTypesData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugRanges()).get();
+            if (section)
+                debug_ranges_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugRangesData);
+
+            section = section_list->FindSectionByName (GetSectionNameDebugStr()).get();
+            if (section)
+                debug_str_file_size = section->GetByteSize();
+            else
+                m_flags.Set (flagsGotDebugStrData);
+        }
+
+        if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
+            abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
+
+        if (debug_line_file_size > 0)
+            abilities |= LineTables;
+
+        if (debug_aranges_file_size > 0)
+            abilities |= AddressAcceleratorTable;
+
+        if (debug_pubnames_file_size > 0)
+            abilities |= FunctionAcceleratorTable;
+
+        if (debug_pubtypes_file_size > 0)
+            abilities |= TypeAcceleratorTable;
+
+        if (debug_macinfo_file_size > 0)
+            abilities |= MacroInformation;
+
+        if (debug_frame_file_size > 0)
+            abilities |= CallFrameInformation;
+    }
+    return abilities;
+}
+
+const DataExtractor&
+SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, const ConstString &section_name, DataExtractor &data)
+{
+    if (m_flags.IsClear (got_flag))
+    {
+        m_flags.Set (got_flag);
+        const SectionList *section_list = m_obj_file->GetSectionList();
+        if (section_list)
+        {
+            Section *section = section_list->FindSectionByName (section_name).get();
+            if (section )
+            {
+                // See if we memory mapped the DWARF segment?
+                if (m_dwarf_data.GetByteSize())
+                {
+                    data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
+                }
+                else
+                {
+                    if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
+                        data.Clear();
+                }
+            }
+        }
+    }
+    return data;
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_abbrev_data()
+{
+    return GetCachedSectionData (flagsGotDebugAbbrevData, GetSectionNameDebugAbbrev(), m_data_debug_abbrev);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_aranges_data()
+{
+    return GetCachedSectionData (flagsGotDebugArangesData, GetSectionNameDebugAranges(), m_data_debug_aranges);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_frame_data()
+{
+    return GetCachedSectionData (flagsGotDebugFrameData, GetSectionNameDebugFrame(), m_data_debug_frame);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_info_data()
+{
+    return GetCachedSectionData (flagsGotDebugInfoData, GetSectionNameDebugInfo(), m_data_debug_info);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_line_data()
+{
+    return GetCachedSectionData (flagsGotDebugLineData, GetSectionNameDebugLine(), m_data_debug_line);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_loc_data()
+{
+    return GetCachedSectionData (flagsGotDebugLocData, GetSectionNameDebugLoc(), m_data_debug_loc);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_macinfo_data()
+{
+    return GetCachedSectionData (flagsGotDebugMacInfoData, GetSectionNameDebugMacInfo(), m_data_debug_macinfo);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_pubnames_data()
+{
+    return GetCachedSectionData (flagsGotDebugPubNamesData, GetSectionNameDebugPubNames(), m_data_debug_pubnames);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_pubtypes_data()
+{
+    return GetCachedSectionData (flagsGotDebugPubTypesData, GetSectionNameDebugPubTypes(), m_data_debug_pubtypes);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_ranges_data()
+{
+    return GetCachedSectionData (flagsGotDebugRangesData, GetSectionNameDebugRanges(), m_data_debug_ranges);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_str_data()
+{
+    return GetCachedSectionData (flagsGotDebugStrData, GetSectionNameDebugStr(), m_data_debug_str);
+}
+
+
+DWARFDebugAbbrev*
+SymbolFileDWARF::DebugAbbrev()
+{
+    if (m_abbr.get() == NULL)
+    {
+        const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
+        if (debug_abbrev_data.GetByteSize() > 0)
+        {
+            m_abbr.reset(new DWARFDebugAbbrev());
+            if (m_abbr.get())
+                m_abbr->Parse(debug_abbrev_data);
+        }
+    }
+    return m_abbr.get();
+}
+
+const DWARFDebugAbbrev*
+SymbolFileDWARF::DebugAbbrev() const
+{
+    return m_abbr.get();
+}
+
+DWARFDebugAranges*
+SymbolFileDWARF::DebugAranges()
+{
+    if (m_aranges.get() == NULL)
+    {
+        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+        m_aranges.reset(new DWARFDebugAranges());
+        if (m_aranges.get())
+        {
+            const DataExtractor &debug_aranges_data = get_debug_aranges_data();
+            if (debug_aranges_data.GetByteSize() > 0)
+                m_aranges->Extract(debug_aranges_data);
+            else
+                m_aranges->Generate(this);
+        }
+    }
+    return m_aranges.get();
+}
+
+const DWARFDebugAranges*
+SymbolFileDWARF::DebugAranges() const
+{
+    return m_aranges.get();
+}
+
+
+DWARFDebugInfo*
+SymbolFileDWARF::DebugInfo()
+{
+    if (m_info.get() == NULL)
+    {
+        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+        if (get_debug_info_data().GetByteSize() > 0)
+        {
+            m_info.reset(new DWARFDebugInfo());
+            if (m_info.get())
+            {
+                m_info->SetDwarfData(this);
+            }
+        }
+    }
+    return m_info.get();
+}
+
+const DWARFDebugInfo*
+SymbolFileDWARF::DebugInfo() const
+{
+    return m_info.get();
+}
+
+//DWARFDebugLine*
+//SymbolFileDWARF::DebugLine()
+//{
+//  if (m_line.get() == NULL)
+//  {
+//      Timer scoped_timer(__PRETTY_FUNCTION__);
+//      const DataExtractor &debug_line_data = debug_line();
+//      if (debug_line_data.GetByteSize() > 0)
+//      {
+//          m_line.reset(new DWARFDebugLine());
+//          if (m_line.get())
+//              m_line->Parse(debug_line_data);
+//      }
+//  }
+//  return m_line.get();
+//}
+//
+//const DWARFDebugLine*
+//SymbolFileDWARF::DebugLine() const
+//{
+//  return m_line.get();
+//}
+
+
+DWARFCompileUnit*
+SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
+{
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+        return info->GetCompileUnit(cu_uid).get();
+    return NULL;
+}
+
+//DWARFCompileUnit*
+//SymbolFileDWARF::GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu)
+//{
+//  DWARFCompileUnit* cu = NULL;
+//  DWARFDebugInfo* info = DebugInfo();
+//  if (info)
+//  {
+//      uint32_t cu_idx = 0;
+//      if (prev_cu != NULL)
+//      {
+//          // Find the index of the previus DWARF compile unit if one was provided
+//          while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
+//          {
+//              ++cu_idx;
+//              if (cu == prev_cu)
+//                  break;
+//          }
+//      }
+//
+//      // Now find the next unparsed DWARF compile unit. We do this by checking the
+//      // user data in the DWARFCompileUnit class that starts as NULL, and eventually
+//      // holds a pointer to the CompileUnit that was created for it after it has
+//      // been parsed.
+//      while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
+//      {
+//          if (cu->GetUserData() == NULL)
+//              break;
+//      }
+//  }
+//  return cu;
+//}
+
+DWARFDebugRanges*
+SymbolFileDWARF::DebugRanges()
+{
+    if (m_ranges.get() == NULL)
+    {
+        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+        if (get_debug_ranges_data().GetByteSize() > 0)
+        {
+            m_ranges.reset(new DWARFDebugRanges());
+            if (m_ranges.get())
+                m_ranges->Extract(this);
+        }
+    }
+    return m_ranges.get();
+}
+
+const DWARFDebugRanges*
+SymbolFileDWARF::DebugRanges() const
+{
+    return m_ranges.get();
+}
+//
+//DWARFDebugPubnames*
+//SymbolFileDWARF::DebugPubnames()
+//{
+//    if (m_pubnames.get() == NULL)
+//    {
+//        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+//        const DataExtractor &debug_pubnames_data = get_debug_pubnames_data();
+//        if (debug_pubnames_data.GetByteSize() > 0)
+//        {
+//            // Pass false to indicate this is a pubnames section
+//            m_pubnames.reset(new DWARFDebugPubnames());
+//            if (m_pubnames.get())
+//            {
+//                // "m_pubnames->GeneratePubnames" is costly, but needed for global variables
+//                m_pubnames->GeneratePubnames(this);
+//
+//#if 0
+//                StreamFile s(stdout);
+//                s.Printf (".debug_pubnames for %s/%s:\n",
+//                          m_obj_file->GetModule()->GetFileSpec().GetDirectory().AsCString(),
+//                          m_obj_file->GetModule()->GetFileSpec().GetFilename().AsCString());
+//                m_pubnames->Dump (&s);
+//#endif
+//                // "m_pubnames->Extract" is quicker, but the pubnames don't always contain what we need.
+//                //m_pubnames->Extract(debug_pubnames_data);
+//            }
+//        }
+//    }
+//    return m_pubnames.get();
+//}
+//
+//const DWARFDebugPubnames*
+//SymbolFileDWARF::DebugPubnames() const
+//{
+//    return m_pubnames.get();
+//}
+
+//DWARFDebugPubnames*
+//SymbolFileDWARF::DebugPubBaseTypes()
+//{
+//    if (m_pubbasetypes.get() == NULL)
+//    {
+//        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+//        // Pass false to indicate this is a pubnames section
+//        m_pubbasetypes.reset(new DWARFDebugPubnames());
+//        if (m_pubbasetypes.get())
+//            m_pubbasetypes->GeneratePubBaseTypes(this);
+//    }
+//    return m_pubbasetypes.get();
+//}
+//
+//const DWARFDebugPubnames*
+//SymbolFileDWARF::DebugPubBaseTypes() const
+//{
+//    return m_pubbasetypes.get();
+//}
+//
+//const DWARFDebugPubnames*
+//SymbolFileDWARF::DebugPubtypes() const
+//{
+//    return m_pubtypes.get();
+//}
+//
+//DWARFDebugPubnames*
+//SymbolFileDWARF::DebugPubtypes()
+//{
+//    if (m_pubtypes.get() == NULL)
+//    {
+//        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+//        const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data();
+//        if (debug_pubtypes_data.GetByteSize() > 0)
+//        {
+//            // Pass false to indicate this is a pubnames section
+//            m_pubtypes.reset(new DWARFDebugPubnames());
+//            if (m_pubtypes.get())
+//                m_pubtypes->Extract(debug_pubtypes_data);
+//        }
+//    }
+//    return m_pubtypes.get();
+//}
+//
+
+bool
+SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
+{
+    if (cu != NULL)
+    {
+        const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
+        if (cu_die)
+        {
+            const char * cu_die_name = cu_die->GetName(this, cu);
+            const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
+            Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
+            if (cu_die_name)
+            {
+                if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
+                {
+                    compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language));
+                }
+                else
+                {
+                    std::string fullpath(cu_comp_dir);
+                    if (*fullpath.rbegin() != '/')
+                        fullpath += '/';
+                    fullpath += cu_die_name;
+
+                    compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language));
+                }
+
+                if (compile_unit_sp.get())
+                {
+                    cu->SetUserData(compile_unit_sp.get());
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+#if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
+
+void
+SymbolFileDWARF::ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die)
+{
+    while (die != NULL)
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_base_type:
+            // Put all base types into the base type compile unit
+            fs_to_dies[base_types_fspec].Insert(die);
+            break;
+
+        default:
+            {
+                uint32_t decl_file = die->GetAttributeValueAsUnsigned(this, dw_cu, DW_AT_decl_file, 0);
+                if (decl_file)
+                {
+                    fs_to_dies[dc_cu->GetSupportFiles().GetFileSpecAtIndex(decl_file)].Insert(die);
+                }
+                else
+                {
+                    // add this to the current compile unit
+                    fs_to_dies[cu_fspec].Insert(die);
+                }
+            }
+            break;
+        }
+
+        die = die->GetSibling();
+    }
+}
+
+
+
+#endif
+
+uint32_t
+SymbolFileDWARF::GetNumCompileUnits()
+{
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+    {
+#if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
+        uint32_t cu_idx;
+        FSToDIES fs_to_dies;
+
+        FileSpec base_type_fspec("DW_TAG_base_type");
+        const uint32_t num_comp_units = info->GetNumCompileUnits();
+
+        for (cu_idx=0; cu_idx < num_comp_units; ++cu_idx)
+        {
+            DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
+            if (cu != NULL)
+            {
+                const DWARFDebugInfoEntry *cu_die = cu->DIE();
+                if (cu_die)
+                {
+                    CompUnitSP dc_cu_sp;
+                    ParseCompileUnit(cu, dc_cu_sp);
+                    if (dc_cu_sp.get())
+                    {
+                        FileSpec cu_fspec(*dc_cu_sp.get());
+
+                        ShrinkDSYM(dc_cu_sp.get(), cu, cu_fspec, base_type_fspec, fs_to_dies, cu->DIE()->GetFirstChild());
+                    }
+                }
+            }
+        }
+
+        Stream strm(stdout);
+        FSToDIES::const_iterator pos, end = fs_to_dies.end();
+        for (pos = fs_to_dies.begin(); pos != end; ++pos)
+        {
+            strm << "\n\nMinimal Compile Unit: " << pos->first << ":\n";
+            const DWARFDIECollection& dies = pos->second;
+            dies.Dump(strm, NULL);
+        }
+        return num_comp_units;
+#else
+        return info->GetNumCompileUnits();
+#endif
+    }
+    return 0;
+}
+
+CompUnitSP
+SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
+{
+    CompUnitSP comp_unit;
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+    {
+        DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
+        if (cu != NULL)
+        {
+            // Our symbol vendor shouldn't be asking us to add a compile unit that
+            // has already been added to it, which this DWARF plug-in knows as it
+            // stores the lldb compile unit (CompileUnit) pointer in each
+            // DWARFCompileUnit object when it gets added.
+            assert(cu->GetUserData() == NULL);
+            ParseCompileUnit(cu, comp_unit);
+        }
+    }
+    return comp_unit;
+}
+
+static void
+AddRangesToBlock
+(
+    BlockList& blocks,
+    lldb::user_id_t blockID,
+    DWARFDebugRanges::RangeList& ranges,
+    addr_t block_base_addr
+)
+{
+    ranges.SubtractOffset (block_base_addr);
+    size_t range_idx = 0;
+    const DWARFDebugRanges::Range *debug_range;
+    for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
+    {
+        blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset);
+    }
+}
+
+
+Function *
+SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
+{
+    DWARFDebugRanges::RangeList func_ranges;
+    const char *name = NULL;
+    const char *mangled = NULL;
+    int decl_file = 0;
+    int decl_line = 0;
+    int decl_column = 0;
+    int call_file = 0;
+    int call_line = 0;
+    int call_column = 0;
+    DWARFExpression frame_base;
+
+    // Parse the function prototype as a type that can then be added to concrete function instance
+    ParseTypes (sc, dwarf_cu, die, false, false);
+    //FixupTypes();
+
+    if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
+    {
+        // Union of all ranges in the function DIE (if the function is discontiguous)
+        AddressRange func_range;
+        lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
+        lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
+        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
+        {
+            func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
+            if (func_range.GetBaseAddress().IsValid())
+                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
+        }
+
+        if (func_range.GetBaseAddress().IsValid())
+        {
+            Mangled func_name;
+            if (mangled)
+                func_name.SetValue(mangled, true);
+            else if (name)
+                func_name.SetValue(name, false);
+
+            FunctionSP func_sp;
+            std::auto_ptr<Declaration> decl_ap;
+            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+                decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
+
+            Type *func_type = NULL;
+
+            if (die->GetUserData() != DIE_IS_BEING_PARSED)
+                func_type = (Type*)die->GetUserData();
+
+            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
+
+            func_range.GetBaseAddress().ResolveLinkedAddress();
+
+            func_sp.reset(new Function (sc.comp_unit,
+                                        die->GetOffset(),       // UserID is the DIE offset
+                                        die->GetOffset(),
+                                        func_name,
+                                        func_type,
+                                        func_range));           // first address range
+
+            if (func_sp.get() != NULL)
+            {
+                func_sp->GetFrameBaseExpression() = frame_base;
+                sc.comp_unit->AddFunction(func_sp);
+                return func_sp.get();
+            }
+        }
+    }
+    return NULL;
+}
+
+size_t
+SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
+{
+    assert (sc.comp_unit);
+    size_t functions_added = 0;
+    const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+    if (dwarf_cu)
+    {
+        DWARFDIECollection function_dies;
+        const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
+        size_t func_idx;
+        for (func_idx = 0; func_idx < num_funtions; ++func_idx)
+        {
+            const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
+            if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
+            {
+                if (ParseCompileUnitFunction(sc, dwarf_cu, die))
+                    ++functions_added;
+            }
+        }
+        //FixupTypes();
+    }
+    return functions_added;
+}
+
+bool
+SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
+{
+    assert (sc.comp_unit);
+    DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+    assert (cu);
+    const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
+
+    if (cu_die)
+    {
+        const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
+        dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+
+        // All file indexes in DWARF are one based and a file of index zero is
+        // supposed to be the compile unit itself.
+        support_files.Append (*sc.comp_unit);
+
+        return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
+    }
+    return false;
+}
+
+struct ParseDWARFLineTableCallbackInfo
+{
+    LineTable* line_table;
+    const SectionList *section_list;
+    lldb::addr_t prev_sect_file_base_addr;
+    lldb::addr_t curr_sect_file_base_addr;
+    bool is_oso_for_debug_map;
+    bool prev_in_final_executable;
+    DWARFDebugLine::Row prev_row;
+    SectionSP prev_section_sp;
+    SectionSP curr_section_sp;
+};
+
+//----------------------------------------------------------------------
+// ParseStatementTableCallback
+//----------------------------------------------------------------------
+static void
+ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
+{
+    LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
+    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
+    {
+        // Just started parsing the line table
+    }
+    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
+    {
+        // Done parsing line table, nothing to do for the cleanup
+    }
+    else
+    {
+        ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
+        // We have a new row, lets append it
+
+        if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
+        {
+            info->prev_section_sp = info->curr_section_sp;
+            info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
+            // If this is an end sequence entry, then we subtract one from the
+            // address to make sure we get an address that is not the end of
+            // a section.
+            if (state.end_sequence && state.address != 0)
+                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
+            else
+                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
+
+            if (info->curr_section_sp.get())
+                info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
+            else
+                info->curr_sect_file_base_addr = 0;
+        }
+        if (info->curr_section_sp.get())
+        {
+            lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
+            // Check for the fancy section magic to determine if we
+
+            if (info->is_oso_for_debug_map)
+            {
+                // When this is a debug map object file that contains DWARF
+                // (referenced from an N_OSO debug map nlist entry) we will have
+                // a file address in the file range for our section from the
+                // original .o file, and a load address in the executable that
+                // contains the debug map.
+                //
+                // If the sections for the file range and load range are
+                // different, we have a remapped section for the function and
+                // this address is resolved. If they are the same, then the
+                // function for this address didn't make it into the final
+                // executable.
+                bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
+
+                // If we are doing DWARF with debug map, then we need to carefully
+                // add each line table entry as there may be gaps as functions
+                // get moved around or removed.
+                if (!info->prev_row.end_sequence && info->prev_section_sp.get())
+                {
+                    if (info->prev_in_final_executable)
+                    {
+                        bool terminate_previous_entry = false;
+                        if (!curr_in_final_executable)
+                        {
+                            // Check for the case where the previous line entry
+                            // in a function made it into the final executable,
+                            // yet the current line entry falls in a function
+                            // that didn't. The line table used to be contiguous
+                            // through this address range but now it isn't. We
+                            // need to terminate the previous line entry so
+                            // that we can reconstruct the line range correctly
+                            // for it and to keep the line table correct.
+                            terminate_previous_entry = true;
+                        }
+                        else if (info->curr_section_sp.get() != info->prev_section_sp.get())
+                        {
+                            // Check for cases where the line entries used to be
+                            // contiguous address ranges, but now they aren't.
+                            // This can happen when order files specify the
+                            // ordering of the functions.
+                            lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
+                            Section *curr_sect = info->curr_section_sp.get();
+                            Section *prev_sect = info->prev_section_sp.get();
+                            assert (curr_sect->GetLinkedSection());
+                            assert (prev_sect->GetLinkedSection());
+                            lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
+                            lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
+                            lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
+                            lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
+                            if (object_file_addr_delta != linked_file_addr_delta)
+                                terminate_previous_entry = true;
+                        }
+
+                        if (terminate_previous_entry)
+                        {
+                            line_table->InsertLineEntry (info->prev_section_sp,
+                                                         state.address - info->prev_sect_file_base_addr,
+                                                         info->prev_row.line,
+                                                         info->prev_row.column,
+                                                         info->prev_row.file,
+                                                         false,                 // is_stmt
+                                                         false,                 // basic_block
+                                                         false,                 // state.prologue_end
+                                                         false,                 // state.epilogue_begin
+                                                         true);                 // end_sequence);
+                        }
+                    }
+                }
+
+                if (curr_in_final_executable)
+                {
+                    line_table->InsertLineEntry (info->curr_section_sp,
+                                                 curr_line_section_offset,
+                                                 state.line,
+                                                 state.column,
+                                                 state.file,
+                                                 state.is_stmt,
+                                                 state.basic_block,
+                                                 state.prologue_end,
+                                                 state.epilogue_begin,
+                                                 state.end_sequence);
+                    info->prev_section_sp = info->curr_section_sp;
+                }
+                else
+                {
+                    // If the current address didn't make it into the final
+                    // executable, the current section will be the __text
+                    // segment in the .o file, so we need to clear this so
+                    // we can catch the next function that did make it into
+                    // the final executable.
+                    info->prev_section_sp.reset();
+                    info->curr_section_sp.reset();
+                }
+
+                info->prev_in_final_executable = curr_in_final_executable;
+            }
+            else
+            {
+                // We are not in an object file that contains DWARF for an
+                // N_OSO, this is just a normal DWARF file. The DWARF spec
+                // guarantees that the addresses will be in increasing order
+                // so, since we store line tables in file address order, we
+                // can always just append the line entry without needing to
+                // search for the correct insertion point (we don't need to
+                // use LineEntry::InsertLineEntry()).
+                line_table->AppendLineEntry (info->curr_section_sp,
+                                             curr_line_section_offset,
+                                             state.line,
+                                             state.column,
+                                             state.file,
+                                             state.is_stmt,
+                                             state.basic_block,
+                                             state.prologue_end,
+                                             state.epilogue_begin,
+                                             state.end_sequence);
+            }
+        }
+
+        info->prev_row = state;
+    }
+}
+
+bool
+SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
+{
+    assert (sc.comp_unit);
+    if (sc.comp_unit->GetLineTable() != NULL)
+        return true;
+
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+    if (dwarf_cu)
+    {
+        const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+        const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+        if (cu_line_offset != DW_INVALID_OFFSET)
+        {
+            std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
+            if (line_table_ap.get())
+            {
+                ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false};
+                uint32_t offset = cu_line_offset;
+                DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
+                sc.comp_unit->SetLineTable(line_table_ap.release());
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+size_t
+SymbolFileDWARF::ParseFunctionBlocks
+(
+    const SymbolContext& sc,
+    lldb::user_id_t parentBlockID,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *die,
+    addr_t subprogram_low_pc,
+    bool parse_siblings,
+    bool parse_children
+)
+{
+    size_t blocks_added = 0;
+    while (die != NULL)
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_subprogram:
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_lexical_block:
+            {
+                DWARFDebugRanges::RangeList ranges;
+                const char *name = NULL;
+                const char *mangled_name = NULL;
+                BlockList& blocks = sc.function->GetBlocks(false);
+
+                lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset());
+                int decl_file = 0;
+                int decl_line = 0;
+                int decl_column = 0;
+                int call_file = 0;
+                int call_line = 0;
+                int call_column = 0;
+                if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column))
+                {
+                    if (tag == DW_TAG_subprogram)
+                    {
+                        assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
+                        subprogram_low_pc = ranges.LowestAddress(0);
+                    }
+
+                    AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc);
+
+                    if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
+                    {
+                        std::auto_ptr<Declaration> decl_ap;
+                        if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+                            decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
+
+                        std::auto_ptr<Declaration> call_ap;
+                        if (call_file != 0 || call_line != 0 || call_column != 0)
+                            call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column));
+
+                        blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get());
+                    }
+
+                    ++blocks_added;
+
+                    if (parse_children && die->HasChildren())
+                    {
+                        blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true);
+                    }
+                }
+            }
+            break;
+        default:
+            break;
+        }
+
+        if (parse_siblings)
+            die = die->GetSibling();
+        else
+            die = NULL;
+    }
+    return blocks_added;
+}
+
+size_t
+SymbolFileDWARF::ParseChildMembers
+(
+    const SymbolContext& sc,
+    TypeSP& type_sp,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die,
+    std::vector<clang::CXXBaseSpecifier *>& base_classes,
+    std::vector<int>& member_accessibilities,
+    int& default_accessibility,
+    bool &is_a_class
+)
+{
+    if (parent_die == NULL)
+        return 0;
+
+    TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
+
+    size_t count = 0;
+    const DWARFDebugInfoEntry *die;
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_member:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                if (num_attributes > 0)
+                {
+                    Declaration decl;
+                    DWARFExpression location;
+                    const char *name = NULL;
+                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+                    uint32_t accessibility = clang::AS_none;
+                    off_t member_offset = 0;
+                    size_t byte_size = 0;
+                    size_t bit_offset = 0;
+                    size_t bit_size = 0;
+                    uint32_t i;
+                    for (i=0; i<num_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
+                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
+                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
+                            case DW_AT_data_member_location:
+                                if (form_value.BlockData())
+                                {
+                                    Value initialValue(0);
+                                    Value memberOffset(0);
+                                    const DataExtractor& debug_info_data = get_debug_info_data();
+                                    uint32_t block_length = form_value.Unsigned();
+                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
+                                    {
+                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+                                    }
+                                }
+                                break;
+
+                            case DW_AT_accessibility: accessibility = DwarfToClangAccessibility (form_value.Unsigned()); break;
+                            case DW_AT_declaration:
+                            case DW_AT_description:
+                            case DW_AT_mutable:
+                            case DW_AT_visibility:
+                            default:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+
+                    Type *member_type = ResolveTypeUID(encoding_uid);
+                    assert(member_type);
+                    if (accessibility == clang::AS_none)
+                        accessibility = default_accessibility;
+                    member_accessibilities.push_back(accessibility);
+
+                    type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size);
+                }
+            }
+            break;
+
+        case DW_TAG_subprogram:
+            {
+                is_a_class = true;
+                if (default_accessibility == clang::AS_none)
+                    default_accessibility = clang::AS_private;
+                // TODO: implement DW_TAG_subprogram type parsing
+//              UserDefTypeChildInfo method_info(die->GetOffset());
+//
+//              FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
+//              if (func_sp.get() == NULL)
+//                  ParseCompileUnitFunction(sc, dwarf_cu, die);
+//
+//              method_info.SetEncodingTypeUID(die->GetOffset());
+//              struct_udt->AddMethod(method_info);
+            }
+            break;
+
+        case DW_TAG_inheritance:
+            {
+                is_a_class = true;
+                if (default_accessibility == clang::AS_none)
+                    default_accessibility = clang::AS_private;
+                // TODO: implement DW_TAG_inheritance type parsing
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                if (num_attributes > 0)
+                {
+                    Declaration decl;
+                    DWARFExpression location;
+                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+                    uint32_t accessibility = default_accessibility;
+                    bool is_virtual = false;
+                    bool is_base_of_class = true;
+                    off_t member_offset = 0;
+                    uint32_t i;
+                    for (i=0; i<num_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+                            case DW_AT_data_member_location:
+                                if (form_value.BlockData())
+                                {
+                                    Value initialValue(0);
+                                    Value memberOffset(0);
+                                    const DataExtractor& debug_info_data = get_debug_info_data();
+                                    uint32_t block_length = form_value.Unsigned();
+                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
+                                    {
+                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+                                    }
+                                }
+                                break;
+
+                            case DW_AT_accessibility:
+                                accessibility = DwarfToClangAccessibility(form_value.Unsigned());
+                                break;
+
+                            case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
+                            default:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+
+                    Type *base_class_dctype = ResolveTypeUID(encoding_uid);
+                    assert(base_class_dctype);
+                    base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
+                    assert(base_classes.back());
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+    return count;
+}
+
+
+clang::DeclContext*
+SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
+{
+    DWARFDebugInfo* debug_info = DebugInfo();
+    if (debug_info)
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
+        if (die)
+            return GetClangDeclContextForDIE (cu_sp.get(), die);
+    }
+    return NULL;
+}
+
+Type*
+SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid)
+{
+    DWARFDebugInfo* debug_info = DebugInfo();
+    if (debug_info)
+    {
+        const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL);
+        if (type_die != NULL)
+        {
+            void *type = type_die->GetUserData();
+            if (type == NULL)
+            {
+                DWARFCompileUnitSP cu_sp;
+                const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
+                if (die != NULL)
+                {
+                    TypeSP owning_type_sp;
+                    TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0));
+                }
+                type = type_die->GetUserData();
+            }
+            if (type != DIE_IS_BEING_PARSED)
+                return (Type *)type;
+        }
+    }
+    return NULL;
+}
+
+CompileUnit*
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
+{
+    // Check if the symbol vendor already knows about this compile unit?
+    if (cu->GetUserData() == NULL)
+    {
+        // The symbol vendor doesn't know about this compile unit, we
+        // need to parse and add it to the symbol vendor object.
+        CompUnitSP dc_cu;
+        ParseCompileUnit(cu, dc_cu);
+        if (dc_cu.get())
+        {
+            // Figure out the compile unit index if we weren't given one
+            if (cu_idx == UINT_MAX)
+                DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
+
+            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
+        }
+    }
+    return (CompileUnit*)cu->GetUserData();
+}
+
+bool
+SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
+{
+    sc.Clear();
+    // Check if the symbol vendor already knows about this compile unit?
+    sc.module_sp = m_obj_file->GetModule()->GetSP();
+    sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
+
+    sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
+    if (sc.function == NULL)
+        sc.function = ParseCompileUnitFunction(sc, cu, func_die);
+
+    return sc.function != NULL;
+}
+
+uint32_t
+SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
+{
+    Timer scoped_timer(__PRETTY_FUNCTION__,
+                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
+                       so_addr.GetSection(),
+                       so_addr.GetOffset(),
+                       resolve_scope);
+    uint32_t resolved = 0;
+    if (resolve_scope & (   eSymbolContextCompUnit |
+                            eSymbolContextFunction |
+                            eSymbolContextBlock |
+                            eSymbolContextLineEntry))
+    {
+        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
+
+        DWARFDebugAranges* debug_aranges = DebugAranges();
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_aranges)
+        {
+            dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
+            if (cu_offset != DW_INVALID_OFFSET)
+            {
+                uint32_t cu_idx;
+                DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
+                if (cu)
+                {
+                    sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
+                    assert(sc.comp_unit != NULL);
+                    resolved |= eSymbolContextCompUnit;
+
+                    if (resolve_scope & eSymbolContextLineEntry)
+                    {
+                        LineTable *line_table = sc.comp_unit->GetLineTable();
+                        if (line_table == NULL)
+                        {
+                            if (ParseCompileUnitLineTable(sc))
+                                line_table = sc.comp_unit->GetLineTable();
+                        }
+                        if (line_table != NULL)
+                        {
+                            if (so_addr.IsLinkedAddress())
+                            {
+                                Address linked_addr (so_addr);
+                                linked_addr.ResolveLinkedAddress();
+                                if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
+                                {
+                                    resolved |= eSymbolContextLineEntry;
+                                }
+                            }
+                            else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
+                            {
+                                resolved |= eSymbolContextLineEntry;
+                            }
+                        }
+                    }
+
+                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
+                    {
+                        DWARFDebugInfoEntry *function_die = NULL;
+                        DWARFDebugInfoEntry *block_die = NULL;
+                        if (resolve_scope & eSymbolContextBlock)
+                        {
+                            cu->LookupAddress(file_vm_addr, &function_die, &block_die);
+                        }
+                        else
+                        {
+                            cu->LookupAddress(file_vm_addr, &function_die, NULL);
+                        }
+
+                        if (function_die != NULL)
+                        {
+                            sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
+                            if (sc.function == NULL)
+                                sc.function = ParseCompileUnitFunction(sc, cu, function_die);
+                        }
+
+                        if (sc.function != NULL)
+                        {
+                            resolved |= eSymbolContextFunction;
+
+                            if (resolve_scope & eSymbolContextBlock)
+                            {
+                                BlockList& blocks = sc.function->GetBlocks(true);
+
+                                if (block_die != NULL)
+                                    sc.block = blocks.GetBlockByID(block_die->GetOffset());
+                                else
+                                    sc.block = blocks.GetBlockByID(function_die->GetOffset());
+                                if (sc.block)
+                                    resolved |= eSymbolContextBlock;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return resolved;
+}
+
+
+
+uint32_t
+SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
+{
+    const uint32_t prev_size = sc_list.GetSize();
+    if (resolve_scope & eSymbolContextCompUnit)
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_info)
+        {
+            uint32_t cu_idx;
+            DWARFCompileUnit* cu = NULL;
+
+            for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
+            {
+                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
+                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
+                if (check_inlines || file_spec_matches_cu_file_spec)
+                {
+                    SymbolContext sc (m_obj_file->GetModule());
+                    sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
+                    assert(sc.comp_unit != NULL);
+
+                    uint32_t file_idx = UINT32_MAX;
+
+                    // If we are looking for inline functions only and we don't
+                    // find it in the support files, we are done.
+                    if (check_inlines)
+                    {
+                        file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
+                        if (file_idx == UINT32_MAX)
+                            continue;
+                    }
+
+                    if (line != 0)
+                    {
+                        LineTable *line_table = sc.comp_unit->GetLineTable();
+
+                        if (line_table != NULL && line != 0)
+                        {
+                            // We will have already looked up the file index if
+                            // we are searching for inline entries.
+                            if (!check_inlines)
+                                file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
+
+                            if (file_idx != UINT32_MAX)
+                            {
+                                uint32_t found_line;
+                                uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
+                                found_line = sc.line_entry.line;
+
+                                while (line_idx != UINT_MAX)
+                                {
+                                    sc.function = NULL;
+                                    sc.block = NULL;
+                                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
+                                    {
+                                        const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
+                                        if (file_vm_addr != LLDB_INVALID_ADDRESS)
+                                        {
+                                            DWARFDebugInfoEntry *function_die = NULL;
+                                            DWARFDebugInfoEntry *block_die = NULL;
+                                            cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
+
+                                            if (function_die != NULL)
+                                            {
+                                                sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
+                                                if (sc.function == NULL)
+                                                    sc.function = ParseCompileUnitFunction(sc, cu, function_die);
+                                            }
+
+                                            if (sc.function != NULL)
+                                            {
+                                                BlockList& blocks = sc.function->GetBlocks(true);
+
+                                                if (block_die != NULL)
+                                                    sc.block = blocks.GetBlockByID(block_die->GetOffset());
+                                                else
+                                                    sc.block = blocks.GetBlockByID(function_die->GetOffset());
+                                            }
+                                        }
+                                    }
+
+                                    sc_list.Append(sc);
+                                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
+                                }
+                            }
+                        }
+                        else if (file_spec_matches_cu_file_spec && !check_inlines)
+                        {
+                            // only append the context if we aren't looking for inline call sites
+                            // by file and line and if the file spec matches that of the compile unit
+                            sc_list.Append(sc);
+                        }
+                    }
+                    else if (file_spec_matches_cu_file_spec && !check_inlines)
+                    {
+                        // only append the context if we aren't looking for inline call sites
+                        // by file and line and if the file spec matches that of the compile unit
+                        sc_list.Append(sc);
+                    }
+
+                    if (!check_inlines)
+                        break;
+                }
+            }
+        }
+    }
+    return sc_list.GetSize() - prev_size;
+}
+
+void
+SymbolFileDWARF::Index ()
+{
+    if (m_indexed)
+        return;
+    m_indexed = true;
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARF::Index (%s)",
+                        GetObjectFile()->GetFileSpec().GetFilename().AsCString());
+
+    DWARFDebugInfo* debug_info = DebugInfo();
+    if (debug_info)
+    {
+        uint32_t cu_idx = 0;
+        const uint32_t num_compile_units = GetNumCompileUnits();
+        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+        {
+            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+            bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
+
+            cu->Index (m_name_to_function_die,
+                       m_name_to_inlined_die,
+                       m_name_to_global_die, 
+                       m_name_to_type_die);  
+            
+            // Keep memory down by clearing DIEs if this generate function
+            // caused them to be parsed
+            if (clear_dies)
+                cu->ClearDIEs (true);
+        }
+        
+        m_name_to_function_die.Sort();
+        m_name_to_inlined_die.Sort();
+        m_name_to_global_die.Sort(); 
+        m_name_to_type_die.Sort();
+    }
+}
+
+uint32_t
+SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
+{
+    std::vector<dw_offset_t> die_offsets;
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        variables.Clear();
+
+    // Remember how many variables are in the list before we search in case
+    // we are appending the results to a variable list.
+    const uint32_t original_size = variables.GetSize();
+
+    // Index the DWARF if we haven't already
+    if (!m_indexed)
+        Index ();
+
+    const UniqueCStringMap<dw_offset_t>::Entry *entry;
+    
+    for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString());
+         entry != NULL;
+         entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry))
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
+        DWARFCompileUnit* cu = cu_sp.get();
+        if (die)
+        {
+            SymbolContext sc;
+            sc.module_sp = m_obj_file->GetModule()->GetSP();
+            assert (sc.module_sp);
+
+            sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
+            assert(sc.comp_unit != NULL);
+
+            ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
+
+            if (variables.GetSize() - original_size >= max_matches)
+                break;
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return variables.GetSize() - original_size;
+}
+
+uint32_t
+SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+{
+    std::vector<dw_offset_t> die_offsets;
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        variables.Clear();
+
+    // Remember how many variables are in the list before we search in case
+    // we are appending the results to a variable list.
+    const uint32_t original_size = variables.GetSize();
+
+    // Index the DWARF if we haven't already
+    if (!m_indexed)
+        Index ();
+
+    // Create the pubnames information so we can quickly lookup external symbols by name
+    const size_t num_entries = m_name_to_global_die.GetSize();
+    for (size_t i=0; i<num_entries; i++)
+    {
+        if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i)))
+            continue;
+
+        const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i);
+
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
+        DWARFCompileUnit* cu = cu_sp.get();
+        if (die)
+        {
+            SymbolContext sc;
+            sc.module_sp = m_obj_file->GetModule()->GetSP();
+            assert (sc.module_sp);
+
+
+            sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
+            assert(sc.comp_unit != NULL);
+
+            ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
+
+            if (variables.GetSize() - original_size >= max_matches)
+                break;
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return variables.GetSize() - original_size;
+}
+
+
+uint32_t
+SymbolFileDWARF::FindFunctions(const ConstString &name, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARF::FindFunctions (name = '%s')",
+                        name.AsCString());
+
+    std::vector<dw_offset_t> die_offsets;
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        sc_list.Clear();
+
+    // Remember how many sc_list are in the list before we search in case
+    // we are appending the results to a variable list.
+    uint32_t original_size = sc_list.GetSize();
+
+    // Index the DWARF if we haven't already
+    if (!m_indexed)
+        Index ();
+
+    const UniqueCStringMap<dw_offset_t>::Entry *entry;
+    
+    SymbolContext sc;
+    for (entry = m_name_to_function_die.FindFirstValueForName (name.AsCString());
+         entry != NULL;
+         entry = m_name_to_function_die.FindNextValueForName (name.AsCString(), entry))
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
+        if (die)
+        {
+            if (GetFunction (cu_sp.get(), die, sc))
+            {
+                // We found the function, so we should find the line table
+                // and line table entry as well
+                LineTable *line_table = sc.comp_unit->GetLineTable();
+                if (line_table == NULL)
+                {
+                    if (ParseCompileUnitLineTable(sc))
+                        line_table = sc.comp_unit->GetLineTable();
+                }
+                if (line_table != NULL)
+                    line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
+
+                sc_list.Append(sc);
+            }
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return sc_list.GetSize() - original_size;
+}
+
+
+uint32_t
+SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
+                        regex.GetText());
+
+    std::vector<dw_offset_t> die_offsets;
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        sc_list.Clear();
+
+    // Remember how many sc_list are in the list before we search in case
+    // we are appending the results to a variable list.
+    uint32_t original_size = sc_list.GetSize();
+
+    // Index the DWARF if we haven't already
+    if (!m_indexed)
+        Index ();
+
+    // Create the pubnames information so we can quickly lookup external symbols by name
+    // Create the pubnames information so we can quickly lookup external symbols by name
+    const size_t num_entries = m_name_to_function_die.GetSize();
+    SymbolContext sc;
+    for (size_t i=0; i<num_entries; i++)
+    {
+        if (!regex.Execute(m_name_to_function_die.GetCStringAtIndex (i)))
+            continue;
+
+        const dw_offset_t die_offset = *m_name_to_function_die.GetValueAtIndex (i);
+
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
+        if (die)
+        {
+            if (GetFunction (cu_sp.get(), die, sc))
+            {
+                // We found the function, so we should find the line table
+                // and line table entry as well
+                LineTable *line_table = sc.comp_unit->GetLineTable();
+                if (line_table == NULL)
+                {
+                    if (ParseCompileUnitLineTable(sc))
+                        line_table = sc.comp_unit->GetLineTable();
+                }
+                if (line_table != NULL)
+                    line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
+
+
+                sc_list.Append(sc);
+            }
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return sc_list.GetSize() - original_size;
+}
+
+#if 0
+uint32_t
+SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+{
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        types.Clear();
+
+    // Create the pubnames information so we can quickly lookup external symbols by name
+    DWARFDebugPubnames* pubtypes = DebugPubtypes();
+    if (pubtypes)
+    {
+        std::vector<dw_offset_t> die_offsets;
+        if (!pubtypes->Find(name.AsCString(), false, die_offsets))
+        {
+            DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
+            if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets))
+                return 0;
+        }
+        return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
+    }
+    return 0;
+}
+
+
+uint32_t
+SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+{
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        types.Clear();
+
+    // Create the pubnames information so we can quickly lookup external symbols by name
+    DWARFDebugPubnames* pubtypes = DebugPubtypes();
+    if (pubtypes)
+    {
+        std::vector<dw_offset_t> die_offsets;
+        if (!pubtypes->Find(regex, die_offsets))
+        {
+            DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
+            if (pub_base_types && !pub_base_types->Find(regex, die_offsets))
+                return 0;
+        }
+
+        return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
+    }
+
+    return 0;
+}
+
+
+
+uint32_t
+SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+{
+    // Remember how many sc_list are in the list before we search in case
+    // we are appending the results to a variable list.
+    uint32_t original_size = types.Size();
+
+    const uint32_t num_die_offsets = die_offsets.size();
+    // Parse all of the types we found from the pubtypes matches
+    uint32_t i;
+    uint32_t num_matches = 0;
+    for (i = 0; i < num_die_offsets; ++i)
+    {
+        dw_offset_t die_offset = die_offsets[i];
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
+
+        assert(die != NULL);
+
+        bool get_type_for_die = true;
+        if (encoding)
+        {
+            // Check if this type has already been uniqued and registers with the module?
+            Type* type = (Type*)die->GetUserData();
+            if (type != NULL && type != DIE_IS_BEING_PARSED)
+            {
+                get_type_for_die = type->GetEncoding() == encoding;
+            }
+            else
+            {
+                dw_tag_t tag = die->Tag();
+                switch (encoding)
+                {
+                case Type::address:
+                case Type::boolean:
+                case Type::complex_float:
+                case Type::float_type:
+                case Type::signed_int:
+                case Type::signed_char:
+                case Type::unsigned_int:
+                case Type::unsigned_char:
+                case Type::imaginary_float:
+                case Type::packed_decimal:
+                case Type::numeric_string:
+                case Type::edited_string:
+                case Type::signed_fixed:
+                case Type::unsigned_fixed:
+                case Type::decimal_float:
+                    if (tag != DW_TAG_base_type)
+                        get_type_for_die = false;
+                    else
+                    {
+                        if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding)
+                            get_type_for_die = false;
+                    }
+                    break;
+
+                case Type::indirect_const:      get_type_for_die = tag == DW_TAG_const_type; break;
+                case Type::indirect_restrict:       get_type_for_die = tag == DW_TAG_restrict_type; break;
+                case Type::indirect_volatile:       get_type_for_die = tag == DW_TAG_volatile_type; break;
+                case Type::indirect_typedef:        get_type_for_die = tag == DW_TAG_typedef; break;
+                case Type::indirect_pointer:        get_type_for_die = tag == DW_TAG_pointer_type; break;
+                case Type::indirect_reference:  get_type_for_die = tag == DW_TAG_reference_type; break;
+
+                case Type::user_defined_type:
+                    switch (tag)
+                    {
+                    case DW_TAG_array_type:
+                        get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid);
+                        break;
+
+                    case DW_TAG_structure_type:
+                    case DW_TAG_union_type:
+                    case DW_TAG_class_type:
+                        get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid);
+                        break;
+
+                    case DW_TAG_enumeration_type:
+                        get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid);
+                        break;
+
+                    case DW_TAG_subprogram:
+                    case DW_TAG_subroutine_type:
+                        get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid);
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (get_type_for_die)
+        {
+            TypeSP owning_type_sp;
+            TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0));
+
+            if (type_sp.get())
+            {
+                // See if we are filtering results based on encoding?
+                bool add_type = (encoding == Type::invalid);
+                if (!add_type)
+                {
+                    // We are filtering base on encoding, so lets check the resulting type encoding
+                    add_type = (encoding == type_sp->GetEncoding());
+                    if (add_type)
+                    {
+                        // The type encoding matches, if this is a user defined type, lets
+                        // make sure the exact user define type uid matches if one was provided
+                        if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID)
+                        {
+                            UserDefType* udt = type_sp->GetUserDefinedType().get();
+                            if (udt)
+                                add_type = udt->UserDefinedTypeUID() == udt_uid;
+                        }
+                    }
+                }
+                // Add the type to our list as long as everything matched
+                if (add_type)
+                {
+                    types.InsertUnique(type_sp);
+                    if (++num_matches >= max_matches)
+                        break;
+                }
+            }
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return types.Size() - original_size;
+}
+
+#endif
+
+
+size_t
+SymbolFileDWARF::ParseChildParameters
+(
+    const SymbolContext& sc,
+    TypeSP& type_sp,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die,
+    TypeList* type_list,
+    std::vector<void *>& function_param_types,
+    std::vector<clang::ParmVarDecl*>& function_param_decls
+)
+{
+    if (parent_die == NULL)
+        return 0;
+
+    size_t count = 0;
+    const DWARFDebugInfoEntry *die;
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        dw_tag_t tag = die->Tag();
+        switch (tag)
+        {
+        case DW_TAG_formal_parameter:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                if (num_attributes > 0)
+                {
+                    const char *name = NULL;
+                    Declaration decl;
+                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
+                    // one of None, Auto, Register, Extern, Static, PrivateExtern
+
+                    clang::VarDecl::StorageClass storage = clang::VarDecl::None;
+                    uint32_t i;
+                    for (i=0; i<num_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
+                            case DW_AT_location:
+    //                          if (form_value.BlockData())
+    //                          {
+    //                              const DataExtractor& debug_info_data = debug_info();
+    //                              uint32_t block_length = form_value.Unsigned();
+    //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
+    //                          }
+    //                          else
+    //                          {
+    //                          }
+    //                          break;
+                            case DW_AT_artificial:
+                            case DW_AT_const_value:
+                            case DW_AT_default_value:
+                            case DW_AT_description:
+                            case DW_AT_endianity:
+                            case DW_AT_is_optional:
+                            case DW_AT_segment:
+                            case DW_AT_variable_parameter:
+                            default:
+                            case DW_AT_abstract_origin:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+                    Type *dc_type = ResolveTypeUID(param_type_die_offset);
+                    if (dc_type)
+                    {
+                        function_param_types.push_back (dc_type->GetOpaqueClangQualType());
+
+                        clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
+                        assert(param_var_decl);
+                        function_param_decls.push_back(param_var_decl);
+                    }
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+    return count;
+}
+
+size_t
+SymbolFileDWARF::ParseChildEnumerators
+(
+    const SymbolContext& sc,
+    TypeSP& type_sp,
+    void * enumerator_qual_type,
+    uint32_t enumerator_byte_size,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die
+)
+{
+    if (parent_die == NULL)
+        return 0;
+
+    size_t enumerators_added = 0;
+    const DWARFDebugInfoEntry *die;
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        const dw_tag_t tag = die->Tag();
+        if (tag == DW_TAG_enumerator)
+        {
+            DWARFDebugInfoEntry::Attributes attributes;
+            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+            if (num_child_attributes > 0)
+            {
+                const char *name = NULL;
+                bool got_value = false;
+                int64_t enum_value = 0;
+                Declaration decl;
+
+                uint32_t i;
+                for (i=0; i<num_child_attributes; ++i)
+                {
+                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                    DWARFFormValue form_value;
+                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                    {
+                        switch (attr)
+                        {
+                        case DW_AT_const_value:
+                            got_value = true;
+                            enum_value = form_value.Unsigned();
+                            break;
+
+                        case DW_AT_name:
+                            name = form_value.AsCString(&get_debug_str_data());
+                            break;
+
+                        case DW_AT_description:
+                        default:
+                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                        case DW_AT_sibling:
+                            break;
+                        }
+                    }
+                }
+
+                if (name && name[0] && got_value)
+                {
+                    TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
+                    type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8);
+                    ++enumerators_added;
+                }
+            }
+        }
+    }
+    return enumerators_added;
+}
+
+void
+SymbolFileDWARF::ParseChildArrayInfo
+(
+    const SymbolContext& sc,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die,
+    int64_t& first_index,
+    std::vector<uint64_t>& element_orders,
+    uint32_t& byte_stride,
+    uint32_t& bit_stride
+)
+{
+    if (parent_die == NULL)
+        return;
+
+    const DWARFDebugInfoEntry *die;
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        const dw_tag_t tag = die->Tag();
+        switch (tag)
+        {
+        case DW_TAG_enumerator:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                if (num_child_attributes > 0)
+                {
+                    const char *name = NULL;
+                    bool got_value = false;
+                    int64_t enum_value = 0;
+
+                    uint32_t i;
+                    for (i=0; i<num_child_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_const_value:
+                                got_value = true;
+                                enum_value = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_name:
+                                name = form_value.AsCString(&get_debug_str_data());
+                                break;
+
+                            case DW_AT_description:
+                            default:
+                            case DW_AT_decl_file:
+                            case DW_AT_decl_line:
+                            case DW_AT_decl_column:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+
+        case DW_TAG_subrange_type:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                if (num_child_attributes > 0)
+                {
+                    const char *name = NULL;
+                    bool got_value = false;
+                    uint64_t byte_size = 0;
+                    int64_t enum_value = 0;
+                    uint64_t num_elements = 0;
+                    uint64_t lower_bound = 0;
+                    uint64_t upper_bound = 0;
+                    uint32_t i;
+                    for (i=0; i<num_child_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_const_value:
+                                got_value = true;
+                                enum_value = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_name:
+                                name = form_value.AsCString(&get_debug_str_data());
+                                break;
+
+                            case DW_AT_count:
+                                num_elements = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_bit_stride:
+                                bit_stride = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_byte_stride:
+                                byte_stride = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_byte_size:
+                                byte_size = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_lower_bound:
+                                lower_bound = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_upper_bound:
+                                upper_bound = form_value.Unsigned();
+                                break;
+
+                            default:
+                                //printf("0x%8.8x: %-30s skipping attribute at 0x%8.8x: %s\n", die->GetOffset(), DW_TAG_value_to_name(tag), attributes.die_offsets[i], DW_AT_value_to_name(attr));  // remove this, debug only
+
+                            case DW_AT_abstract_origin:
+                            case DW_AT_accessibility:
+                            case DW_AT_allocated:
+                            case DW_AT_associated:
+                            case DW_AT_data_location:
+                            case DW_AT_declaration:
+                            case DW_AT_description:
+                            case DW_AT_sibling:
+                            case DW_AT_threads_scaled:
+                            case DW_AT_type:
+                            case DW_AT_visibility:
+                                break;
+                            }
+                        }
+                    }
+
+                    if (upper_bound > lower_bound)
+                        num_elements = upper_bound - lower_bound + 1;
+
+                    if (num_elements > 0)
+                        element_orders.push_back (num_elements);
+                }
+            }
+            break;
+        }
+    }
+}
+
+Type*
+SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe)
+{
+    if (type_die_offset != DW_INVALID_OFFSET)
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp);
+        assert(type_die != NULL);
+        GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx);
+        // Return the uniqued type if there is one
+        Type* type = (Type*)type_die->GetUserData();
+        if (type == DIE_IS_BEING_PARSED && safe)
+            return NULL;
+        return type;
+    }
+    return NULL;
+}
+
+TypeSP
+SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx)
+{
+    TypeSP type_sp;
+    if (die != NULL)
+    {
+        assert(cu != NULL);
+        Type *type_ptr = (Type *)die->GetUserData();
+        if (type_ptr == NULL)
+        {
+            SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
+            bool type_is_new = false;
+            type_sp = ParseType(sc, cu, die, type_is_new);
+            type_ptr = (Type *)die->GetUserData();
+            if (owning_type_sp.get() == NULL)
+                owning_type_sp = type_sp;
+        }
+        else if (type_ptr != DIE_IS_BEING_PARSED)
+        {
+            // Grab the existing type from the master types lists
+            type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
+        }
+
+    }
+    return type_sp;
+}
+
+clang::DeclContext *
+SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
+{
+    if (die_offset != DW_INVALID_OFFSET)
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
+        return GetClangDeclContextForDIE (cu_sp.get(), die);
+    }
+    return NULL;
+}
+
+
+
+clang::DeclContext *
+SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+{
+    DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
+    if (pos != m_die_to_decl_ctx.end())
+        return pos->second;
+
+    while (die != NULL)
+    {
+        switch (die->Tag())
+        {
+        case DW_TAG_namespace:
+            {
+                const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
+                if (namespace_name)
+                {
+                    TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
+                    assert(type_list);
+                    Declaration decl;   // TODO: fill in the decl object
+                    clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
+                    if (namespace_decl)
+                        m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
+                    return namespace_decl;
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+        clang::DeclContext *decl_ctx;
+        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
+        if (decl_ctx)
+            return decl_ctx;
+
+        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
+        if (decl_ctx)
+            return decl_ctx;
+
+        die = die->GetParent();
+    }
+    return NULL;
+}
+
+TypeSP
+SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
+{
+    TypeSP type_sp;
+
+    uint32_t accessibility = clang::AS_none;
+    if (die != NULL)
+    {
+        dw_tag_t tag = die->Tag();
+        if (die->GetUserData() == NULL)
+        {
+            type_is_new = true;
+
+            bool is_forward_declaration = false;
+            DWARFDebugInfoEntry::Attributes attributes;
+            const char *type_name_cstr = NULL;
+            ConstString type_name_dbstr;
+            Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
+            void *clang_type = NULL;
+
+            TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
+            dw_attr_t attr;
+
+            switch (tag)
+            {
+            case DW_TAG_base_type:
+            case DW_TAG_pointer_type:
+            case DW_TAG_reference_type:
+            case DW_TAG_typedef:
+            case DW_TAG_const_type:
+            case DW_TAG_restrict_type:
+            case DW_TAG_volatile_type:
+                {
+                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
+                    // Set a bit that lets us know that we are currently parsing this
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                    Declaration decl;
+                    uint32_t encoding = 0;
+                    size_t byte_size = 0;
+                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_dbstr.SetCString(type_name_cstr);
+                                    break;
+                                case DW_AT_byte_size:   byte_size = form_value.Unsigned();  break;
+                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
+                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+                                default:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    switch (tag)
+                    {
+                    default:
+                    case DW_TAG_base_type:
+                        clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
+                        break;
+
+                    case DW_TAG_pointer_type:
+                        // The encoding_uid will be embedded into the
+                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
+                        encoding_uid_type = Type::ePointerToTypeWithUID;
+                        break;
+
+                    case DW_TAG_reference_type:
+                        // The encoding_uid will be embedded into the
+                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
+                        encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
+                        break;
+
+                    case DW_TAG_typedef:
+                        // The encoding_uid will be embedded into the
+                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
+                        encoding_uid_type = Type::eTypedefToTypeWithUID;
+                        break;
+
+                    case DW_TAG_const_type:
+                        // The encoding_uid will be embedded into the
+                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
+                        encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
+                        break;
+
+                    case DW_TAG_restrict_type:
+                        // The encoding_uid will be embedded into the
+                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
+                        encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
+                        break;
+
+                    case DW_TAG_volatile_type:
+                        // The encoding_uid will be embedded into the
+                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
+                        encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
+                        break;
+                    }
+
+                    type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
+
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
+
+
+//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
+//                  if (encoding_type != NULL)
+//                  {
+//                      if (encoding_type != DIE_IS_BEING_PARSED)
+//                          type_sp->SetEncodingType(encoding_type);
+//                      else
+//                          m_indirect_fixups.push_back(type_sp.get());
+//                  }
+                }
+                break;
+
+            case DW_TAG_structure_type:
+            case DW_TAG_union_type:
+            case DW_TAG_class_type:
+                {
+                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
+                    // Set a bit that lets us know that we are currently parsing this
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
+
+                    size_t byte_size = 0;
+                    //bool struct_is_class = false;
+                    Declaration decl;
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_dbstr.SetCString(type_name_cstr);
+                                    break;
+                                case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
+                                case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; break;
+                                case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_data_location:
+                                case DW_AT_description:
+                                case DW_AT_start_scope:
+                                case DW_AT_visibility:
+                                default:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    int tag_decl_kind = -1;
+                    int default_accessibility = clang::AS_none;
+                    if (tag == DW_TAG_structure_type)
+                    {
+                        tag_decl_kind = clang::TTK_Struct;
+                        default_accessibility = clang::AS_public;
+                    }
+                    else if (tag == DW_TAG_union_type)
+                    {
+                        tag_decl_kind = clang::TTK_Union;
+                        default_accessibility = clang::AS_public;
+                    }
+                    else if (tag == DW_TAG_class_type)
+                    {
+                        tag_decl_kind = clang::TTK_Class;
+                        default_accessibility = clang::AS_private;
+                    }
+
+                    assert (tag_decl_kind != -1);
+                    clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die));
+
+                    m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
+                    type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
+
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
+
+//                  assert(type_sp.get());
+//                  if (accessibility)
+//                      type_sp->SetAccess(accessibility);
+//
+                    type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
+                    if (die->HasChildren())
+                    {
+                        std::vector<clang::CXXBaseSpecifier *> base_classes;
+                        std::vector<int> member_accessibilities;
+                        bool is_a_class = false;
+                        ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class);
+                        // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
+                        // need to tell the clang type it is actually a class.
+                        if (is_a_class && tag_decl_kind != clang::TTK_Class)
+                            type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
+
+                        // Since DW_TAG_structure_type gets used for both classes
+                        // and structures, we may need to set any DW_TAG_member
+                        // fields to have a "private" access if none was specified.
+                        // When we parsed the child members we tracked that actual
+                        // accessibility value for each DW_TAG_member in the
+                        // "member_accessibilities" array. If the value for the
+                        // member is zero, then it was set to the "default_accessibility"
+                        // which for structs was "public". Below we correct this
+                        // by setting any fields to "private" that weren't correctly
+                        // set.
+                        if (is_a_class && !member_accessibilities.empty())
+                        {
+                            // This is a class and all members that didn't have
+                            // their access specified are private.
+                            type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, clang::AS_private, member_accessibilities.data(), member_accessibilities.size());
+                        }
+
+                        if (!base_classes.empty())
+                        {
+                            type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, base_classes.data(), base_classes.size());
+                        }
+                    }
+                    type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
+                }
+                break;
+
+            case DW_TAG_enumeration_type:
+                {
+                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
+                    // Set a bit that lets us know that we are currently parsing this
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
+
+                    size_t byte_size = 0;
+                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
+                    Declaration decl;
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_dbstr.SetCString(type_name_cstr);
+                                    break;
+                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+                                case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
+                                case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
+                                case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_bit_stride:
+                                case DW_AT_byte_stride:
+                                case DW_AT_data_location:
+                                case DW_AT_description:
+                                case DW_AT_start_scope:
+                                case DW_AT_visibility:
+                                case DW_AT_specification:
+                                case DW_AT_abstract_origin:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+
+                        clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr);
+                        m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
+                        type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
+
+                        const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
+
+                        if (die->HasChildren())
+                        {
+                            type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
+                            void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
+                            ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die);
+                            type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
+                        }
+                    }
+                }
+                break;
+
+            case DW_TAG_subprogram:
+            case DW_TAG_subroutine_type:
+                {
+                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
+                    // Set a bit that lets us know that we are currently parsing this
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
+
+                    const char *mangled = NULL;
+                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
+                    Declaration decl;
+                    bool isVariadic = false;
+                    bool is_inline = false;
+                    unsigned type_quals = 0;
+                    clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
+
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_dbstr.SetCString(type_name_cstr);
+                                    break;
+
+                                case DW_AT_MIPS_linkage_name:   mangled = form_value.AsCString(&get_debug_str_data()); break;
+                                case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
+                                case DW_AT_accessibility:       accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
+                                case DW_AT_declaration:         is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_external:
+                                    if (form_value.Unsigned())
+                                    {
+                                        if (storage == clang::FunctionDecl::None)
+                                            storage = clang::FunctionDecl::Extern;
+                                        else
+                                            storage = clang::FunctionDecl::PrivateExtern;
+                                    }
+                                    break;
+                                case DW_AT_inline:
+                                    is_inline = form_value.Unsigned() != 0;
+                                    break;
+
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_address_class:
+                                case DW_AT_artificial:
+                                case DW_AT_calling_convention:
+                                case DW_AT_data_location:
+                                case DW_AT_elemental:
+                                case DW_AT_entry_pc:
+                                case DW_AT_explicit:
+                                case DW_AT_frame_base:
+                                case DW_AT_high_pc:
+                                case DW_AT_low_pc:
+                                case DW_AT_object_pointer:
+                                case DW_AT_prototyped:
+                                case DW_AT_pure:
+                                case DW_AT_ranges:
+                                case DW_AT_recursive:
+                                case DW_AT_return_addr:
+                                case DW_AT_segment:
+                                case DW_AT_specification:
+                                case DW_AT_start_scope:
+                                case DW_AT_static_link:
+                                case DW_AT_trampoline:
+                                case DW_AT_visibility:
+                                case DW_AT_virtuality:
+                                case DW_AT_vtable_elem_location:
+                                case DW_AT_abstract_origin:
+                                case DW_AT_description:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+
+                        void *return_clang_type = NULL;
+                        Type *func_type = ResolveTypeUID(type_die_offset);
+                        if (func_type)
+                            return_clang_type = func_type->GetOpaqueClangQualType();
+                        else
+                            return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType();
+
+                        std::vector<void *> function_param_types;
+                        std::vector<clang::ParmVarDecl*> function_param_decls;
+
+                        // Parse the function children for the parameters
+                        ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
+
+                        clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
+                        if (type_name_cstr)
+                        {
+                            clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
+                            // Add the decl to our DIE to decl context map
+                            assert (function_decl);
+                            m_die_to_decl_ctx[die] = function_decl;
+                            if (!function_param_decls.empty())
+                                type_list->GetClangASTContext().SetFunctionParameters (function_decl, function_param_decls.data(), function_param_decls.size());
+                        }
+                        type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
+
+                        const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
+                        assert(type_sp.get());
+                    }
+                }
+                break;
+
+            case DW_TAG_array_type:
+                {
+                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
+                    // Set a bit that lets us know that we are currently parsing this
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
+
+                    size_t byte_size = 0;
+                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
+                    Declaration decl;
+                    int64_t first_index = 0;
+                    uint32_t byte_stride = 0;
+                    uint32_t bit_stride = 0;
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_dbstr.SetCString(type_name_cstr);
+                                    break;
+
+                                case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
+                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
+                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
+                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
+                                case DW_AT_accessibility:   accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
+                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_data_location:
+                                case DW_AT_description:
+                                case DW_AT_ordering:
+                                case DW_AT_start_scope:
+                                case DW_AT_visibility:
+                                case DW_AT_specification:
+                                case DW_AT_abstract_origin:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+
+                        Type *element_type = ResolveTypeUID(type_die_offset);
+
+                        if (element_type)
+                        {
+                            std::vector<uint64_t> element_orders;
+                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
+                            if (byte_stride == 0 && bit_stride == 0)
+                                byte_stride = element_type->GetByteSize();
+                            void *array_element_type = element_type->GetOpaqueClangQualType();
+                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
+                            uint64_t num_elements = 0;
+                            std::vector<uint64_t>::const_reverse_iterator pos;
+                            std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
+                            for (pos = element_orders.rbegin(); pos != end; ++pos)
+                            {
+                                num_elements = *pos;
+                                clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
+                                array_element_type = clang_type;
+                                array_element_bit_stride = array_element_bit_stride * num_elements;
+                            }
+                            ConstString empty_name;
+                            type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
+                            const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
+                        }
+                    }
+                }
+                break;
+
+            default:
+                break;
+            }
+
+            if (type_sp.get())
+            {
+                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
+                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+
+                SymbolContextScope * symbol_context_scope = NULL;
+                if (sc_parent_tag == DW_TAG_compile_unit)
+                {
+                    symbol_context_scope = sc.comp_unit;
+                }
+                else if (sc.function != NULL)
+                {
+                    symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
+                    if (symbol_context_scope == NULL)
+                        symbol_context_scope = sc.function;
+                }
+
+                if (symbol_context_scope != NULL)
+                {
+                    type_sp->SetSymbolContextScope(symbol_context_scope);
+                }
+
+//              if (udt_sp.get())
+//              {
+//                  if (is_forward_declaration)
+//                      udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
+//                  type_sp->SetUserDefinedType(udt_sp);
+//              }
+
+                if (type_sp.unique())
+                {
+                    // We are ready to put this type into the uniqued list up at the module level
+                    TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
+
+                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get());
+
+                    type_sp = uniqued_type_sp;
+                }
+            }
+        }
+        else
+        {
+            switch (tag)
+            {
+            case DW_TAG_base_type:
+            case DW_TAG_pointer_type:
+            case DW_TAG_reference_type:
+            case DW_TAG_typedef:
+            case DW_TAG_const_type:
+            case DW_TAG_restrict_type:
+            case DW_TAG_volatile_type:
+            case DW_TAG_structure_type:
+            case DW_TAG_union_type:
+            case DW_TAG_class_type:
+            case DW_TAG_enumeration_type:
+            case DW_TAG_subprogram:
+            case DW_TAG_subroutine_type:
+            case DW_TAG_array_type:
+                {
+                    Type *existing_type = (Type*)die->GetUserData();
+                    if (existing_type != DIE_IS_BEING_PARSED)
+                    {
+                        type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID());
+                    }
+                }
+                break;
+            default:
+                //assert(!"invalid type tag...");
+                break;
+            }
+        }
+    }
+    return type_sp;
+}
+
+size_t
+SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
+{
+    size_t types_added = 0;
+    while (die != NULL)
+    {
+        bool type_is_new = false;
+        if (ParseType(sc, dwarf_cu, die, type_is_new).get())
+        {
+            if (type_is_new)
+                ++types_added;
+        }
+
+        if (parse_children && die->HasChildren())
+        {
+            if (die->Tag() == DW_TAG_subprogram)
+            {
+                SymbolContext child_sc(sc);
+                child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
+                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
+            }
+            else
+                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
+        }
+
+        if (parse_siblings)
+            die = die->GetSibling();
+        else
+            die = NULL;
+    }
+    return types_added;
+}
+
+
+size_t
+SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
+{
+    assert(sc.comp_unit && sc.function);
+    size_t functions_added = 0;
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+    if (dwarf_cu)
+    {
+        dw_offset_t function_die_offset = sc.function->GetID();
+        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
+        if (function_die)
+        {
+            ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
+        }
+    }
+
+    return functions_added;
+}
+
+
+size_t
+SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
+{
+    // At least a compile unit must be valid
+    assert(sc.comp_unit);
+    size_t types_added = 0;
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+    if (dwarf_cu)
+    {
+        if (sc.function)
+        {
+            dw_offset_t function_die_offset = sc.function->GetID();
+            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
+            if (func_die && func_die->HasChildren())
+            {
+                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
+            }
+        }
+        else
+        {
+            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
+            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
+            {
+                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
+            }
+        }
+    }
+
+    return types_added;
+}
+
+size_t
+SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
+{
+    if (sc.comp_unit != NULL)
+    {
+        DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
+
+        if (dwarf_cu == NULL)
+            return 0;
+
+        if (sc.function)
+        {
+            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
+            return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true);
+        }
+        else if (sc.comp_unit)
+        {
+            uint32_t vars_added = 0;
+            VariableListSP variables (sc.comp_unit->GetVariableList(false));
+            
+            if (variables.get() == NULL)
+            {
+                variables.reset(new VariableList());
+                sc.comp_unit->SetVariableList(variables);
+
+                // Index if we already haven't to make sure the compile units
+                // get indexed and make their global DIE index list
+                if (!m_indexed)
+                    Index ();
+
+                const size_t num_globals = dwarf_cu->GetNumGlobals();
+                for (size_t idx=0; idx<num_globals; ++idx)
+                {
+                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx)));
+                    if (var_sp)
+                    {
+                        variables->AddVariable(var_sp);
+                        ++vars_added;
+                    }
+                }
+            }
+            return vars_added;
+        }
+    }
+    return 0;
+}
+
+
+VariableSP
+SymbolFileDWARF::ParseVariableDIE
+(
+    const SymbolContext& sc,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *die
+)
+{
+
+    VariableSP var_sp;
+    
+    const dw_tag_t tag = die->Tag();
+    DWARFDebugInfoEntry::Attributes attributes;
+    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
+    if (num_attributes > 0)
+    {
+        const char *name = NULL;
+        Declaration decl;
+        uint32_t i;
+        TypeSP type_sp;
+        Type *var_type = NULL;
+        DWARFExpression location;
+        bool is_external = false;
+        bool is_artificial = false;
+        uint32_t accessibility = clang::AS_none;
+
+        for (i=0; i<num_attributes; ++i)
+        {
+            dw_attr_t attr = attributes.AttributeAtIndex(i);
+            DWARFFormValue form_value;
+            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+            {
+                switch (attr)
+                {
+                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
+                case DW_AT_type:        var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
+                case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
+                case DW_AT_location:
+                    {
+                        if (form_value.BlockData())
+                        {
+                            const DataExtractor& debug_info_data = get_debug_info_data();
+
+                            uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+                            uint32_t block_length = form_value.Unsigned();
+                            location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL);
+                        }
+                        else
+                        {
+                            const DataExtractor&    debug_loc_data = get_debug_loc_data();
+                            const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+                            size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
+                            if (loc_list_length > 0)
+                            {
+                                Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList());
+                                location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
+                            }
+                        }
+                    }
+                    break;
+
+                case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
+                case DW_AT_accessibility:   accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
+                case DW_AT_const_value:
+                case DW_AT_declaration:
+                case DW_AT_description:
+                case DW_AT_endianity:
+                case DW_AT_segment:
+                case DW_AT_start_scope:
+                case DW_AT_visibility:
+                default:
+                case DW_AT_abstract_origin:
+                case DW_AT_sibling:
+                case DW_AT_specification:
+                    break;
+                }
+            }
+        }
+
+        if (location.IsValid())
+        {
+            assert(var_type != DIE_IS_BEING_PARSED);
+
+            ConstString var_name(name);
+
+            ValueType scope = eValueTypeInvalid;
+
+            const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
+            dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+
+            if (tag == DW_TAG_formal_parameter)
+                scope = eValueTypeVariableArgument;
+            else if (is_external || parent_tag == DW_TAG_compile_unit)
+                scope = eValueTypeVariableGlobal;
+            else
+                scope = eValueTypeVariableLocal;
+
+            SymbolContextScope * symbol_context_scope = NULL;
+            if (parent_tag == DW_TAG_compile_unit)
+            {
+                symbol_context_scope = sc.comp_unit;
+            }
+            else if (sc.function != NULL)
+            {
+                symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
+                if (symbol_context_scope == NULL)
+                    symbol_context_scope = sc.function;
+            }
+
+            assert(symbol_context_scope != NULL);
+            var_sp.reset (new Variable(die->GetOffset(), 
+                                       var_name, 
+                                       var_type, 
+                                       scope, 
+                                       symbol_context_scope, 
+                                       &decl, 
+                                       location, 
+                                       is_external, 
+                                       is_artificial));
+            const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get());
+        }
+    }
+    return var_sp;
+}
+
+size_t
+SymbolFileDWARF::ParseVariables
+(
+    const SymbolContext& sc,
+    const DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *orig_die,
+    bool parse_siblings,
+    bool parse_children,
+    VariableList* cc_variable_list
+)
+{
+    if (orig_die == NULL)
+        return 0;
+
+    size_t vars_added = 0;
+    const DWARFDebugInfoEntry *die = orig_die;
+    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
+    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+    VariableListSP variables;
+    switch (parent_tag)
+    {
+    case DW_TAG_compile_unit:
+        if (sc.comp_unit != NULL)
+        {
+            variables = sc.comp_unit->GetVariableList(false);
+            if (variables.get() == NULL)
+            {
+                variables.reset(new VariableList());
+                sc.comp_unit->SetVariableList(variables);
+            }
+        }
+        else
+        {
+            assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
+            vars_added = 0;
+        }
+        break;
+
+    case DW_TAG_subprogram:
+    case DW_TAG_inlined_subroutine:
+    case DW_TAG_lexical_block:
+        if (sc.function != NULL)
+        {
+            // Check to see if we already have parsed the variables for the given scope
+            variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false);
+            if (variables.get() == NULL)
+            {
+                variables.reset(new VariableList());
+                sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables);
+            }
+        }
+        else
+        {
+            assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
+            vars_added = 0;
+        }
+        break;
+
+    default:
+        assert(!"Didn't find appropriate parent DIE for variable list...");
+        break;
+    }
+
+    // We need to have a variable list at this point that we can add variables to
+    assert(variables.get());
+
+    while (die != NULL)
+    {
+        dw_tag_t tag = die->Tag();
+
+        // Check to see if we have already parsed this variable or constant?
+        if (die->GetUserData() == NULL)
+        {
+            // We haven't already parsed it, lets do that now.
+            if ((tag == DW_TAG_variable) ||
+                (tag == DW_TAG_constant) ||
+                (tag == DW_TAG_formal_parameter && sc.function))
+            {
+                VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die));
+                if (var_sp)
+                {
+                    variables->AddVariable(var_sp);
+                    ++vars_added;
+                }
+            }
+        }
+
+        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
+
+        if (!skip_children && parse_children && die->HasChildren())
+        {
+            vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true);
+            //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
+        }
+
+        if (parse_siblings)
+            die = die->GetSibling();
+        else
+            die = NULL;
+    }
+
+    if (cc_variable_list)
+    {
+        cc_variable_list->AddVariables(variables.get());
+    }
+
+    return vars_added;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+SymbolFileDWARF::GetPluginName()
+{
+    return "SymbolFileDWARF";
+}
+
+const char *
+SymbolFileDWARF::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+SymbolFileDWARF::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in command are currently supported.");
+    return error;
+}
+
+Log *
+SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
new file mode 100644
index 0000000..95545a4
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -0,0 +1,331 @@
+//===-- SymbolFileDWARF.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolFileDWARF_h_
+#define liblldb_SymbolFileDWARF_h_
+
+// C Includes
+// C++ Includes
+#include <list>
+#include <memory>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+// Project includes
+#include "DWARFDefines.h"
+
+
+//----------------------------------------------------------------------
+// Forward Declarations for this DWARF plugin
+//----------------------------------------------------------------------
+class DWARFAbbreviationDeclaration;
+class DWARFAbbreviationDeclarationSet;
+class DWARFCompileUnit;
+class DWARFDebugAbbrev;
+class DWARFDebugAranges;
+class DWARFDebugInfo;
+class DWARFDebugInfoEntry;
+class DWARFDebugLine;
+class DWARFDebugPubnames;
+class DWARFDebugRanges;
+class DWARFDIECollection;
+class DWARFFormValue;
+
+class SymbolFileDWARF : public lldb_private::SymbolFile
+{
+public:
+    friend class SymbolFileDWARFDebugMap;
+
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static lldb_private::SymbolFile*
+    CreateInstance (lldb_private::ObjectFile* obj_file);
+    //------------------------------------------------------------------
+    // Constructors and Destructors
+    //------------------------------------------------------------------
+                            SymbolFileDWARF(lldb_private::ObjectFile* ofile);
+    virtual                 ~SymbolFileDWARF();
+
+    virtual uint32_t        GetAbilities ();
+
+    //------------------------------------------------------------------
+    // Compile Unit function calls
+    //------------------------------------------------------------------
+    virtual uint32_t        GetNumCompileUnits();
+    virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index);
+
+    virtual size_t          ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
+    virtual bool            ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
+    virtual bool            ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList& support_files);
+    virtual size_t          ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
+    virtual size_t          ParseTypes (const lldb_private::SymbolContext& sc);
+    virtual size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc);
+
+    virtual lldb_private::Type*     ResolveTypeUID(lldb::user_id_t type_uid);
+    virtual clang::DeclContext* GetClangDeclContextForTypeUID (lldb::user_id_t type_uid);
+
+    virtual uint32_t        ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
+    virtual uint32_t        ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
+    virtual uint32_t        FindGlobalVariables(const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+    virtual uint32_t        FindGlobalVariables(const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+    virtual uint32_t        FindFunctions(const lldb_private::ConstString &name, bool append, lldb_private::SymbolContextList& sc_list);
+    virtual uint32_t        FindFunctions(const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list);
+//  virtual uint32_t        FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types);
+//  virtual uint32_t        FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types);
+
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+    // Approach 2 - count + accessor
+    // Index compile units would scan the initial compile units and register
+    // them with the module. This would only be done on demand if and only if
+    // the compile units were needed.
+    //virtual size_t        GetCompUnitCount() = 0;
+    //virtual CompUnitSP    GetCompUnitAtIndex(size_t cu_idx) = 0;
+
+    const lldb_private::DataExtractor&      get_debug_abbrev_data();
+    const lldb_private::DataExtractor&      get_debug_aranges_data();
+    const lldb_private::DataExtractor&      get_debug_frame_data();
+    const lldb_private::DataExtractor&      get_debug_info_data();
+    const lldb_private::DataExtractor&      get_debug_line_data();
+    const lldb_private::DataExtractor&      get_debug_loc_data();
+    const lldb_private::DataExtractor&      get_debug_macinfo_data();
+    const lldb_private::DataExtractor&      get_debug_pubnames_data();
+    const lldb_private::DataExtractor&      get_debug_pubtypes_data();
+    const lldb_private::DataExtractor&      get_debug_ranges_data();
+    const lldb_private::DataExtractor&      get_debug_str_data();
+
+    DWARFDebugAbbrev*       DebugAbbrev();
+    const DWARFDebugAbbrev* DebugAbbrev() const;
+
+    DWARFDebugAranges*      DebugAranges();
+    const DWARFDebugAranges*DebugAranges() const;
+
+    DWARFDebugInfo*         DebugInfo();
+    const DWARFDebugInfo*   DebugInfo() const;
+
+//  These shouldn't be used unless we want to dump the DWARF line tables.
+//  DWARFDebugLine*         DebugLine();
+//  const DWARFDebugLine*   DebugLine() const;
+
+//    DWARFDebugPubnames*     DebugPubnames();
+//    const DWARFDebugPubnames* DebugPubnames() const;
+//
+//    DWARFDebugPubnames*     DebugPubBaseTypes();
+//    const DWARFDebugPubnames* DebugPubBaseTypes() const;
+//
+//    DWARFDebugPubnames*     DebugPubtypes();
+//    const DWARFDebugPubnames* DebugPubtypes() const;
+
+    DWARFDebugRanges*       DebugRanges();
+    const DWARFDebugRanges* DebugRanges() const;
+
+    const lldb_private::DataExtractor&
+    GetCachedSectionData (uint32_t got_flag, const lldb_private::ConstString &section_name, lldb_private::DataExtractor &data);
+
+    static bool             SupportedVersion(uint16_t version);
+
+    clang::DeclContext *
+    GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die);
+
+    clang::DeclContext *
+    GetClangDeclContextForDIEOffset (dw_offset_t die_offset);
+
+    lldb_private::Flags&
+    GetFlags ()
+    {
+        return m_flags;
+    }
+
+    const lldb_private::Flags&
+    GetFlags () const
+    {
+        return m_flags;
+    }
+
+protected:
+
+    enum
+    {
+        flagsGotDebugAbbrevData     = (1 << 0),
+        flagsGotDebugArangesData    = (1 << 1),
+        flagsGotDebugFrameData      = (1 << 2),
+        flagsGotDebugInfoData       = (1 << 3),
+        flagsGotDebugLineData       = (1 << 4),
+        flagsGotDebugLocData        = (1 << 5),
+        flagsGotDebugMacInfoData    = (1 << 6),
+        flagsGotDebugPubNamesData   = (1 << 7),
+        flagsGotDebugPubTypesData   = (1 << 8),
+        flagsGotDebugRangesData     = (1 << 9),
+        flagsGotDebugStrData        = (1 << 10),
+        // True if this is a .o file used when resolving a N_OSO entry with
+        // debug maps.
+        flagsDWARFIsOSOForDebugMap  = (1 << 16)
+    };
+
+    DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
+    bool                    ParseCompileUnit(DWARFCompileUnit* cu, lldb::CompUnitSP& compile_unit_sp);
+    DWARFCompileUnit*       GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid);
+    DWARFCompileUnit*       GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu);
+    lldb_private::CompileUnit*      GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx = UINT_MAX);
+    bool                    GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, lldb_private::SymbolContext& sc);
+    lldb_private::Function *        ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die);
+    size_t                  ParseFunctionBlocks (const lldb_private::SymbolContext& sc,
+                                                 lldb::user_id_t parentBlockID,
+                                                 const DWARFCompileUnit* dwarf_cu,
+                                                 const DWARFDebugInfoEntry *die,
+                                                 lldb::addr_t subprogram_low_pc,
+                                                 bool parse_siblings,
+                                                 bool parse_children);
+    size_t                  ParseTypes (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children);
+    lldb::TypeSP            ParseType (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new);
+
+    lldb::VariableSP        ParseVariableDIE(
+                                const lldb_private::SymbolContext& sc,
+                                const DWARFCompileUnit* dwarf_cu,
+                                const DWARFDebugInfoEntry *die);
+
+    size_t                  ParseVariables(
+                                const lldb_private::SymbolContext& sc,
+                                const DWARFCompileUnit* dwarf_cu,
+                                const DWARFDebugInfoEntry *die,
+                                bool parse_siblings,
+                                bool parse_children,
+                                lldb_private::VariableList* cc_variable_list = NULL);
+
+    size_t                  ParseChildMembers(
+                                const lldb_private::SymbolContext& sc,
+                                lldb::TypeSP& type_sp,
+                                const DWARFCompileUnit* dwarf_cu,
+                                const DWARFDebugInfoEntry *die,
+                                std::vector<clang::CXXBaseSpecifier *>& base_classes,
+                                std::vector<int>& member_accessibilities,
+                                int &default_accessibility,
+                                bool &is_a_class);
+
+    size_t                  ParseChildParameters(
+                                const lldb_private::SymbolContext& sc,
+                                lldb::TypeSP& type_sp,
+                                const DWARFCompileUnit* dwarf_cu,
+                                const DWARFDebugInfoEntry *parent_die,
+                                lldb_private::TypeList* type_list,
+                                std::vector<void *>& function_args,
+                                std::vector<clang::ParmVarDecl*>& function_param_decls);
+
+    size_t                  ParseChildEnumerators(
+                                const lldb_private::SymbolContext& sc,
+                                lldb::TypeSP& type_sp,
+                                void *enumerator_qual_type,
+                                uint32_t enumerator_byte_size,
+                                const DWARFCompileUnit* dwarf_cu,
+                                const DWARFDebugInfoEntry *enum_die);
+
+    void                    ParseChildArrayInfo(
+                                const lldb_private::SymbolContext& sc,
+                                const DWARFCompileUnit* dwarf_cu,
+                                const DWARFDebugInfoEntry *parent_die,
+                                int64_t& first_index,
+                                std::vector<uint64_t>& element_orders,
+                                uint32_t& byte_stride,
+                                uint32_t& bit_stride);
+
+    lldb_private::Type*     GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, lldb::TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe);
+    lldb::TypeSP            GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, lldb::TypeSP& owning_type_sp, int32_t child_type, uint32_t idx);
+//  uint32_t                FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types);
+
+    void                    Index();
+
+    lldb_private::Flags             m_flags;
+    lldb_private::DataExtractor     m_dwarf_data; 
+    lldb_private::DataExtractor     m_data_debug_abbrev;
+    lldb_private::DataExtractor     m_data_debug_aranges;
+    lldb_private::DataExtractor     m_data_debug_frame;
+    lldb_private::DataExtractor     m_data_debug_info;
+    lldb_private::DataExtractor     m_data_debug_line;
+    lldb_private::DataExtractor     m_data_debug_loc;
+    lldb_private::DataExtractor     m_data_debug_macinfo;
+    lldb_private::DataExtractor     m_data_debug_pubnames;
+    lldb_private::DataExtractor     m_data_debug_pubtypes;
+    lldb_private::DataExtractor     m_data_debug_ranges;
+    lldb_private::DataExtractor     m_data_debug_str;
+
+    // The auto_ptr items below are generated on demand if and when someone accesses
+    // them through a non const version of this class.
+    std::auto_ptr<DWARFDebugAbbrev>     m_abbr;
+    std::auto_ptr<DWARFDebugAranges>    m_aranges;
+    std::auto_ptr<DWARFDebugInfo>       m_info;
+    std::auto_ptr<DWARFDebugLine>       m_line;
+    lldb_private::UniqueCStringMap<dw_offset_t> m_name_to_function_die; // All concrete functions
+    lldb_private::UniqueCStringMap<dw_offset_t> m_name_to_inlined_die;  // All inlined functions
+    lldb_private::UniqueCStringMap<dw_offset_t> m_name_to_global_die;   // Global and static variables
+    lldb_private::UniqueCStringMap<dw_offset_t> m_name_to_type_die;     // All type DIE offsets
+    bool m_indexed;
+
+//    std::auto_ptr<DWARFDebugPubnames>   m_pubnames;
+//    std::auto_ptr<DWARFDebugPubnames>   m_pubbasetypes; // Just like m_pubtypes, but for DW_TAG_base_type DIEs
+//    std::auto_ptr<DWARFDebugPubnames>   m_pubtypes;
+    std::auto_ptr<DWARFDebugRanges>     m_ranges;
+
+    typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
+    DIEToDeclContextMap m_die_to_decl_ctx;
+    
+//  TypeFixupColl   m_type_fixups;
+//  std::vector<Type*> m_indirect_fixups;
+
+//#define LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST 1
+#if defined(LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST)
+
+    typedef std::map<FileSpec, DWARFDIECollection> FSToDIES;
+    void ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_cu_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die);
+#endif
+};
+
+#endif  // liblldb_SymbolFileDWARF_h_
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
new file mode 100644
index 0000000..7bf968d
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -0,0 +1,873 @@
+//===-- SymbolFileDWARFDebugMap.cpp ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARFDebugMap.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/VariableList.h"
+
+#include "SymbolFileDWARF.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+SymbolFileDWARFDebugMap::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+SymbolFileDWARFDebugMap::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+SymbolFileDWARFDebugMap::GetPluginNameStatic()
+{
+    return "symbol-file.dwarf2-debugmap";
+}
+
+const char *
+SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
+{
+    return "DWARF and DWARF3 debug symbol file reader (debug map).";
+}
+
+SymbolFile*
+SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
+{
+    return new SymbolFileDWARFDebugMap (obj_file);
+}
+
+
+SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
+    SymbolFile(ofile),
+    m_flags(),
+    m_compile_unit_infos(),
+    m_func_indexes(),
+    m_glob_indexes()
+{
+}
+
+
+SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
+{
+}
+
+void
+SymbolFileDWARFDebugMap::InitOSO ()
+{
+    if (m_flags.test(kHaveInitializedOSOs))
+        return;
+
+    m_flags.set(kHaveInitializedOSOs);
+    // In order to get the abilities of this plug-in, we look at the list of
+    // N_OSO entries (object files) from the symbol table and make sure that
+    // these files exist and also contain valid DWARF. If we get any of that
+    // then we return the abilities of the first N_OSO's DWARF.
+
+    Symtab* symtab = m_obj_file->GetSymtab();
+    if (symtab)
+    {
+        //StreamFile s(0, 4, eByteOrderHost, stdout);
+        std::vector<uint32_t> oso_indexes;
+        const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithType(eSymbolTypeObjectFile, oso_indexes);
+
+        symtab->AppendSymbolIndexesWithType(eSymbolTypeFunction, m_func_indexes);
+        symtab->AppendSymbolIndexesWithType(eSymbolTypeGlobal, m_glob_indexes);
+
+        symtab->SortSymbolIndexesByValue(m_func_indexes, true);
+        symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
+
+        if (oso_index_count > 0)
+        {
+            m_compile_unit_infos.resize(oso_index_count);
+//          s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
+//          symtab->Dump(&s, oso_indexes);
+
+            for (uint32_t i=0; i<oso_index_count; ++i)
+            {
+                m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
+                if (m_compile_unit_infos[i].so_symbol->GetSiblingIndex() == 0)
+                    m_compile_unit_infos[i].so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 2);
+                m_compile_unit_infos[i].oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
+            }
+        }
+    }
+}
+
+Module *
+SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
+{
+    const uint32_t cu_count = GetNumCompileUnits();
+    if (oso_idx < cu_count)
+        return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
+    return NULL;
+}
+
+Module *
+SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
+{
+    if (comp_unit_info->oso_module_sp.get() == NULL)
+    {
+        Symbol *oso_symbol = comp_unit_info->oso_symbol;
+        if (oso_symbol)
+        {
+            FileSpec oso_file_spec(oso_symbol->GetMangled().GetName().AsCString());
+
+            ModuleList::GetSharedModule (oso_file_spec,
+                                         m_obj_file->GetModule()->GetArchitecture(),
+                                         NULL,  // UUID pointer
+                                         NULL,  // object name
+                                         0,     // object offset
+                                         comp_unit_info->oso_module_sp,
+                                         NULL,
+                                         NULL);
+            //comp_unit_info->oso_module_sp.reset(new Module (oso_file_spec, m_obj_file->GetModule()->GetArchitecture()));
+        }
+    }
+    return comp_unit_info->oso_module_sp.get();
+}
+
+
+bool
+SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
+{
+    if (oso_idx < m_compile_unit_infos.size())
+    {
+        if (!m_compile_unit_infos[oso_idx].so_file)
+        {
+
+            if (m_compile_unit_infos[oso_idx].so_symbol == NULL)
+                return false;
+
+            std::string so_path (m_compile_unit_infos[oso_idx].so_symbol->GetMangled().GetName().AsCString());
+            if (m_compile_unit_infos[oso_idx].so_symbol[1].GetType() == eSymbolTypeSourceFile)
+                so_path += m_compile_unit_infos[oso_idx].so_symbol[1].GetMangled().GetName().AsCString();
+            m_compile_unit_infos[oso_idx].so_file.SetFile(so_path.c_str());
+        }
+        file_spec = m_compile_unit_infos[oso_idx].so_file;
+        return true;
+    }
+    return false;
+}
+
+
+
+ObjectFile *
+SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
+{
+    Module *oso_module = GetModuleByOSOIndex (oso_idx);
+    if (oso_module)
+        return oso_module->GetObjectFile();
+    return NULL;
+}
+
+SymbolFileDWARF *
+SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
+{
+    CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
+    if (comp_unit_info)
+        return GetSymbolFileByCompUnitInfo (comp_unit_info);
+    return NULL;
+}
+
+ObjectFile *
+SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
+{
+    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+    if (oso_module)
+        return oso_module->GetObjectFile();
+    return NULL;
+}
+
+SymbolFileDWARF *
+SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
+{
+    if (oso_idx < m_compile_unit_infos.size())
+        return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
+    return NULL;
+}
+
+SymbolFileDWARF *
+SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
+{
+    if (comp_unit_info->oso_symbol_vendor == NULL)
+    {
+        ObjectFile *oso_objfile = GetObjectFileByCompUnitInfo (comp_unit_info);
+
+        if (oso_objfile)
+        {
+            comp_unit_info->oso_symbol_vendor = oso_objfile->GetModule()->GetSymbolVendor();
+//          SymbolFileDWARF *oso_dwarf = new SymbolFileDWARF(oso_objfile);
+//          comp_unit_info->oso_dwarf_sp.reset (oso_dwarf);
+            if (comp_unit_info->oso_symbol_vendor)
+            {
+                // Set a bit that lets this DWARF file know that it is being
+                // used along with a debug map and that it will have the
+                // remapped sections that we do below.
+                ((SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile())->GetFlags().Set(SymbolFileDWARF::flagsDWARFIsOSOForDebugMap);
+                comp_unit_info->debug_map_sections_sp.reset(new SectionList);
+
+                Symtab *exe_symtab = m_obj_file->GetSymtab();
+                Module *oso_module = oso_objfile->GetModule();
+                Symtab *oso_symtab = oso_objfile->GetSymtab();
+//#define DEBUG_OSO_DMAP    // Do not check in with this defined...
+#if defined(DEBUG_OSO_DMAP)
+                StreamFile s(stdout);
+                s << "OSO symtab:\n";
+                oso_symtab->Dump(&s, NULL);
+                s << "OSO sections before:\n";
+                oso_objfile->GetSectionList()->Dump(&s, NULL, true);
+#endif
+
+                ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
+                //SectionList *oso_sections = oso_objfile->Sections();
+                // Now we need to make sections that map from zero based object
+                // file addresses to where things eneded up in the main executable.
+                uint32_t oso_start_idx = comp_unit_info->oso_symbol->GetID() + 1;
+                const uint32_t oso_end_idx = comp_unit_info->so_symbol->GetSiblingIndex();
+                uint32_t sect_id = 0x10000;
+                for (uint32_t idx = oso_start_idx; idx < oso_end_idx; ++idx)
+                {
+                    Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+                    if (exe_symbol)
+                    {
+                        switch (exe_symbol->GetType())
+                        {
+                        case eSymbolTypeFunction:
+                            {
+                                // For each N_FUN, or function that we run into in the debug map
+                                // we make a new section that we add to the sections found in the
+                                // .o file. This new section has the file address set to what the
+                                // addresses are in the .o file, and the load address is adjusted
+                                // to match where it ended up in the final executable! We do this
+                                // before we parse any dwarf info so that when it goes get parsed
+                                // all section/offset addresses that get registered will resolve
+                                // correctly to the new addresses in the main executable.
+
+                                // First we find the original symbol in the .o file's symbol table
+                                Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeCode);
+                                if (oso_fun_symbol)
+                                {
+                                    // If we found the symbol, then we
+                                    Section* exe_fun_section = const_cast<Section *>(exe_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection());
+                                    Section* oso_fun_section = const_cast<Section *>(oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection());
+                                    if (oso_fun_section)
+                                    {
+                                        // Now we create a section that we will add as a child of the
+                                        // section in which the .o symbol (the N_FUN) exists.
+
+                                        // We use the exe_symbol size because the one in the .o file
+                                        // will just be a symbol with no size, and the exe_symbol
+                                        // size will reflect any size changes (ppc has been known to
+                                        // shrink function sizes when it gets rid of jump islands that
+                                        // aren't needed anymore).
+                                        SectionSP oso_fun_section_sp (new Section (const_cast<Section *>(oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()),
+                                                                                   oso_module,                         // Module (the .o file)
+                                                                                   sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
+                                                                                   exe_symbol->GetMangled().GetName(), // Name the section the same as the symbol for which is was generated!
+                                                                                   eSectionTypeDebug,
+                                                                                   oso_fun_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(),  // File VM address offset in the current section
+                                                                                   exe_symbol->GetByteSize(),          // File size (we need the size from the executable)
+                                                                                   0, 0, 0));
+
+                                        oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
+                                                                               exe_symbol->GetValue().GetFileAddress() - exe_fun_section->GetFileAddress());
+                                        oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
+                                        comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp);
+                                    }
+                                }
+                            }
+                            break;
+
+                        case eSymbolTypeGlobal:
+                        case eSymbolTypeStatic:
+                            {
+                                // For each N_GSYM we remap the address for the global by making
+                                // a new section that we add to the sections found in the .o file.
+                                // This new section has the file address set to what the
+                                // addresses are in the .o file, and the load address is adjusted
+                                // to match where it ended up in the final executable! We do this
+                                // before we parse any dwarf info so that when it goes get parsed
+                                // all section/offset addresses that get registered will resolve
+                                // correctly to the new addresses in the main executable. We
+                                // initially set the section size to be 1 byte, but will need to
+                                // fix up these addresses further after all globals have been
+                                // parsed to span the gaps, or we can find the global variable
+                                // sizes from the DWARF info as we are parsing.
+
+#if 0
+                                // First we find the non-stab entry that corresponds to the N_GSYM in the executable
+                                Symbol *exe_gsym_symbol = exe_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData);
+#else
+                                // The mach-o object file parser already matches up the N_GSYM with with the non-stab
+                                // entry, so we shouldn't have to do that. If this ever changes, enable the code above
+                                // in the "#if 0" block. STSYM's always match the symbol as found below.
+                                Symbol *exe_gsym_symbol = exe_symbol;
+#endif
+                                // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
+                                Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData);
+                                if (exe_gsym_symbol && oso_gsym_symbol)
+                                {
+                                    // If we found the symbol, then we
+                                    Section* exe_gsym_section = const_cast<Section *>(exe_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection());
+                                    Section* oso_gsym_section = const_cast<Section *>(oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection());
+                                    if (oso_gsym_section)
+                                    {
+                                        SectionSP oso_gsym_section_sp (new Section (const_cast<Section *>(oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection()),
+                                                                                   oso_module,                         // Module (the .o file)
+                                                                                   sect_id++,                          // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
+                                                                                   exe_symbol->GetMangled().GetName(), // Name the section the same as the symbol for which is was generated!
+                                                                                   eSectionTypeDebug,
+                                                                                   oso_gsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(),  // File VM address offset in the current section
+                                                                                   1,                                   // We don't know the size of the global, just do the main address for now.
+                                                                                   0, 0, 0));
+
+                                        oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
+                                                                               exe_gsym_symbol->GetValue().GetFileAddress() - exe_gsym_section->GetFileAddress());
+                                        oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
+                                        comp_unit_info->debug_map_sections_sp->AddSection(oso_gsym_section_sp);
+                                    }
+                                }
+                            }
+                            break;
+
+//                        case eSymbolTypeStatic:
+//                            {
+//                                // For each N_STSYM we remap the address for the global by making
+//                                // a new section that we add to the sections found in the .o file.
+//                                // This new section has the file address set to what the
+//                                // addresses are in the .o file, and the load address is adjusted
+//                                // to match where it ended up in the final executable! We do this
+//                                // before we parse any dwarf info so that when it goes get parsed
+//                                // all section/offset addresses that get registered will resolve
+//                                // correctly to the new addresses in the main executable. We
+//                                // initially set the section size to be 1 byte, but will need to
+//                                // fix up these addresses further after all globals have been
+//                                // parsed to span the gaps, or we can find the global variable
+//                                // sizes from the DWARF info as we are parsing.
+//
+//
+//                                Symbol *exe_stsym_symbol = exe_symbol;
+//                                // First we find the non-stab entry that corresponds to the N_STSYM in the .o file
+//                                Symbol *oso_stsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(), eSymbolTypeData);
+//                                if (exe_stsym_symbol && oso_stsym_symbol)
+//                                {
+//                                    // If we found the symbol, then we
+//                                    Section* exe_stsym_section = const_cast<Section *>(exe_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection());
+//                                    Section* oso_stsym_section = const_cast<Section *>(oso_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection());
+//                                    if (oso_stsym_section)
+//                                    {
+//                                        // The load address of the symbol will use the section in the
+//                                        // executable that contains the debug map that corresponds to
+//                                        // the N_FUN symbol. We set the offset to reflect the offset
+//                                        // into that section since we are creating a new section.
+//                                        AddressRange stsym_load_range(exe_stsym_section, exe_stsym_symbol->GetValue().GetFileAddress() - exe_stsym_section->GetFileAddress(), 1);
+//                                        // We need the symbol's section offset address from the .o file, but
+//                                        // we need a non-zero size.
+//                                        AddressRange stsym_file_range(exe_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetSection(), exe_stsym_symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(), 1);
+//
+//                                        // Now we create a section that we will add as a child of the
+//                                        // section in which the .o symbol (the N_FUN) exists.
+//
+//// TODO: mimic what I did for N_FUN if that works...
+////                                        // We use the 1 byte for the size because we don't know the
+////                                        // size of the global symbol without seeing the DWARF.
+////                                        SectionSP oso_fun_section_sp (new Section ( NULL, oso_module,                     // Module (the .o file)
+////                                                                                        sect_id++,                      // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
+////                                                                                        exe_symbol->GetMangled().GetName(),// Name the section the same as the symbol for which is was generated!
+////                                                                                       // &stsym_load_range,              // Load offset is the offset into the executable section for the N_FUN from the debug map
+////                                                                                        &stsym_file_range,              // File section/offset is just the same os the symbol on the .o file
+////                                                                                        0, 0, 0));
+////
+////                                        // Now we add the new section to the .o file's sections as a child
+////                                        // of the section in which the N_SECT symbol exists.
+////                                        oso_stsym_section->GetChildren().AddSection(oso_fun_section_sp);
+////                                        comp_unit_info->debug_map_sections_sp->AddSection(oso_fun_section_sp);
+//                                    }
+//                                }
+//                            }
+//                            break;
+                        }
+                    }
+                }
+#if defined(DEBUG_OSO_DMAP)
+                s << "OSO sections after:\n";
+                oso_objfile->GetSectionList()->Dump(&s, NULL, true);
+#endif
+            }
+        }
+    }
+    if (comp_unit_info->oso_symbol_vendor)
+        return (SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile();
+    return NULL;
+}
+
+uint32_t
+SymbolFileDWARFDebugMap::GetAbilities ()
+{
+    // In order to get the abilities of this plug-in, we look at the list of
+    // N_OSO entries (object files) from the symbol table and make sure that
+    // these files exist and also contain valid DWARF. If we get any of that
+    // then we return the abilities of the first N_OSO's DWARF.
+
+    const uint32_t oso_index_count = GetNumCompileUnits();
+    if (oso_index_count > 0)
+    {
+        const uint32_t dwarf_abilities = SymbolFile::CompileUnits |
+                                         SymbolFile::Functions |
+                                         SymbolFile::Blocks |
+                                         SymbolFile::GlobalVariables |
+                                         SymbolFile::LocalVariables |
+                                         SymbolFile::VariableTypes |
+                                         SymbolFile::LineTables;
+
+        for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
+        {
+            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
+            if (oso_dwarf)
+            {
+                uint32_t oso_abilities = oso_dwarf->GetAbilities();
+                if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
+                    return oso_abilities;
+            }
+        }
+    }
+    return 0;
+}
+
+uint32_t
+SymbolFileDWARFDebugMap::GetNumCompileUnits()
+{
+    InitOSO ();
+    return m_compile_unit_infos.size();
+}
+
+
+CompUnitSP
+SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
+{
+    CompUnitSP comp_unit_sp;
+    const uint32_t cu_count = GetNumCompileUnits();
+
+    if (cu_idx < cu_count)
+    {
+        if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL)
+        {
+            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (cu_idx);
+            if (oso_dwarf)
+            {
+                // There is only one compile unit for N_OSO entry right now, so
+                // it will always exist at index zero.
+                m_compile_unit_infos[cu_idx].oso_compile_unit_sp = m_compile_unit_infos[cu_idx].oso_symbol_vendor->GetCompileUnitAtIndex (0);
+            }
+
+            if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL)
+            {
+                // We weren't able to get the DWARF for this N_OSO entry (the
+                // .o file may be missing or not at the specified path), make
+                // one up as best we can from the debug map. We set the uid
+                // of the compile unit to the symbol index with the MSBit set
+                // so that it doesn't collide with any uid values from the DWARF
+                Symbol *so_symbol = m_compile_unit_infos[cu_idx].so_symbol;
+                if (so_symbol)
+                {
+                    m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
+                                                                                            NULL,
+                                                                                            so_symbol->GetMangled().GetName().AsCString(),
+                                                                                            cu_idx,
+                                                                                            Language::Unknown));
+                }
+            }
+        }
+        comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
+    }
+
+    return comp_unit_sp;
+}
+
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
+{
+    const uint32_t cu_count = GetNumCompileUnits();
+    for (uint32_t i=0; i<cu_count; ++i)
+    {
+        if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get())
+            return &m_compile_unit_infos[i];
+    }
+    return NULL;
+}
+
+size_t
+SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseCompileUnitFunctions (sc);
+    return 0;
+}
+
+bool
+SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseCompileUnitLineTable (sc);
+    return false;
+}
+
+bool
+SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
+    return false;
+}
+
+
+size_t
+SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseFunctionBlocks (sc);
+    return 0;
+}
+
+
+size_t
+SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseTypes (sc);
+    return 0;
+}
+
+
+size_t
+SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
+{
+    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+    if (oso_dwarf)
+        return oso_dwarf->ParseTypes (sc);
+    return 0;
+}
+
+
+
+Type*
+SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
+{
+    return NULL;
+}
+
+
+uint32_t
+SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
+{
+    uint32_t resolved_flags = 0;
+    Symtab* symtab = m_obj_file->GetSymtab();
+    if (symtab)
+    {
+        const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
+        sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
+
+        if (sc.symbol != NULL)
+        {
+            resolved_flags |= eSymbolContextSymbol;
+
+            uint32_t oso_idx = 0;
+            CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (sc.symbol->GetID(), &oso_idx);
+            if (comp_unit_info)
+            {
+                SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
+                ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
+                if (oso_dwarf && oso_objfile)
+                {
+                    SectionList *oso_section_list = oso_objfile->GetSectionList();
+
+
+                    SectionSP oso_section_sp(oso_section_list->FindSectionByName(exe_so_addr.GetSection()->GetName()));
+                    if (oso_section_sp)
+                    {
+                        SectionSP oso_symbol_section_sp (oso_section_sp->GetChildren().FindSectionContainingLinkedFileAddress (exe_file_addr));
+
+                        if (oso_symbol_section_sp)
+                        {
+                            const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
+                            Address oso_so_addr (oso_symbol_section_sp.get(), exe_file_addr - linked_file_addr);
+                            if (oso_so_addr.IsSectionOffset())
+                                resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+                        }
+                    }
+                    // Map the load address from in the executable back to a
+                    // section/offset address in the .o file so we can do
+                    // lookups in the .o DWARF.
+//                    Address oso_so_addr (exe_load_addr, false, comp_unit_info->debug_map_sections_sp.get());
+//
+//                    // Make sure we were able to resolve this back to a .o
+//                    // section offset address, and if so, resolve the context
+//                    // for everything that was asked for.
+//                    if (oso_so_addr.IsSectionOffset())
+//                        resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+                }
+            }
+        }
+    }
+    return resolved_flags;
+}
+
+
+uint32_t
+SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
+{
+    uint32_t initial = sc_list.GetSize();
+    const uint32_t cu_count = GetNumCompileUnits();
+
+    FileSpec so_file_spec;
+    for (uint32_t i=0; i<cu_count; ++i)
+    {
+        if (GetFileSpecForSO (i, so_file_spec))
+        {
+            // By passing false to the comparison we will be able to match
+            // and files given a filename only. If both file_spec and
+            // so_file_spec have directories, we will still do a full match.
+            if (FileSpec::Compare (file_spec, so_file_spec, false) == 0)
+            {
+                SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
+
+                oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
+            }
+        }
+    }
+    return sc_list.GetSize() - initial;
+}
+
+uint32_t
+SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
+(
+    const ConstString &name,
+    const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
+    uint32_t max_matches,
+    VariableList& variables
+)
+{
+    const uint32_t original_size = variables.GetSize();
+    const size_t match_count = indexes.size();
+    for (size_t i=0; i<match_count; ++i)
+    {
+        uint32_t oso_idx;
+        CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
+        if (comp_unit_info)
+        {
+            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
+            if (oso_dwarf)
+            {
+                if (oso_dwarf->FindGlobalVariables(name, true, max_matches, variables))
+                    if (variables.GetSize() > max_matches)
+                        break;
+            }
+        }
+    }
+    return variables.GetSize() - original_size;
+}
+
+uint32_t
+SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
+{
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        variables.Clear();
+
+    // Remember how many variables are in the list before we search in case
+    // we are appending the results to a variable list.
+    const uint32_t original_size = variables.GetSize();
+
+    Symtab* symtab = m_obj_file->GetSymtab();
+    if (symtab)
+    {
+        std::vector<uint32_t> indexes;
+        const size_t match_count = m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType (name, eSymbolTypeGlobal, indexes);
+        if (match_count)
+        {
+            PrivateFindGlobalVariables (name, indexes, max_matches, variables);
+        }
+    }
+    // Return the number of variable that were appended to the list
+    return variables.GetSize() - original_size;
+}
+
+
+uint32_t
+SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+{
+    return 0;
+}
+
+
+int
+SymbolFileDWARFDebugMap::SymbolContainsSymbolIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
+{
+    const uint32_t symbol_idx = *symbol_idx_ptr;
+
+    if (symbol_idx < comp_unit_info->so_symbol->GetID())
+        return -1;
+
+    if (symbol_idx < comp_unit_info->so_symbol->GetSiblingIndex())
+        return 0;
+
+    return 1;
+}
+
+
+SymbolFileDWARFDebugMap::CompileUnitInfo*
+SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
+{
+    const uint32_t oso_index_count = m_compile_unit_infos.size();
+    CompileUnitInfo *comp_unit_info = NULL;
+    if (oso_index_count)
+    {
+        comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(), sizeof(CompileUnitInfo), (comparison_function)SymbolContainsSymbolIndex);
+    }
+
+    if (oso_idx_ptr)
+    {
+        if (comp_unit_info != NULL)
+            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
+        else
+            *oso_idx_ptr = UINT32_MAX;
+    }
+    return comp_unit_info;
+}
+
+uint32_t
+SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
+                        name.GetCString());
+
+
+    std::vector<uint32_t> indexes;
+    uint32_t initial_size = 0;
+    if (append)
+        initial_size = sc_list.GetSize();
+    else
+        sc_list.Clear();
+
+    const size_t match_count = m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType (name, eSymbolTypeFunction, indexes);
+    if (match_count > 0)
+    {
+        for (size_t i=0; i<match_count; ++i)
+        {
+            uint32_t oso_idx;
+            CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
+            if (comp_unit_info)
+            {
+                SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
+                if (oso_dwarf)
+                    oso_dwarf->FindFunctions(name, true, sc_list);
+            }
+        }
+//      Stream s(stdout);
+//      sc_list.Dump(&s);
+    }
+
+    return sc_list.GetSize() - initial_size;
+}
+
+
+uint32_t
+SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
+                        regex.GetText());
+
+
+    return 0;
+}
+
+//
+//uint32_t
+//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+//{
+//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+//  if (oso_dwarf)
+//      return oso_dwarf->FindTypes (sc, name, append, max_matches, encoding, udt_uid, types);
+//  return 0;
+//}
+//
+//
+//uint32_t
+//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+//{
+//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
+//  if (oso_dwarf)
+//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
+//  return 0;
+//}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+SymbolFileDWARFDebugMap::GetPluginName()
+{
+    return "SymbolFileDWARFDebugMap";
+}
+
+const char *
+SymbolFileDWARFDebugMap::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+SymbolFileDWARFDebugMap::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+SymbolFileDWARFDebugMap::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+SymbolFileDWARFDebugMap::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in command are currently supported.");
+    return error;
+}
+
+Log *
+SymbolFileDWARFDebugMap::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
+
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
new file mode 100644
index 0000000..0a312ab
--- /dev/null
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -0,0 +1,186 @@
+//===-- SymbolFileDWARFDebugMap.h ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolFileDWARFDebugMap_h_
+#define liblldb_SymbolFileDWARFDebugMap_h_
+
+
+#include <vector>
+#include <bitset>
+#include "lldb/Symbol/SymbolFile.h"
+
+class SymbolFileDWARF;
+
+class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile
+{
+public:
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static lldb_private::SymbolFile *
+    CreateInstance (lldb_private::ObjectFile* obj_file);
+
+    //------------------------------------------------------------------
+    // Constructors and Destructors
+    //------------------------------------------------------------------
+                            SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile);
+    virtual               ~ SymbolFileDWARFDebugMap ();
+
+    virtual uint32_t        GetAbilities ();
+
+    //------------------------------------------------------------------
+    // Compile Unit function calls
+    //------------------------------------------------------------------
+    virtual uint32_t        GetNumCompileUnits ();
+    virtual lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index);
+
+    virtual size_t          ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
+    virtual bool            ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
+    virtual bool            ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
+    virtual size_t          ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
+    virtual size_t          ParseTypes (const lldb_private::SymbolContext& sc);
+    virtual size_t          ParseVariablesForContext (const lldb_private::SymbolContext& sc);
+
+    virtual lldb_private::Type*     ResolveTypeUID (lldb::user_id_t type_uid);
+    virtual uint32_t        ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
+    virtual uint32_t        ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
+    virtual uint32_t        FindGlobalVariables (const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+    virtual uint32_t        FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+    virtual uint32_t        FindFunctions (const lldb_private::ConstString &name, bool append, lldb_private::SymbolContextList& sc_list);
+    virtual uint32_t        FindFunctions (const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list);
+//  virtual uint32_t        FindTypes (const lldb_private::SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types);
+//  virtual uint32_t        FindTypes (const lldb_private::SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types);
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+protected:
+    enum
+    {
+        kHaveInitializedOSOs = (1 << 0),
+        kNumFlags
+    };
+
+    //------------------------------------------------------------------
+    // Class specific types
+    //------------------------------------------------------------------
+    struct CompileUnitInfo
+    {
+        lldb_private::FileSpec so_file;
+        lldb_private::Symbol *so_symbol;
+        lldb_private::Symbol *oso_symbol;
+        lldb::ModuleSP oso_module_sp;
+        lldb::CompUnitSP oso_compile_unit_sp;
+        lldb_private::SymbolVendor *oso_symbol_vendor;
+//      lldb_private::shared_ptr<SymbolFileDWARF> oso_dwarf_sp;
+//      lldb_private::shared_ptr<SymbolVendor> oso_dwarf_sp;
+        std::vector<uint32_t> function_indexes;
+        std::vector<uint32_t> static_indexes;
+        lldb::SharedPtr<lldb_private::SectionList>::Type debug_map_sections_sp;
+
+        CompileUnitInfo() :
+            so_file(),
+            so_symbol(NULL),
+            oso_symbol(NULL),
+            oso_module_sp(),
+            oso_compile_unit_sp(),
+            oso_symbol_vendor(NULL),
+//          oso_dwarf_sp(),
+            function_indexes(),
+            static_indexes(),
+            debug_map_sections_sp()
+        {
+        }
+    };
+
+    //------------------------------------------------------------------
+    // Protected Member Functions
+    //------------------------------------------------------------------
+    void
+    InitOSO ();
+
+    bool
+    GetFileSpecForSO (uint32_t oso_idx, lldb_private::FileSpec &file_spec);
+
+    CompileUnitInfo *
+    GetCompUnitInfo (const lldb_private::SymbolContext& sc);
+
+    lldb_private::Module *
+    GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
+
+    lldb_private::Module *
+    GetModuleByOSOIndex (uint32_t oso_idx);
+
+    lldb_private::ObjectFile *
+    GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
+
+    lldb_private::ObjectFile *
+    GetObjectFileByOSOIndex (uint32_t oso_idx);
+
+    SymbolFileDWARF *
+    GetSymbolFile (const lldb_private::SymbolContext& sc);
+
+    SymbolFileDWARF *
+    GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info);
+
+    SymbolFileDWARF *
+    GetSymbolFileByOSOIndex (uint32_t oso_idx);
+
+    CompileUnitInfo*
+    GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr);
+
+    static int
+    SymbolContainsSymbolIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info);
+
+    uint32_t
+    PrivateFindGlobalVariables (const lldb_private::ConstString &name,
+                                const std::vector<uint32_t> &name_symbol_indexes,
+                                uint32_t max_matches,
+                                lldb_private::VariableList& variables);
+
+    //------------------------------------------------------------------
+    // Member Variables
+    //------------------------------------------------------------------
+    std::bitset<kNumFlags> m_flags;
+    std::vector<CompileUnitInfo> m_compile_unit_infos;
+    std::vector<uint32_t> m_func_indexes;   // Sorted by address
+    std::vector<uint32_t> m_glob_indexes;
+};
+
+#endif // #ifndef liblldb_SymbolFileDWARFDebugMap_h_
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
new file mode 100644
index 0000000..d7da356
--- /dev/null
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -0,0 +1,401 @@
+//===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileSymtab.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Function.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+SymbolFileSymtab::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+SymbolFileSymtab::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+SymbolFileSymtab::GetPluginNameStatic()
+{
+    return "symbol-file.symtab";
+}
+
+const char *
+SymbolFileSymtab::GetPluginDescriptionStatic()
+{
+    return "Reads debug symbols from an object file's symbol table.";
+}
+
+
+SymbolFile*
+SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
+{
+    return new SymbolFileSymtab(obj_file);
+}
+
+SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
+    SymbolFile(obj_file),
+    m_source_indexes(),
+    m_func_indexes(),
+    m_code_indexes(),
+    m_data_indexes(),
+    m_addr_indexes()
+{
+}
+
+SymbolFileSymtab::~SymbolFileSymtab()
+{
+}
+
+
+uint32_t
+SymbolFileSymtab::GetAbilities ()
+{
+    uint32_t abilities = 0;
+    const Symtab *symtab = m_obj_file->GetSymtab();
+    if (symtab)
+    {
+
+        //----------------------------------------------------------------------
+        // The snippet of code below will get the indexes the module symbol
+        // table entries that are code, data, or function related (debug info),
+        // sort them by value (address) and dump the sorted symbols.
+        //----------------------------------------------------------------------
+        symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes);
+        if (!m_source_indexes.empty())
+        {
+            abilities |= CompileUnits;
+        }
+        symtab->AppendSymbolIndexesWithType(eSymbolTypeFunction, m_func_indexes);
+        if (!m_func_indexes.empty())
+        {
+            symtab->SortSymbolIndexesByValue(m_func_indexes, true);
+            abilities |= Functions;
+        }
+
+        symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, m_code_indexes);
+        if (!m_code_indexes.empty())
+        {
+            symtab->SortSymbolIndexesByValue(m_code_indexes, true);
+            abilities |= Labels;
+        }
+
+        symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes);
+
+        if (!m_data_indexes.empty())
+        {
+            symtab->SortSymbolIndexesByValue(m_data_indexes, true);
+            abilities |= GlobalVariables;
+        }
+    }
+
+    return abilities;
+}
+
+uint32_t
+SymbolFileSymtab::GetNumCompileUnits()
+{
+    // If we don't have any source file symbols we will just have one compile unit for
+    // the entire object file
+    if (m_source_indexes.empty())
+        return 1;
+
+    // If we have any source file symbols we will logically orgnize the object symbols
+    // using these.
+    return m_source_indexes.size();
+}
+
+CompUnitSP
+SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
+{
+    CompUnitSP cu_sp;
+
+    // If we don't have any source file symbols we will just have one compile unit for
+    // the entire object file
+    if (m_source_indexes.empty())
+    {
+        const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
+        if (obj_file_spec)
+            cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, Language::Unknown));
+
+    }
+    else if (idx < m_source_indexes.size())
+    {
+        const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
+        if (cu_symbol)
+            cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, Language::Unknown));
+    }
+    return cu_sp;
+}
+
+size_t
+SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
+{
+    size_t num_added = 0;
+    // We must at least have a valid compile unit
+    assert (sc.comp_unit != NULL);
+    const Symtab *symtab = m_obj_file->GetSymtab();
+    const Symbol *curr_symbol = NULL;
+    const Symbol *next_symbol = NULL;
+//  const char *prefix = m_obj_file->SymbolPrefix();
+//  if (prefix == NULL)
+//      prefix == "";
+//
+//  const uint32_t prefix_len = strlen(prefix);
+
+    // If we don't have any source file symbols we will just have one compile unit for
+    // the entire object file
+    if (m_source_indexes.empty())
+    {
+        // The only time we will have a user ID of zero is when we don't have
+        // and source file symbols and we declare one compile unit for the
+        // entire object file
+        if (!m_func_indexes.empty())
+        {
+
+        }
+
+        if (!m_code_indexes.empty())
+        {
+//          StreamFile s(stdout);
+//          symtab->Dump(&s, m_code_indexes);
+
+            uint32_t idx = 0;   // Index into the indexes
+            const uint32_t num_indexes = m_code_indexes.size();
+            for (idx = 0; idx < num_indexes; ++idx)
+            {
+                uint32_t symbol_idx = m_code_indexes[idx];
+                curr_symbol = symtab->SymbolAtIndex(symbol_idx);
+                if (curr_symbol)
+                {
+                    // Union of all ranges in the function DIE (if the function is discontiguous)
+                    AddressRange func_range(curr_symbol->GetValue(), 0);
+                    if (func_range.GetBaseAddress().IsSectionOffset())
+                    {
+                        uint32_t symbol_size = curr_symbol->GetByteSize();
+                        if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
+                            func_range.SetByteSize(symbol_size);
+                        else if (idx + 1 < num_indexes)
+                        {
+                            next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
+                            if (next_symbol)
+                            {
+                                func_range.SetByteSize(next_symbol->GetValue().GetOffset() - curr_symbol->GetValue().GetOffset());
+                            }
+                        }
+
+                        FunctionSP func_sp(new Function(sc.comp_unit,
+                                                            symbol_idx,                 // UserID is the DIE offset
+                                                            LLDB_INVALID_UID,           // We don't have any type info for this function
+                                                            curr_symbol->GetMangled(),  // Linker/mangled name
+                                                            NULL,                       // no return type for a code symbol...
+                                                            func_range));               // first address range
+
+                        if (func_sp.get() != NULL)
+                        {
+                            sc.comp_unit->AddFunction(func_sp);
+                            ++num_added;
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+    else
+    {
+        // We assume we
+    }
+    return num_added;
+}
+
+bool
+SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
+{
+    return false;
+}
+
+bool
+SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
+{
+    return false;
+}
+
+size_t
+SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
+{
+    return 0;
+}
+
+
+size_t
+SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
+{
+    return 0;
+}
+
+
+size_t
+SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
+{
+    return 0;
+}
+
+Type*
+SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
+{
+    return NULL;
+}
+
+
+
+uint32_t
+SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
+{
+    if (m_obj_file->GetSymtab() == NULL)
+        return 0;
+
+    uint32_t resolved_flags = 0;
+    if (resolve_scope & eSymbolContextSymbol)
+    {
+        sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
+        if (sc.symbol)
+            resolved_flags |= eSymbolContextSymbol;
+    }
+    return resolved_flags;
+}
+
+uint32_t
+SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
+{
+    return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
+{
+    return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+{
+    return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindFunctions(const ConstString &name, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileSymtab::FindFunctions (name = '%s')",
+                        name.GetCString());
+
+    Symtab *symtab = m_obj_file->GetSymtab();
+    if (symtab)
+    {
+        const uint32_t start_size = sc_list.GetSize();
+        std::vector<uint32_t> symbol_indexes;
+        symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeFunction, symbol_indexes);
+        symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, symbol_indexes);
+        const uint32_t num_matches = symbol_indexes.size();
+        if (num_matches)
+        {
+            SymbolContext sc(m_obj_file->GetModule());
+            for (uint32_t i=0; i<num_matches; i++)
+            {
+                sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+                sc_list.Append(sc);
+            }
+        }
+        return sc_list.GetSize() - start_size;
+    }
+    return 0;
+}
+
+uint32_t
+SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileSymtab::FindFunctions (regex = '%s')",
+                        regex.GetText());
+
+    return 0;
+}
+
+//uint32_t
+//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+//{
+//  return 0;
+//}
+//
+//uint32_t
+//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
+//{
+//  return 0;
+//}
+
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+SymbolFileSymtab::GetPluginName()
+{
+    return "SymbolFileSymtab";
+}
+
+const char *
+SymbolFileSymtab::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+SymbolFileSymtab::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+SymbolFileSymtab::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+SymbolFileSymtab::ExecutePluginCommand (Args &command, Stream *strm)
+{
+    Error error;
+    error.SetErrorString("No plug-in command are currently supported.");
+    return error;
+}
+
+Log *
+SymbolFileSymtab::EnablePluginLogging (Stream *strm, Args &command)
+{
+    return NULL;
+}
+
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
new file mode 100644
index 0000000..ac73f29
--- /dev/null
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -0,0 +1,136 @@
+//===-- SymbolFileSymtab.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolFileSymtab_h_
+#define liblldb_SymbolFileSymtab_h_
+
+#include "lldb/Symbol/SymbolFile.h"
+#include <vector>
+
+class SymbolFileSymtab : public lldb_private::SymbolFile
+{
+public:
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static lldb_private::SymbolFile*
+    CreateInstance (lldb_private::ObjectFile* obj_file);
+
+    //------------------------------------------------------------------
+    // Constructors and Destructors
+    //------------------------------------------------------------------
+    SymbolFileSymtab(lldb_private::ObjectFile* obj_file);
+
+    virtual
+    ~SymbolFileSymtab();
+
+    virtual uint32_t        GetAbilities ();
+
+    //------------------------------------------------------------------
+    // Compile Unit function calls
+    //------------------------------------------------------------------
+    virtual uint32_t
+    GetNumCompileUnits();
+
+    virtual lldb::CompUnitSP
+    ParseCompileUnitAtIndex(uint32_t index);
+
+    virtual size_t
+    ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc);
+
+    virtual bool
+    ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc);
+
+    virtual bool
+    ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files);
+
+    virtual size_t
+    ParseFunctionBlocks (const lldb_private::SymbolContext& sc);
+
+    virtual size_t
+    ParseTypes (const lldb_private::SymbolContext& sc);
+
+    virtual size_t
+    ParseVariablesForContext (const lldb_private::SymbolContext& sc);
+
+    virtual lldb_private::Type*
+    ResolveTypeUID(lldb::user_id_t type_uid);
+
+    virtual uint32_t
+    ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc);
+
+    virtual uint32_t
+    ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list);
+
+    virtual uint32_t
+    FindGlobalVariables(const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+
+    virtual uint32_t
+    FindGlobalVariables(const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables);
+
+    virtual uint32_t
+    FindFunctions(const lldb_private::ConstString &name, bool append, lldb_private::SymbolContextList& sc_list);
+
+    virtual uint32_t
+    FindFunctions(const lldb_private::RegularExpression& regex, bool append, lldb_private::SymbolContextList& sc_list);
+
+//  virtual uint32_t
+//  FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, bool append, uint32_t max_matches, lldb_private::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types);
+
+//  virtual uint32_t
+//  FindTypes(const lldb_private::SymbolContext& sc, const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::Type::Encoding encoding, lldb::user_id_t udt_uid, lldb_private::TypeList& types);
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+
+
+protected:
+    std::vector<uint32_t>   m_source_indexes;
+    std::vector<uint32_t>   m_func_indexes;
+    std::vector<uint32_t>   m_code_indexes;
+    std::vector<uint32_t>   m_data_indexes;
+    std::vector<uint32_t>   m_addr_indexes; // Anything that needs to go into an search by address
+
+private:
+    DISALLOW_COPY_AND_ASSIGN (SymbolFileSymtab);
+};
+
+
+#endif  // liblldb_SymbolFileSymtab_h_