Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "DWARFDebugInfoEntry.h"
     11 
     12 #include <assert.h>
     13 
     14 #include <algorithm>
     15 
     16 #include "lldb/Core/Module.h"
     17 #include "lldb/Core/Stream.h"
     18 #include "lldb/Expression/DWARFExpression.h"
     19 #include "lldb/Symbol/ObjectFile.h"
     20 
     21 #include "DWARFCompileUnit.h"
     22 #include "SymbolFileDWARF.h"
     23 #include "DWARFDebugAbbrev.h"
     24 #include "DWARFDebugAranges.h"
     25 #include "DWARFDebugInfo.h"
     26 #include "DWARFDeclContext.h"
     27 #include "DWARFDIECollection.h"
     28 #include "DWARFFormValue.h"
     29 #include "DWARFLocationDescription.h"
     30 #include "DWARFLocationList.h"
     31 #include "DWARFDebugRanges.h"
     32 
     33 using namespace lldb_private;
     34 using namespace std;
     35 extern int g_verbose;
     36 
     37 
     38 
     39 DWARFDebugInfoEntry::Attributes::Attributes() :
     40     m_infos()
     41 {
     42 }
     43 
     44 DWARFDebugInfoEntry::Attributes::~Attributes()
     45 {
     46 }
     47 
     48 
     49 uint32_t
     50 DWARFDebugInfoEntry::Attributes::FindAttributeIndex(dw_attr_t attr) const
     51 {
     52     collection::const_iterator end = m_infos.end();
     53     collection::const_iterator beg = m_infos.begin();
     54     collection::const_iterator pos;
     55     for (pos = beg; pos != end; ++pos)
     56     {
     57         if (pos->attr == attr)
     58             return std::distance(beg, pos);
     59     }
     60     return UINT32_MAX;
     61 }
     62 
     63 void
     64 DWARFDebugInfoEntry::Attributes::Append(const DWARFCompileUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr, dw_form_t form)
     65 {
     66     Info info = { cu, attr_die_offset, attr, form };
     67     m_infos.push_back(info);
     68 }
     69 
     70 bool
     71 DWARFDebugInfoEntry::Attributes::ContainsAttribute(dw_attr_t attr) const
     72 {
     73     return FindAttributeIndex(attr) != UINT32_MAX;
     74 }
     75 
     76 bool
     77 DWARFDebugInfoEntry::Attributes::RemoveAttribute(dw_attr_t attr)
     78 {
     79     uint32_t attr_index = FindAttributeIndex(attr);
     80     if (attr_index != UINT32_MAX)
     81     {
     82         m_infos.erase(m_infos.begin() + attr_index);
     83         return true;
     84     }
     85     return false;
     86 }
     87 
     88 bool
     89 DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const
     90 {
     91     form_value.SetForm(FormAtIndex(i));
     92     lldb::offset_t offset = DIEOffsetAtIndex(i);
     93     return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i));
     94 }
     95 
     96 uint64_t
     97 DWARFDebugInfoEntry::Attributes::FormValueAsUnsigned (SymbolFileDWARF* dwarf2Data, dw_attr_t attr, uint64_t fail_value) const
     98 {
     99     const uint32_t attr_idx = FindAttributeIndex (attr);
    100     if (attr_idx != UINT32_MAX)
    101         return FormValueAsUnsignedAtIndex (dwarf2Data, attr_idx, fail_value);
    102     return fail_value;
    103 }
    104 
    105 uint64_t
    106 DWARFDebugInfoEntry::Attributes::FormValueAsUnsignedAtIndex(SymbolFileDWARF* dwarf2Data, uint32_t i, uint64_t fail_value) const
    107 {
    108     DWARFFormValue form_value;
    109     if (ExtractFormValueAtIndex(dwarf2Data, i, form_value))
    110         return form_value.Reference(CompileUnitAtIndex(i));
    111     return fail_value;
    112 }
    113 
    114 
    115 
    116 bool
    117 DWARFDebugInfoEntry::FastExtract
    118 (
    119     const DataExtractor& debug_info_data,
    120     const DWARFCompileUnit* cu,
    121     const uint8_t *fixed_form_sizes,
    122     lldb::offset_t *offset_ptr
    123 )
    124 {
    125     m_offset = *offset_ptr;
    126     m_parent_idx = 0;
    127     m_sibling_idx = 0;
    128     m_empty_children = false;
    129     const uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr);
    130     assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
    131     m_abbr_idx = abbr_idx;
    132 
    133     //assert (fixed_form_sizes);  // For best performance this should be specified!
    134 
    135     if (m_abbr_idx)
    136     {
    137         lldb::offset_t offset = *offset_ptr;
    138 
    139         const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
    140 
    141         if (abbrevDecl == NULL)
    142         {
    143             cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid abbreviation code %u, please file a bug and attach the file at the start of this error message",
    144                                                                                  m_offset,
    145                                                                                  (unsigned)abbr_idx);
    146             // WE can't parse anymore if the DWARF is borked...
    147             *offset_ptr = UINT32_MAX;
    148             return false;
    149         }
    150         m_tag = abbrevDecl->Tag();
    151         m_has_children = abbrevDecl->HasChildren();
    152         // Skip all data in the .debug_info for the attributes
    153         const uint32_t numAttributes = abbrevDecl->NumAttributes();
    154         register uint32_t i;
    155         register dw_form_t form;
    156         for (i=0; i<numAttributes; ++i)
    157         {
    158             form = abbrevDecl->GetFormByIndexUnchecked(i);
    159 
    160             const uint8_t fixed_skip_size = fixed_form_sizes [form];
    161             if (fixed_skip_size)
    162                 offset += fixed_skip_size;
    163             else
    164             {
    165                 bool form_is_indirect = false;
    166                 do
    167                 {
    168                     form_is_indirect = false;
    169                     register uint32_t form_size = 0;
    170                     switch (form)
    171                     {
    172                     // Blocks if inlined data that have a length field and the data bytes
    173                     // inlined in the .debug_info
    174                     case DW_FORM_exprloc     :
    175                     case DW_FORM_block       : form_size = debug_info_data.GetULEB128 (&offset);      break;
    176                     case DW_FORM_block1      : form_size = debug_info_data.GetU8_unchecked (&offset); break;
    177                     case DW_FORM_block2      : form_size = debug_info_data.GetU16_unchecked (&offset);break;
    178                     case DW_FORM_block4      : form_size = debug_info_data.GetU32_unchecked (&offset);break;
    179 
    180                     // Inlined NULL terminated C-strings
    181                     case DW_FORM_string      :
    182                         debug_info_data.GetCStr (&offset);
    183                         break;
    184 
    185                     // Compile unit address sized values
    186                     case DW_FORM_addr        :
    187                         form_size = cu->GetAddressByteSize();
    188                         break;
    189                     case DW_FORM_ref_addr    :
    190                         if (cu->GetVersion() <= 2)
    191                             form_size = cu->GetAddressByteSize();
    192                         else
    193                             form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet
    194                         break;
    195 
    196                     // 0 sized form
    197                     case DW_FORM_flag_present:
    198                         form_size = 0;
    199                         break;
    200 
    201                     // 1 byte values
    202                     case DW_FORM_data1       :
    203                     case DW_FORM_flag        :
    204                     case DW_FORM_ref1        :
    205                         form_size = 1;
    206                         break;
    207 
    208                     // 2 byte values
    209                     case DW_FORM_data2       :
    210                     case DW_FORM_ref2        :
    211                         form_size = 2;
    212                         break;
    213 
    214                     // 4 byte values
    215                     case DW_FORM_strp        :
    216                     case DW_FORM_data4       :
    217                     case DW_FORM_ref4        :
    218                         form_size = 4;
    219                         break;
    220 
    221                     // 8 byte values
    222                     case DW_FORM_data8       :
    223                     case DW_FORM_ref8        :
    224                     case DW_FORM_ref_sig8    :
    225                         form_size = 8;
    226                         break;
    227 
    228                     // signed or unsigned LEB 128 values
    229                     case DW_FORM_sdata       :
    230                     case DW_FORM_udata       :
    231                     case DW_FORM_ref_udata   :
    232                         debug_info_data.Skip_LEB128 (&offset);
    233                         break;
    234 
    235                     case DW_FORM_indirect    :
    236                         form_is_indirect = true;
    237                         form = debug_info_data.GetULEB128 (&offset);
    238                         break;
    239 
    240                     case DW_FORM_sec_offset  :
    241                         if (cu->GetAddressByteSize () == 4)
    242                             debug_info_data.GetU32 (offset_ptr);
    243                         else
    244                             debug_info_data.GetU64 (offset_ptr);
    245                         break;
    246 
    247                     default:
    248                         *offset_ptr = m_offset;
    249                         return false;
    250                     }
    251                     offset += form_size;
    252 
    253                 } while (form_is_indirect);
    254             }
    255         }
    256         *offset_ptr = offset;
    257         return true;
    258     }
    259     else
    260     {
    261         m_tag = 0;
    262         m_has_children = false;
    263         return true;    // NULL debug tag entry
    264     }
    265 
    266     return false;
    267 }
    268 
    269 //----------------------------------------------------------------------
    270 // Extract
    271 //
    272 // Extract a debug info entry for a given compile unit from the
    273 // .debug_info and .debug_abbrev data within the SymbolFileDWARF class
    274 // starting at the given offset
    275 //----------------------------------------------------------------------
    276 bool
    277 DWARFDebugInfoEntry::Extract
    278 (
    279     SymbolFileDWARF* dwarf2Data,
    280     const DWARFCompileUnit* cu,
    281     lldb::offset_t *offset_ptr
    282 )
    283 {
    284     const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
    285 //    const DataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
    286     const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
    287     const uint8_t cu_addr_size = cu->GetAddressByteSize();
    288     lldb::offset_t offset = *offset_ptr;
    289 //  if (offset >= cu_end_offset)
    290 //      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);
    291     if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
    292     {
    293         m_offset = offset;
    294 
    295         const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
    296         assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
    297         m_abbr_idx = abbr_idx;
    298         if (abbr_idx)
    299         {
    300             const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
    301 
    302             if (abbrevDecl)
    303             {
    304                 m_tag = abbrevDecl->Tag();
    305                 m_has_children = abbrevDecl->HasChildren();
    306 
    307                 bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
    308                 if (cu && isCompileUnitTag)
    309                     ((DWARFCompileUnit*)cu)->SetBaseAddress(0);
    310 
    311                 // Skip all data in the .debug_info for the attributes
    312                 const uint32_t numAttributes = abbrevDecl->NumAttributes();
    313                 uint32_t i;
    314                 dw_attr_t attr;
    315                 dw_form_t form;
    316                 for (i=0; i<numAttributes; ++i)
    317                 {
    318                     abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
    319 
    320                     if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc)))
    321                     {
    322                         DWARFFormValue form_value(form);
    323                         if (form_value.ExtractValue(debug_info_data, &offset, cu))
    324                         {
    325                             if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
    326                                 ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned());
    327                         }
    328                     }
    329                     else
    330                     {
    331                         bool form_is_indirect = false;
    332                         do
    333                         {
    334                             form_is_indirect = false;
    335                             register uint32_t form_size = 0;
    336                             switch (form)
    337                             {
    338                             // Blocks if inlined data that have a length field and the data bytes
    339                             // inlined in the .debug_info
    340                             case DW_FORM_exprloc     :
    341                             case DW_FORM_block       : form_size = debug_info_data.GetULEB128(&offset);  break;
    342                             case DW_FORM_block1      : form_size = debug_info_data.GetU8(&offset);       break;
    343                             case DW_FORM_block2      : form_size = debug_info_data.GetU16(&offset);      break;
    344                             case DW_FORM_block4      : form_size = debug_info_data.GetU32(&offset);      break;
    345 
    346                             // Inlined NULL terminated C-strings
    347                             case DW_FORM_string      : debug_info_data.GetCStr(&offset);                 break;
    348 
    349                             // Compile unit address sized values
    350                             case DW_FORM_addr        :
    351                                 form_size = cu_addr_size;
    352                                 break;
    353                             case DW_FORM_ref_addr    :
    354                                 if (cu->GetVersion() <= 2)
    355                                     form_size = cu_addr_size;
    356                                 else
    357                                     form_size = 4; // 4 bytes for DWARF 32, 8 bytes for DWARF 64, but we don't support DWARF64 yet
    358                                 break;
    359 
    360                             // 0 sized form
    361                             case DW_FORM_flag_present:
    362                                 form_size = 0;
    363                                 break;
    364 
    365                             // 1 byte values
    366                             case DW_FORM_data1       :
    367                             case DW_FORM_flag        :
    368                             case DW_FORM_ref1        :
    369                                 form_size = 1;
    370                                 break;
    371 
    372                             // 2 byte values
    373                             case DW_FORM_data2       :
    374                             case DW_FORM_ref2        :
    375                                 form_size = 2;
    376                                 break;
    377 
    378                             // 4 byte values
    379                             case DW_FORM_strp        :
    380                                 form_size = 4;
    381                                 break;
    382 
    383                             case DW_FORM_data4       :
    384                             case DW_FORM_ref4        :
    385                                 form_size = 4;
    386                                 break;
    387 
    388                             // 8 byte values
    389                             case DW_FORM_data8       :
    390                             case DW_FORM_ref8        :
    391                             case DW_FORM_ref_sig8    :
    392                                 form_size = 8;
    393                                 break;
    394 
    395                             // signed or unsigned LEB 128 values
    396                             case DW_FORM_sdata       :
    397                             case DW_FORM_udata       :
    398                             case DW_FORM_ref_udata   :
    399                                 debug_info_data.Skip_LEB128(&offset);
    400                                 break;
    401 
    402                             case DW_FORM_indirect    :
    403                                 form = debug_info_data.GetULEB128(&offset);
    404                                 form_is_indirect = true;
    405                                 break;
    406 
    407                             case DW_FORM_sec_offset  :
    408                                 if (cu->GetAddressByteSize () == 4)
    409                                     debug_info_data.GetU32 (offset_ptr);
    410                                 else
    411                                     debug_info_data.GetU64 (offset_ptr);
    412                                 break;
    413 
    414                             default:
    415                                 *offset_ptr = offset;
    416                                 return false;
    417                             }
    418 
    419                             offset += form_size;
    420                         } while (form_is_indirect);
    421                     }
    422                 }
    423                 *offset_ptr = offset;
    424                 return true;
    425             }
    426         }
    427         else
    428         {
    429             m_tag = 0;
    430             m_has_children = false;
    431             *offset_ptr = offset;
    432             return true;    // NULL debug tag entry
    433         }
    434     }
    435 
    436     return false;
    437 }
    438 
    439 //----------------------------------------------------------------------
    440 // DumpAncestry
    441 //
    442 // Dumps all of a debug information entries parents up until oldest and
    443 // all of it's attributes to the specified stream.
    444 //----------------------------------------------------------------------
    445 void
    446 DWARFDebugInfoEntry::DumpAncestry
    447 (
    448     SymbolFileDWARF* dwarf2Data,
    449     const DWARFCompileUnit* cu,
    450     const DWARFDebugInfoEntry* oldest,
    451     Stream &s,
    452     uint32_t recurse_depth
    453 ) const
    454 {
    455     const DWARFDebugInfoEntry* parent = GetParent();
    456     if (parent && parent != oldest)
    457         parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
    458     Dump(dwarf2Data, cu, s, recurse_depth);
    459 }
    460 
    461 //----------------------------------------------------------------------
    462 // Compare two DIE by comparing all their attributes values, and
    463 // following all DW_FORM_ref attributes and comparing their contents as
    464 // well (except for DW_AT_sibling attributes.
    465 //
    466 //  DWARFDebugInfoEntry::CompareState compare_state;
    467 //  int result = DWARFDebugInfoEntry::Compare(this, 0x00017ccb, 0x0001eb2b, compare_state, false, true);
    468 //----------------------------------------------------------------------
    469 //int
    470 //DWARFDebugInfoEntry::Compare
    471 //(
    472 //    SymbolFileDWARF* dwarf2Data,
    473 //    dw_offset_t a_die_offset,
    474 //    dw_offset_t b_die_offset,
    475 //    CompareState &compare_state,
    476 //    bool compare_siblings,
    477 //    bool compare_children
    478 //)
    479 //{
    480 //    if (a_die_offset == b_die_offset)
    481 //        return 0;
    482 //
    483 //    DWARFCompileUnitSP a_cu_sp;
    484 //    DWARFCompileUnitSP b_cu_sp;
    485 //    const DWARFDebugInfoEntry* a_die = dwarf2Data->DebugInfo()->GetDIEPtr(a_die_offset, &a_cu_sp);
    486 //    const DWARFDebugInfoEntry* b_die = dwarf2Data->DebugInfo()->GetDIEPtr(b_die_offset, &b_cu_sp);
    487 //
    488 //    return Compare(dwarf2Data, a_cu_sp.get(), a_die, b_cu_sp.get(), b_die, compare_state, compare_siblings, compare_children);
    489 //}
    490 //
    491 //int
    492 //DWARFDebugInfoEntry::Compare
    493 //(
    494 //    SymbolFileDWARF* dwarf2Data,
    495 //    DWARFCompileUnit* a_cu, const DWARFDebugInfoEntry* a_die,
    496 //    DWARFCompileUnit* b_cu, const DWARFDebugInfoEntry* b_die,
    497 //    CompareState &compare_state,
    498 //    bool compare_siblings,
    499 //    bool compare_children
    500 //)
    501 //{
    502 //    if (a_die == b_die)
    503 //        return 0;
    504 //
    505 //    if (!compare_state.AddTypePair(a_die->GetOffset(), b_die->GetOffset()))
    506 //    {
    507 //        // We are already comparing both of these types, so let
    508 //        // compares complete for the real result
    509 //        return 0;
    510 //    }
    511 //
    512 //    //printf("DWARFDebugInfoEntry::Compare(0x%8.8x, 0x%8.8x)\n", a_die->GetOffset(), b_die->GetOffset());
    513 //
    514 //    // Do we have two valid DIEs?
    515 //    if (a_die && b_die)
    516 //    {
    517 //        // Both DIE are valid
    518 //        int result = 0;
    519 //
    520 //        const dw_tag_t a_tag = a_die->Tag();
    521 //        const dw_tag_t b_tag = b_die->Tag();
    522 //        if (a_tag == 0 && b_tag == 0)
    523 //            return 0;
    524 //
    525 //        //printf("    comparing tags: %s and %s\n", DW_TAG_value_to_name(a_tag), DW_TAG_value_to_name(b_tag));
    526 //
    527 //        if (a_tag < b_tag)
    528 //            return -1;
    529 //        else if (a_tag > b_tag)
    530 //            return 1;
    531 //
    532 //        DWARFDebugInfoEntry::Attributes a_attrs;
    533 //        DWARFDebugInfoEntry::Attributes b_attrs;
    534 //        size_t a_attr_count = a_die->GetAttributes(dwarf2Data, a_cu, a_attrs);
    535 //        size_t b_attr_count = b_die->GetAttributes(dwarf2Data, b_cu, b_attrs);
    536 //        if (a_attr_count != b_attr_count)
    537 //        {
    538 //            a_attrs.RemoveAttribute(DW_AT_sibling);
    539 //            b_attrs.RemoveAttribute(DW_AT_sibling);
    540 //        }
    541 //
    542 //        a_attr_count = a_attrs.Size();
    543 //        b_attr_count = b_attrs.Size();
    544 //
    545 //        DWARFFormValue a_form_value;
    546 //        DWARFFormValue b_form_value;
    547 //
    548 //        if (a_attr_count != b_attr_count)
    549 //        {
    550 //            uint32_t is_decl_index = a_attrs.FindAttributeIndex(DW_AT_declaration);
    551 //            uint32_t a_name_index = UINT32_MAX;
    552 //            uint32_t b_name_index = UINT32_MAX;
    553 //            if (is_decl_index != UINT32_MAX)
    554 //            {
    555 //                if (a_attr_count == 2)
    556 //                {
    557 //                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
    558 //                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
    559 //                }
    560 //            }
    561 //            else
    562 //            {
    563 //                is_decl_index = b_attrs.FindAttributeIndex(DW_AT_declaration);
    564 //                if (is_decl_index != UINT32_MAX && a_attr_count == 2)
    565 //                {
    566 //                    a_name_index = a_attrs.FindAttributeIndex(DW_AT_name);
    567 //                    b_name_index = b_attrs.FindAttributeIndex(DW_AT_name);
    568 //                }
    569 //            }
    570 //            if (a_name_index != UINT32_MAX && b_name_index != UINT32_MAX)
    571 //            {
    572 //                if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, a_name_index, a_form_value) &&
    573 //                    b_attrs.ExtractFormValueAtIndex(dwarf2Data, b_name_index, b_form_value))
    574 //                {
    575 //                    result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, &dwarf2Data->get_debug_str_data());
    576 //                    if (result == 0)
    577 //                    {
    578 //                        a_attr_count = b_attr_count = 0;
    579 //                        compare_children = false;
    580 //                    }
    581 //                }
    582 //            }
    583 //        }
    584 //
    585 //        if (a_attr_count < b_attr_count)
    586 //            return -1;
    587 //        if (a_attr_count > b_attr_count)
    588 //            return 1;
    589 //
    590 //
    591 //        // The number of attributes are the same...
    592 //        if (a_attr_count > 0)
    593 //        {
    594 //            const DataExtractor* debug_str_data_ptr = &dwarf2Data->get_debug_str_data();
    595 //
    596 //            uint32_t i;
    597 //            for (i=0; i<a_attr_count; ++i)
    598 //            {
    599 //                const dw_attr_t a_attr = a_attrs.AttributeAtIndex(i);
    600 //                const dw_attr_t b_attr = b_attrs.AttributeAtIndex(i);
    601 //                //printf("    comparing attributes\n\t\t0x%8.8x: %s %s\t\t0x%8.8x: %s %s\n",
    602 //                //                a_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(a_attrs.FormAtIndex(i)), DW_AT_value_to_name(a_attr),
    603 //                //                b_attrs.DIEOffsetAtIndex(i), DW_FORM_value_to_name(b_attrs.FormAtIndex(i)), DW_AT_value_to_name(b_attr));
    604 //
    605 //                if (a_attr < b_attr)
    606 //                    return -1;
    607 //                else if (a_attr > b_attr)
    608 //                    return 1;
    609 //
    610 //                switch (a_attr)
    611 //                {
    612 //                // Since we call a form of GetAttributes which inlines the
    613 //                // attributes from DW_AT_abstract_origin and DW_AT_specification
    614 //                // we don't care if their values mismatch...
    615 //                case DW_AT_abstract_origin:
    616 //                case DW_AT_specification:
    617 //                case DW_AT_sibling:
    618 //                case DW_AT_containing_type:
    619 //                    //printf("        action = IGNORE\n");
    620 //                    result = 0;
    621 //                    break;  // ignore
    622 //
    623 //                default:
    624 //                    if (a_attrs.ExtractFormValueAtIndex(dwarf2Data, i, a_form_value) &&
    625 //                        b_attrs.ExtractFormValueAtIndex(dwarf2Data, i, b_form_value))
    626 //                        result = DWARFFormValue::Compare (a_form_value, b_form_value, a_cu, b_cu, debug_str_data_ptr);
    627 //                    break;
    628 //                }
    629 //
    630 //                //printf("\t  result = %i\n", result);
    631 //
    632 //                if (result != 0)
    633 //                {
    634 //                    // Attributes weren't equal, lets see if we care?
    635 //                    switch (a_attr)
    636 //                    {
    637 //                    case DW_AT_decl_file:
    638 //                        // TODO: add the ability to compare files in two different compile units
    639 //                        if (a_cu == b_cu)
    640 //                        {
    641 //                            //printf("        action = RETURN RESULT\n");
    642 //                            return result;  // Only return the compare results when the compile units are the same and the decl_file attributes can be compared
    643 //                        }
    644 //                        else
    645 //                        {
    646 //                            result = 0;
    647 //                            //printf("        action = IGNORE\n");
    648 //                        }
    649 //                        break;
    650 //
    651 //                    default:
    652 //                        switch (a_attrs.FormAtIndex(i))
    653 //                        {
    654 //                        case DW_FORM_ref1:
    655 //                        case DW_FORM_ref2:
    656 //                        case DW_FORM_ref4:
    657 //                        case DW_FORM_ref8:
    658 //                        case DW_FORM_ref_udata:
    659 //                        case DW_FORM_ref_addr:
    660 //                            //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));
    661 //                            // These attribute values refer to other DIEs, so lets compare those instead of their DIE offsets...
    662 //                            result = Compare(dwarf2Data, a_form_value.Reference(a_cu), b_form_value.Reference(b_cu), compare_state, false, true);
    663 //                            if (result != 0)
    664 //                                return result;
    665 //                            break;
    666 //
    667 //                        default:
    668 //                            // We do care that they were different, return this result...
    669 //                            //printf("        action = RETURN RESULT\n");
    670 //                            return result;
    671 //                        }
    672 //                    }
    673 //                }
    674 //            }
    675 //        }
    676 //        //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));
    677 //
    678 //        if (compare_children)
    679 //        {
    680 //            bool a_has_children = a_die->HasChildren();
    681 //            bool b_has_children = b_die->HasChildren();
    682 //            if (a_has_children == b_has_children)
    683 //            {
    684 //                // Both either have kids or don't
    685 //                if (a_has_children)
    686 //                    result = Compare(   dwarf2Data,
    687 //                                        a_cu, a_die->GetFirstChild(),
    688 //                                        b_cu, b_die->GetFirstChild(),
    689 //                                        compare_state, true, compare_children);
    690 //                else
    691 //                    result = 0;
    692 //            }
    693 //            else if (!a_has_children)
    694 //                result = -1;    // A doesn't have kids, but B does
    695 //            else
    696 //                result = 1; // A has kids, but B doesn't
    697 //        }
    698 //
    699 //        if (compare_siblings)
    700 //        {
    701 //            result = Compare(   dwarf2Data,
    702 //                                a_cu, a_die->GetSibling(),
    703 //                                b_cu, b_die->GetSibling(),
    704 //                                compare_state, true, compare_children);
    705 //        }
    706 //
    707 //        return result;
    708 //    }
    709 //
    710 //    if (a_die == NULL)
    711 //        return -1;  // a_die is NULL, yet b_die is non-NULL
    712 //    else
    713 //        return 1;   // a_die is non-NULL, yet b_die is NULL
    714 //
    715 //}
    716 //
    717 //
    718 //int
    719 //DWARFDebugInfoEntry::Compare
    720 //(
    721 //  SymbolFileDWARF* dwarf2Data,
    722 //  const DWARFCompileUnit* cu_a,
    723 //  const DWARFDebugInfoEntry* die_a,
    724 //  const DWARFCompileUnit* cu_a,
    725 //  const DWARFDebugInfoEntry* die_b,
    726 //  CompareState &compare_state
    727 //)
    728 //{
    729 //}
    730 
    731 //----------------------------------------------------------------------
    732 // GetDIENamesAndRanges
    733 //
    734 // Gets the valid address ranges for a given DIE by looking for a
    735 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
    736 // attributes.
    737 //----------------------------------------------------------------------
    738 bool
    739 DWARFDebugInfoEntry::GetDIENamesAndRanges
    740 (
    741     SymbolFileDWARF* dwarf2Data,
    742     const DWARFCompileUnit* cu,
    743     const char * &name,
    744     const char * &mangled,
    745     DWARFDebugRanges::RangeList& ranges,
    746     int& decl_file,
    747     int& decl_line,
    748     int& decl_column,
    749     int& call_file,
    750     int& call_line,
    751     int& call_column,
    752     DWARFExpression *frame_base
    753 ) const
    754 {
    755     if (dwarf2Data == NULL)
    756         return false;
    757 
    758     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
    759     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
    760     std::vector<dw_offset_t> die_offsets;
    761     bool set_frame_base_loclist_addr = false;
    762 
    763     lldb::offset_t offset;
    764     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
    765 
    766     if (abbrevDecl)
    767     {
    768         const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
    769 
    770         if (!debug_info_data.ValidOffset(offset))
    771             return false;
    772 
    773         const uint32_t numAttributes = abbrevDecl->NumAttributes();
    774         uint32_t i;
    775         dw_attr_t attr;
    776         dw_form_t form;
    777         bool do_offset = false;
    778 
    779         for (i=0; i<numAttributes; ++i)
    780         {
    781             abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
    782             DWARFFormValue form_value(form);
    783             if (form_value.ExtractValue(debug_info_data, &offset, cu))
    784             {
    785                 switch (attr)
    786                 {
    787                 case DW_AT_low_pc:
    788                     lo_pc = form_value.Unsigned();
    789 
    790                     if (do_offset)
    791                         hi_pc += lo_pc;
    792                     do_offset = false;
    793                     break;
    794 
    795                 case DW_AT_entry_pc:
    796                     lo_pc = form_value.Unsigned();
    797                     break;
    798 
    799                 case DW_AT_high_pc:
    800                     hi_pc = form_value.Unsigned();
    801                     if (form_value.Form() != DW_FORM_addr)
    802                     {
    803                         if (lo_pc == LLDB_INVALID_ADDRESS)
    804                             do_offset = hi_pc != LLDB_INVALID_ADDRESS;
    805                         else
    806                             hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations
    807                     }
    808                     break;
    809 
    810                 case DW_AT_ranges:
    811                     {
    812                         const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
    813                         debug_ranges->FindRanges(form_value.Unsigned(), ranges);
    814                         // All DW_AT_ranges are relative to the base address of the
    815                         // compile unit. We add the compile unit base address to make
    816                         // sure all the addresses are properly fixed up.
    817                         ranges.Slide(cu->GetBaseAddress());
    818                     }
    819                     break;
    820 
    821                 case DW_AT_name:
    822                     if (name == NULL)
    823                         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
    824                     break;
    825 
    826                 case DW_AT_MIPS_linkage_name:
    827                 case DW_AT_linkage_name:
    828                     if (mangled == NULL)
    829                         mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data());
    830                     break;
    831 
    832                 case DW_AT_abstract_origin:
    833                     die_offsets.push_back(form_value.Reference(cu));
    834                     break;
    835 
    836                 case DW_AT_specification:
    837                     die_offsets.push_back(form_value.Reference(cu));
    838                     break;
    839 
    840                 case DW_AT_decl_file:
    841                     if (decl_file == 0)
    842                         decl_file = form_value.Unsigned();
    843                     break;
    844 
    845                 case DW_AT_decl_line:
    846                     if (decl_line == 0)
    847                         decl_line = form_value.Unsigned();
    848                     break;
    849 
    850                 case DW_AT_decl_column:
    851                     if (decl_column == 0)
    852                         decl_column = form_value.Unsigned();
    853                     break;
    854 
    855                 case DW_AT_call_file:
    856                     if (call_file == 0)
    857                         call_file = form_value.Unsigned();
    858                     break;
    859 
    860                 case DW_AT_call_line:
    861                     if (call_line == 0)
    862                         call_line = form_value.Unsigned();
    863                     break;
    864 
    865                 case DW_AT_call_column:
    866                     if (call_column == 0)
    867                         call_column = form_value.Unsigned();
    868                     break;
    869 
    870                 case DW_AT_frame_base:
    871                     if (frame_base)
    872                     {
    873                         if (form_value.BlockData())
    874                         {
    875                             uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
    876                             uint32_t block_length = form_value.Unsigned();
    877                             frame_base->SetOpcodeData(debug_info_data, block_offset, block_length);
    878                         }
    879                         else
    880                         {
    881                             const DataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data();
    882                             const dw_offset_t debug_loc_offset = form_value.Unsigned();
    883 
    884                             size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
    885                             if (loc_list_length > 0)
    886                             {
    887                                 frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
    888                                 if (lo_pc != LLDB_INVALID_ADDRESS)
    889                                 {
    890                                     assert (lo_pc >= cu->GetBaseAddress());
    891                                     frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
    892                                 }
    893                                 else
    894                                 {
    895                                     set_frame_base_loclist_addr = true;
    896                                 }
    897                             }
    898                         }
    899                     }
    900                     break;
    901 
    902                 default:
    903                     break;
    904                 }
    905             }
    906         }
    907     }
    908 
    909     if (ranges.IsEmpty())
    910     {
    911         if (lo_pc != LLDB_INVALID_ADDRESS)
    912         {
    913             if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
    914                 ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc));
    915             else
    916                 ranges.Append(DWARFDebugRanges::Range (lo_pc, 0));
    917         }
    918     }
    919 
    920     if (set_frame_base_loclist_addr)
    921     {
    922         dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
    923         assert (lowest_range_pc >= cu->GetBaseAddress());
    924         frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress());
    925     }
    926 
    927     if (ranges.IsEmpty() || name == NULL || mangled == NULL)
    928     {
    929         std::vector<dw_offset_t>::const_iterator pos;
    930         std::vector<dw_offset_t>::const_iterator end = die_offsets.end();
    931         for (pos = die_offsets.begin(); pos != end; ++pos)
    932         {
    933             DWARFCompileUnitSP cu_sp_ptr;
    934             const DWARFDebugInfoEntry* die = NULL;
    935             dw_offset_t die_offset = *pos;
    936             if (die_offset != DW_INVALID_OFFSET)
    937             {
    938                 die = dwarf2Data->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
    939                 if (die)
    940                     die->GetDIENamesAndRanges(dwarf2Data, cu_sp_ptr.get(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
    941             }
    942         }
    943     }
    944     return !ranges.IsEmpty();
    945 }
    946 
    947 //----------------------------------------------------------------------
    948 // Dump
    949 //
    950 // Dumps a debug information entry and all of it's attributes to the
    951 // specified stream.
    952 //----------------------------------------------------------------------
    953 void
    954 DWARFDebugInfoEntry::Dump
    955 (
    956     SymbolFileDWARF* dwarf2Data,
    957     const DWARFCompileUnit* cu,
    958     Stream &s,
    959     uint32_t recurse_depth
    960 ) const
    961 {
    962     const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
    963     lldb::offset_t offset = m_offset;
    964 
    965     if (debug_info_data.ValidOffset(offset))
    966     {
    967         dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
    968 
    969         s.Printf("\n0x%8.8x: ", m_offset);
    970         s.Indent();
    971         if (abbrCode != m_abbr_idx)
    972         {
    973             s.Printf( "error: DWARF has been modified\n");
    974         }
    975         else if (abbrCode)
    976         {
    977             const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode);
    978 
    979             if (abbrevDecl)
    980             {
    981                 s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
    982                 s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' ');
    983 
    984                 // Dump all data in the .debug_info for the attributes
    985                 const uint32_t numAttributes = abbrevDecl->NumAttributes();
    986                 uint32_t i;
    987                 dw_attr_t attr;
    988                 dw_form_t form;
    989                 for (i=0; i<numAttributes; ++i)
    990                 {
    991                     abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
    992 
    993                     DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form);
    994                 }
    995 
    996                 const DWARFDebugInfoEntry* child = GetFirstChild();
    997                 if (recurse_depth > 0 && child)
    998                 {
    999                     s.IndentMore();
   1000 
   1001                     while (child)
   1002                     {
   1003                         child->Dump(dwarf2Data, cu, s, recurse_depth-1);
   1004                         child = child->GetSibling();
   1005                     }
   1006                     s.IndentLess();
   1007                 }
   1008             }
   1009             else
   1010                 s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode);
   1011         }
   1012         else
   1013         {
   1014             s.Printf( "NULL\n");
   1015         }
   1016     }
   1017 }
   1018 
   1019 void
   1020 DWARFDebugInfoEntry::DumpLocation
   1021 (
   1022     SymbolFileDWARF* dwarf2Data,
   1023     DWARFCompileUnit* cu,
   1024     Stream &s
   1025 ) const
   1026 {
   1027     const DWARFDebugInfoEntry *cu_die = cu->GetCompileUnitDIEOnly();
   1028     const char *cu_name = NULL;
   1029     if (cu_die != NULL)
   1030         cu_name = cu_die->GetName (dwarf2Data, cu);
   1031     const char *obj_file_name = NULL;
   1032     ObjectFile *obj_file = dwarf2Data->GetObjectFile();
   1033     if (obj_file)
   1034         obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString();
   1035     const char *die_name = GetName (dwarf2Data, cu);
   1036     s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)",
   1037               cu->GetOffset(),
   1038               GetOffset(),
   1039               die_name ? die_name : "",
   1040               cu_name ? cu_name : "<NULL>",
   1041               obj_file_name ? obj_file_name : "<NULL>");
   1042 }
   1043 
   1044 //----------------------------------------------------------------------
   1045 // DumpAttribute
   1046 //
   1047 // Dumps a debug information entry attribute along with it's form. Any
   1048 // special display of attributes is done (disassemble location lists,
   1049 // show enumeration values for attributes, etc).
   1050 //----------------------------------------------------------------------
   1051 void
   1052 DWARFDebugInfoEntry::DumpAttribute
   1053 (
   1054     SymbolFileDWARF* dwarf2Data,
   1055     const DWARFCompileUnit* cu,
   1056     const DataExtractor& debug_info_data,
   1057     lldb::offset_t *offset_ptr,
   1058     Stream &s,
   1059     dw_attr_t attr,
   1060     dw_form_t form
   1061 )
   1062 {
   1063     bool verbose    = s.GetVerbose();
   1064     bool show_form  = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
   1065 
   1066     const DataExtractor* debug_str_data = dwarf2Data ? &dwarf2Data->get_debug_str_data() : NULL;
   1067     if (verbose)
   1068         s.Offset (*offset_ptr);
   1069     else
   1070         s.Printf ("            ");
   1071     s.Indent(DW_AT_value_to_name(attr));
   1072 
   1073     if (show_form)
   1074     {
   1075         s.Printf( "[%s", DW_FORM_value_to_name(form));
   1076     }
   1077 
   1078     DWARFFormValue form_value(form);
   1079 
   1080     if (!form_value.ExtractValue(debug_info_data, offset_ptr, cu))
   1081         return;
   1082 
   1083     if (show_form)
   1084     {
   1085         if (form == DW_FORM_indirect)
   1086         {
   1087             s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form()));
   1088         }
   1089 
   1090         s.PutCString("] ");
   1091     }
   1092 
   1093     s.PutCString("( ");
   1094 
   1095     // Always dump form value if verbose is enabled
   1096     if (verbose)
   1097     {
   1098         form_value.Dump(s, debug_str_data, cu);
   1099     }
   1100 
   1101 
   1102     // Check to see if we have any special attribute formatters
   1103     switch (attr)
   1104     {
   1105     case DW_AT_stmt_list:
   1106         if ( verbose ) s.PutCString(" ( ");
   1107         s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
   1108         if ( verbose ) s.PutCString(" )");
   1109         break;
   1110 
   1111     case DW_AT_language:
   1112         if ( verbose ) s.PutCString(" ( ");
   1113         s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
   1114         if ( verbose ) s.PutCString(" )");
   1115         break;
   1116 
   1117     case DW_AT_encoding:
   1118         if ( verbose ) s.PutCString(" ( ");
   1119         s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
   1120         if ( verbose ) s.PutCString(" )");
   1121         break;
   1122 
   1123     case DW_AT_frame_base:
   1124     case DW_AT_location:
   1125     case DW_AT_data_member_location:
   1126         {
   1127             const uint8_t* blockData = form_value.BlockData();
   1128             if (blockData)
   1129             {
   1130                 if (!verbose)
   1131                     form_value.Dump(s, debug_str_data, cu);
   1132 
   1133                 // Location description is inlined in data in the form value
   1134                 DataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
   1135                 if ( verbose ) s.PutCString(" ( ");
   1136                 print_dwarf_expression (s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
   1137                 if ( verbose ) s.PutCString(" )");
   1138             }
   1139             else
   1140             {
   1141                 // We have a location list offset as the value that is
   1142                 // the offset into the .debug_loc section that describes
   1143                 // the value over it's lifetime
   1144                 uint64_t debug_loc_offset = form_value.Unsigned();
   1145                 if (dwarf2Data)
   1146                 {
   1147                     if ( !verbose )
   1148                         form_value.Dump(s, debug_str_data, cu);
   1149                     DWARFLocationList::Dump(s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
   1150                 }
   1151                 else
   1152                 {
   1153                     if ( !verbose )
   1154                         form_value.Dump(s, NULL, cu);
   1155                 }
   1156             }
   1157         }
   1158         break;
   1159 
   1160     case DW_AT_abstract_origin:
   1161     case DW_AT_specification:
   1162         {
   1163             uint64_t abstract_die_offset = form_value.Reference(cu);
   1164             form_value.Dump(s, debug_str_data, cu);
   1165         //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
   1166             if ( verbose ) s.PutCString(" ( ");
   1167             GetName(dwarf2Data, cu, abstract_die_offset, s);
   1168             if ( verbose ) s.PutCString(" )");
   1169         }
   1170         break;
   1171 
   1172     case DW_AT_type:
   1173         {
   1174             uint64_t type_die_offset = form_value.Reference(cu);
   1175             if (!verbose)
   1176                 form_value.Dump(s, debug_str_data, cu);
   1177             s.PutCString(" ( ");
   1178             AppendTypeName(dwarf2Data, cu, type_die_offset, s);
   1179             s.PutCString(" )");
   1180         }
   1181         break;
   1182 
   1183     case DW_AT_ranges:
   1184         {
   1185             if ( !verbose )
   1186                 form_value.Dump(s, debug_str_data, cu);
   1187             lldb::offset_t ranges_offset = form_value.Unsigned();
   1188             dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
   1189             if (dwarf2Data)
   1190                 DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
   1191         }
   1192         break;
   1193 
   1194     default:
   1195         if ( !verbose )
   1196             form_value.Dump(s, debug_str_data, cu);
   1197         break;
   1198     }
   1199 
   1200     s.PutCString(" )\n");
   1201 }
   1202 
   1203 //----------------------------------------------------------------------
   1204 // Get all attribute values for a given DIE, including following any
   1205 // specification or abstract origin attributes and including those in
   1206 // the results. Any duplicate attributes will have the first instance
   1207 // take precedence (this can happen for declaration attributes).
   1208 //----------------------------------------------------------------------
   1209 size_t
   1210 DWARFDebugInfoEntry::GetAttributes
   1211 (
   1212     SymbolFileDWARF* dwarf2Data,
   1213     const DWARFCompileUnit* cu,
   1214     const uint8_t *fixed_form_sizes,
   1215     DWARFDebugInfoEntry::Attributes& attributes,
   1216     uint32_t curr_depth
   1217 ) const
   1218 {
   1219     lldb::offset_t offset;
   1220     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
   1221 
   1222     if (abbrevDecl)
   1223     {
   1224         const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
   1225 
   1226         if (fixed_form_sizes == NULL)
   1227             fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(cu->GetAddressByteSize());
   1228 
   1229         const uint32_t num_attributes = abbrevDecl->NumAttributes();
   1230         uint32_t i;
   1231         dw_attr_t attr;
   1232         dw_form_t form;
   1233         DWARFFormValue form_value;
   1234         for (i=0; i<num_attributes; ++i)
   1235         {
   1236             abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form);
   1237 
   1238             // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
   1239             // attributes, the depth will be non-zero. We need to omit certain
   1240             // attributes that don't make sense.
   1241             switch (attr)
   1242             {
   1243             case DW_AT_sibling:
   1244             case DW_AT_declaration:
   1245                 if (curr_depth > 0)
   1246                 {
   1247                     // This attribute doesn't make sense when combined with
   1248                     // the DIE that references this DIE. We know a DIE is
   1249                     // referencing this DIE because curr_depth is not zero
   1250                     break;
   1251                 }
   1252                 // Fall through...
   1253             default:
   1254                 attributes.Append(cu, offset, attr, form);
   1255                 break;
   1256             }
   1257 
   1258             if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))
   1259             {
   1260                 form_value.SetForm(form);
   1261                 if (form_value.ExtractValue(debug_info_data, &offset, cu))
   1262                 {
   1263                     const DWARFDebugInfoEntry* die = NULL;
   1264                     dw_offset_t die_offset = form_value.Reference(cu);
   1265                     if (cu->ContainsDIEOffset(die_offset))
   1266                     {
   1267                         die = const_cast<DWARFCompileUnit*>(cu)->GetDIEPtr(die_offset);
   1268                         if (die)
   1269                             die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes, curr_depth + 1);
   1270                     }
   1271                     else
   1272                     {
   1273                         DWARFCompileUnitSP cu_sp_ptr;
   1274                         die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(die_offset, &cu_sp_ptr);
   1275                         if (die)
   1276                             die->GetAttributes(dwarf2Data, cu_sp_ptr.get(), fixed_form_sizes, attributes, curr_depth + 1);
   1277                     }
   1278                 }
   1279             }
   1280             else
   1281             {
   1282                 const uint8_t fixed_skip_size = fixed_form_sizes [form];
   1283                 if (fixed_skip_size)
   1284                     offset += fixed_skip_size;
   1285                 else
   1286                     DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
   1287             }
   1288         }
   1289     }
   1290     else
   1291     {
   1292         attributes.Clear();
   1293     }
   1294     return attributes.Size();
   1295 
   1296 }
   1297 
   1298 //----------------------------------------------------------------------
   1299 // GetAttributeValue
   1300 //
   1301 // Get the value of an attribute and return the .debug_info offset of the
   1302 // attribute if it was properly extracted into form_value, or zero
   1303 // if we fail since an offset of zero is invalid for an attribute (it
   1304 // would be a compile unit header).
   1305 //----------------------------------------------------------------------
   1306 dw_offset_t
   1307 DWARFDebugInfoEntry::GetAttributeValue
   1308 (
   1309     SymbolFileDWARF* dwarf2Data,
   1310     const DWARFCompileUnit* cu,
   1311     const dw_attr_t attr,
   1312     DWARFFormValue& form_value,
   1313     dw_offset_t* end_attr_offset_ptr
   1314 ) const
   1315 {
   1316     lldb::offset_t offset;
   1317     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
   1318 
   1319     if (abbrevDecl)
   1320     {
   1321         uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
   1322 
   1323         if (attr_idx != DW_INVALID_INDEX)
   1324         {
   1325             const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
   1326 
   1327             uint32_t idx=0;
   1328             while (idx<attr_idx)
   1329                 DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
   1330 
   1331             const dw_offset_t attr_offset = offset;
   1332             form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
   1333             if (form_value.ExtractValue(debug_info_data, &offset, cu))
   1334             {
   1335                 if (end_attr_offset_ptr)
   1336                     *end_attr_offset_ptr = offset;
   1337                 return attr_offset;
   1338             }
   1339         }
   1340     }
   1341 
   1342     return 0;
   1343 }
   1344 
   1345 //----------------------------------------------------------------------
   1346 // GetAttributeValueAsString
   1347 //
   1348 // Get the value of an attribute as a string return it. The resulting
   1349 // pointer to the string data exists within the supplied SymbolFileDWARF
   1350 // and will only be available as long as the SymbolFileDWARF is still around
   1351 // and it's content doesn't change.
   1352 //----------------------------------------------------------------------
   1353 const char*
   1354 DWARFDebugInfoEntry::GetAttributeValueAsString
   1355 (
   1356     SymbolFileDWARF* dwarf2Data,
   1357     const DWARFCompileUnit* cu,
   1358     const dw_attr_t attr,
   1359     const char* fail_value) const
   1360 {
   1361     DWARFFormValue form_value;
   1362     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
   1363         return form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1364     return fail_value;
   1365 }
   1366 
   1367 //----------------------------------------------------------------------
   1368 // GetAttributeValueAsUnsigned
   1369 //
   1370 // Get the value of an attribute as unsigned and return it.
   1371 //----------------------------------------------------------------------
   1372 uint64_t
   1373 DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
   1374 (
   1375     SymbolFileDWARF* dwarf2Data,
   1376     const DWARFCompileUnit* cu,
   1377     const dw_attr_t attr,
   1378     uint64_t fail_value
   1379 ) const
   1380 {
   1381     DWARFFormValue form_value;
   1382     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
   1383         return form_value.Unsigned();
   1384     return fail_value;
   1385 }
   1386 
   1387 //----------------------------------------------------------------------
   1388 // GetAttributeValueAsSigned
   1389 //
   1390 // Get the value of an attribute a signed value and return it.
   1391 //----------------------------------------------------------------------
   1392 int64_t
   1393 DWARFDebugInfoEntry::GetAttributeValueAsSigned
   1394 (
   1395     SymbolFileDWARF* dwarf2Data,
   1396     const DWARFCompileUnit* cu,
   1397     const dw_attr_t attr,
   1398     int64_t fail_value
   1399 ) const
   1400 {
   1401     DWARFFormValue form_value;
   1402     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
   1403         return form_value.Signed();
   1404     return fail_value;
   1405 }
   1406 
   1407 //----------------------------------------------------------------------
   1408 // GetAttributeValueAsReference
   1409 //
   1410 // Get the value of an attribute as reference and fix up and compile
   1411 // unit relative offsets as needed.
   1412 //----------------------------------------------------------------------
   1413 uint64_t
   1414 DWARFDebugInfoEntry::GetAttributeValueAsReference
   1415 (
   1416     SymbolFileDWARF* dwarf2Data,
   1417     const DWARFCompileUnit* cu,
   1418     const dw_attr_t attr,
   1419     uint64_t fail_value
   1420 ) const
   1421 {
   1422     DWARFFormValue form_value;
   1423     if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
   1424         return form_value.Reference(cu);
   1425     return fail_value;
   1426 }
   1427 
   1428 //----------------------------------------------------------------------
   1429 // GetAttributeHighPC
   1430 //
   1431 // Get the hi_pc, adding hi_pc to lo_pc when specified
   1432 // as an <offset-from-low-pc>.
   1433 //
   1434 // Returns the hi_pc or fail_value.
   1435 //----------------------------------------------------------------------
   1436 dw_addr_t
   1437 DWARFDebugInfoEntry::GetAttributeHighPC
   1438 (
   1439     SymbolFileDWARF* dwarf2Data,
   1440     const DWARFCompileUnit* cu,
   1441     dw_addr_t lo_pc,
   1442     uint64_t fail_value
   1443 ) const
   1444 {
   1445     DWARFFormValue form_value;
   1446 
   1447     if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value))
   1448     {
   1449         dw_addr_t hi_pc = form_value.Unsigned();
   1450         if (form_value.Form() != DW_FORM_addr)
   1451             hi_pc += lo_pc; // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
   1452         return hi_pc;
   1453     }
   1454     return fail_value;
   1455 }
   1456 
   1457 //----------------------------------------------------------------------
   1458 // GetAttributeAddressRange
   1459 //
   1460 // Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified
   1461 // as an <offset-from-low-pc>.
   1462 //
   1463 // Returns true or sets lo_pc and hi_pc to fail_value.
   1464 //----------------------------------------------------------------------
   1465 bool
   1466 DWARFDebugInfoEntry::GetAttributeAddressRange
   1467 (
   1468     SymbolFileDWARF* dwarf2Data,
   1469     const DWARFCompileUnit* cu,
   1470     dw_addr_t& lo_pc,
   1471     dw_addr_t& hi_pc,
   1472     uint64_t fail_value
   1473 ) const
   1474 {
   1475     lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, fail_value);
   1476     if (lo_pc != fail_value)
   1477     {
   1478         hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value);
   1479         if (hi_pc != fail_value)
   1480           return true;
   1481     }
   1482     lo_pc = fail_value;
   1483     hi_pc = fail_value;
   1484     return false;
   1485 }
   1486 //----------------------------------------------------------------------
   1487 // GetAttributeValueAsLocation
   1488 //
   1489 // Get the value of an attribute as reference and fix up and compile
   1490 // unit relative offsets as needed.
   1491 //----------------------------------------------------------------------
   1492 dw_offset_t
   1493 DWARFDebugInfoEntry::GetAttributeValueAsLocation
   1494 (
   1495     SymbolFileDWARF* dwarf2Data,
   1496     const DWARFCompileUnit* cu,
   1497     const dw_attr_t attr,
   1498     DataExtractor& location_data,
   1499     uint32_t &block_size
   1500 ) const
   1501 {
   1502     block_size = 0;
   1503     DWARFFormValue form_value;
   1504 
   1505     // Empty out data in case we don't find anything
   1506     location_data.Clear();
   1507     dw_offset_t end_addr_offset = DW_INVALID_OFFSET;
   1508     const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset);
   1509     if (attr_offset)
   1510     {
   1511         const uint8_t* blockData = form_value.BlockData();
   1512         if (blockData)
   1513         {
   1514             // We have an inlined location list in the .debug_info section
   1515             const DataExtractor& debug_info = dwarf2Data->get_debug_info_data();
   1516             dw_offset_t block_offset = blockData - debug_info.GetDataStart();
   1517             block_size = (end_addr_offset - attr_offset) - form_value.Unsigned();
   1518             location_data.SetData(debug_info, block_offset, block_size);
   1519         }
   1520         else
   1521         {
   1522             // We have a location list offset as the value that is
   1523             // the offset into the .debug_loc section that describes
   1524             // the value over it's lifetime
   1525             lldb::offset_t debug_loc_offset = form_value.Unsigned();
   1526             if (dwarf2Data)
   1527             {
   1528                 assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
   1529                 return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data);
   1530             }
   1531         }
   1532     }
   1533     return attr_offset;
   1534 }
   1535 
   1536 //----------------------------------------------------------------------
   1537 // GetName
   1538 //
   1539 // Get value of the DW_AT_name attribute and return it if one exists,
   1540 // else return NULL.
   1541 //----------------------------------------------------------------------
   1542 const char*
   1543 DWARFDebugInfoEntry::GetName
   1544 (
   1545     SymbolFileDWARF* dwarf2Data,
   1546     const DWARFCompileUnit* cu
   1547 ) const
   1548 {
   1549     DWARFFormValue form_value;
   1550     if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
   1551         return form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1552     else
   1553     {
   1554         if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
   1555         {
   1556             DWARFCompileUnitSP cu_sp_ptr;
   1557             const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
   1558             if (die)
   1559                 return die->GetName(dwarf2Data, cu_sp_ptr.get());
   1560         }
   1561     }
   1562     return NULL;
   1563 }
   1564 
   1565 
   1566 //----------------------------------------------------------------------
   1567 // GetMangledName
   1568 //
   1569 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if
   1570 // one exists, else return the value of the DW_AT_name attribute
   1571 //----------------------------------------------------------------------
   1572 const char*
   1573 DWARFDebugInfoEntry::GetMangledName
   1574 (
   1575     SymbolFileDWARF* dwarf2Data,
   1576     const DWARFCompileUnit* cu,
   1577     bool substitute_name_allowed
   1578 ) const
   1579 {
   1580     const char* name = NULL;
   1581     DWARFFormValue form_value;
   1582 
   1583     if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
   1584         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1585 
   1586     if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
   1587         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1588 
   1589     if (substitute_name_allowed && name == NULL)
   1590     {
   1591         if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
   1592             name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1593     }
   1594     return name;
   1595 }
   1596 
   1597 
   1598 //----------------------------------------------------------------------
   1599 // GetPubname
   1600 //
   1601 // Get value the name for a DIE as it should appear for a
   1602 // .debug_pubnames or .debug_pubtypes section.
   1603 //----------------------------------------------------------------------
   1604 const char*
   1605 DWARFDebugInfoEntry::GetPubname
   1606 (
   1607     SymbolFileDWARF* dwarf2Data,
   1608     const DWARFCompileUnit* cu
   1609 ) const
   1610 {
   1611     const char* name = NULL;
   1612     if (!dwarf2Data)
   1613         return name;
   1614 
   1615     DWARFFormValue form_value;
   1616 
   1617     if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
   1618         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1619     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
   1620         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1621     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
   1622         name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1623     else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
   1624     {
   1625         // The specification DIE may be in another compile unit so we need
   1626         // to get a die and its compile unit.
   1627         DWARFCompileUnitSP cu_sp_ptr;
   1628         const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(cu), &cu_sp_ptr);
   1629         if (die)
   1630             return die->GetPubname(dwarf2Data, cu_sp_ptr.get());
   1631     }
   1632     return name;
   1633 }
   1634 
   1635 
   1636 //----------------------------------------------------------------------
   1637 // GetName
   1638 //
   1639 // Get value of the DW_AT_name attribute for a debug information entry
   1640 // that exists at offset "die_offset" and place that value into the
   1641 // supplied stream object. If the DIE is a NULL object "NULL" is placed
   1642 // into the stream, and if no DW_AT_name attribute exists for the DIE
   1643 // then nothing is printed.
   1644 //----------------------------------------------------------------------
   1645 bool
   1646 DWARFDebugInfoEntry::GetName
   1647 (
   1648     SymbolFileDWARF* dwarf2Data,
   1649     const DWARFCompileUnit* cu,
   1650     const dw_offset_t die_offset,
   1651     Stream &s
   1652 )
   1653 {
   1654     if (dwarf2Data == NULL)
   1655     {
   1656         s.PutCString("NULL");
   1657         return false;
   1658     }
   1659 
   1660     DWARFDebugInfoEntry die;
   1661     lldb::offset_t offset = die_offset;
   1662     if (die.Extract(dwarf2Data, cu, &offset))
   1663     {
   1664         if (die.IsNULL())
   1665         {
   1666             s.PutCString("NULL");
   1667             return true;
   1668         }
   1669         else
   1670         {
   1671             DWARFFormValue form_value;
   1672             if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
   1673             {
   1674                 const char* name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1675                 if (name)
   1676                 {
   1677                     s.PutCString(name);
   1678                     return true;
   1679                 }
   1680             }
   1681         }
   1682     }
   1683     return false;
   1684 }
   1685 
   1686 //----------------------------------------------------------------------
   1687 // AppendTypeName
   1688 //
   1689 // Follows the type name definition down through all needed tags to
   1690 // end up with a fully qualified type name and dump the results to
   1691 // the supplied stream. This is used to show the name of types given
   1692 // a type identifier.
   1693 //----------------------------------------------------------------------
   1694 bool
   1695 DWARFDebugInfoEntry::AppendTypeName
   1696 (
   1697     SymbolFileDWARF* dwarf2Data,
   1698     const DWARFCompileUnit* cu,
   1699     const dw_offset_t die_offset,
   1700     Stream &s
   1701 )
   1702 {
   1703     if (dwarf2Data == NULL)
   1704     {
   1705         s.PutCString("NULL");
   1706         return false;
   1707     }
   1708 
   1709     DWARFDebugInfoEntry die;
   1710     lldb::offset_t offset = die_offset;
   1711     if (die.Extract(dwarf2Data, cu, &offset))
   1712     {
   1713         if (die.IsNULL())
   1714         {
   1715             s.PutCString("NULL");
   1716             return true;
   1717         }
   1718         else
   1719         {
   1720             const char* name = die.GetPubname(dwarf2Data, cu);
   1721         //  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
   1722         //      name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
   1723             if (name)
   1724                 s.PutCString(name);
   1725             else
   1726             {
   1727                 bool result = true;
   1728                 const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
   1729 
   1730                 if (abbrevDecl == NULL)
   1731                     return false;
   1732 
   1733                 switch (abbrevDecl->Tag())
   1734                 {
   1735                 case DW_TAG_array_type:         break;  // print out a "[]" after printing the full type of the element below
   1736                 case DW_TAG_base_type:          s.PutCString("base ");         break;
   1737                 case DW_TAG_class_type:         s.PutCString("class ");            break;
   1738                 case DW_TAG_const_type:         s.PutCString("const ");            break;
   1739                 case DW_TAG_enumeration_type:   s.PutCString("enum ");         break;
   1740                 case DW_TAG_file_type:          s.PutCString("file ");         break;
   1741                 case DW_TAG_interface_type:     s.PutCString("interface ");        break;
   1742                 case DW_TAG_packed_type:        s.PutCString("packed ");       break;
   1743                 case DW_TAG_pointer_type:       break;  // print out a '*' after printing the full type below
   1744                 case DW_TAG_ptr_to_member_type: break;  // print out a '*' after printing the full type below
   1745                 case DW_TAG_reference_type:     break;  // print out a '&' after printing the full type below
   1746                 case DW_TAG_restrict_type:      s.PutCString("restrict ");     break;
   1747                 case DW_TAG_set_type:           s.PutCString("set ");          break;
   1748                 case DW_TAG_shared_type:        s.PutCString("shared ");       break;
   1749                 case DW_TAG_string_type:        s.PutCString("string ");       break;
   1750                 case DW_TAG_structure_type:     s.PutCString("struct ");       break;
   1751                 case DW_TAG_subrange_type:      s.PutCString("subrange ");     break;
   1752                 case DW_TAG_subroutine_type:    s.PutCString("function ");     break;
   1753                 case DW_TAG_thrown_type:        s.PutCString("thrown ");       break;
   1754                 case DW_TAG_union_type:         s.PutCString("union ");            break;
   1755                 case DW_TAG_unspecified_type:   s.PutCString("unspecified ");  break;
   1756                 case DW_TAG_volatile_type:      s.PutCString("volatile ");     break;
   1757                 default:
   1758                     return false;
   1759                 }
   1760 
   1761                 // Follow the DW_AT_type if possible
   1762                 DWARFFormValue form_value;
   1763                 if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
   1764                 {
   1765                     uint64_t next_die_offset = form_value.Reference(cu);
   1766                     result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
   1767                 }
   1768 
   1769                 switch (abbrevDecl->Tag())
   1770                 {
   1771                 case DW_TAG_array_type:         s.PutCString("[]");    break;
   1772                 case DW_TAG_pointer_type:       s.PutChar('*');    break;
   1773                 case DW_TAG_ptr_to_member_type: s.PutChar('*');    break;
   1774                 case DW_TAG_reference_type:     s.PutChar('&');    break;
   1775                 default:
   1776                     break;
   1777                 }
   1778                 return result;
   1779             }
   1780         }
   1781     }
   1782     return false;
   1783 }
   1784 
   1785 bool
   1786 DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const
   1787 {
   1788     if (die)
   1789     {
   1790         const dw_offset_t die_offset = die->GetOffset();
   1791         if (die_offset > GetOffset())
   1792         {
   1793             const DWARFDebugInfoEntry *sibling = GetSibling();
   1794             assert (sibling); // TODO: take this out
   1795             if (sibling)
   1796                 return die_offset < sibling->GetOffset();
   1797         }
   1798     }
   1799     return false;
   1800 }
   1801 
   1802 //----------------------------------------------------------------------
   1803 // BuildAddressRangeTable
   1804 //----------------------------------------------------------------------
   1805 void
   1806 DWARFDebugInfoEntry::BuildAddressRangeTable
   1807 (
   1808     SymbolFileDWARF* dwarf2Data,
   1809     const DWARFCompileUnit* cu,
   1810     DWARFDebugAranges* debug_aranges
   1811 ) const
   1812 {
   1813     if (m_tag)
   1814     {
   1815         if (m_tag == DW_TAG_subprogram)
   1816         {
   1817             dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
   1818             dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
   1819             if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
   1820             {
   1821                 /// 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);
   1822                 debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
   1823             }
   1824         }
   1825 
   1826 
   1827         const DWARFDebugInfoEntry* child = GetFirstChild();
   1828         while (child)
   1829         {
   1830             child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
   1831             child = child->GetSibling();
   1832         }
   1833     }
   1834 }
   1835 
   1836 //----------------------------------------------------------------------
   1837 // BuildFunctionAddressRangeTable
   1838 //
   1839 // This function is very similar to the BuildAddressRangeTable function
   1840 // except that the actual DIE offset for the function is placed in the
   1841 // table instead of the compile unit offset (which is the way the
   1842 // standard .debug_aranges section does it).
   1843 //----------------------------------------------------------------------
   1844 void
   1845 DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
   1846 (
   1847     SymbolFileDWARF* dwarf2Data,
   1848     const DWARFCompileUnit* cu,
   1849     DWARFDebugAranges* debug_aranges
   1850 ) const
   1851 {
   1852     if (m_tag)
   1853     {
   1854         if (m_tag == DW_TAG_subprogram)
   1855         {
   1856             dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
   1857             dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
   1858             if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
   1859             {
   1860             //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
   1861                 debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
   1862             }
   1863         }
   1864 
   1865         const DWARFDebugInfoEntry* child = GetFirstChild();
   1866         while (child)
   1867         {
   1868             child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
   1869             child = child->GetSibling();
   1870         }
   1871     }
   1872 }
   1873 
   1874 void
   1875 DWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data,
   1876                                          DWARFCompileUnit* cu,
   1877                                          DWARFDIECollection &decl_context_dies) const
   1878 {
   1879     const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
   1880     if (parent_decl_ctx_die && parent_decl_ctx_die != this)
   1881     {
   1882         decl_context_dies.Append(parent_decl_ctx_die);
   1883         parent_decl_ctx_die->GetDeclContextDIEs (dwarf2Data, cu, decl_context_dies);
   1884     }
   1885 }
   1886 
   1887 void
   1888 DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
   1889                                           DWARFCompileUnit* cu,
   1890                                           DWARFDeclContext &dwarf_decl_ctx) const
   1891 {
   1892     const dw_tag_t tag = Tag();
   1893     if (tag != DW_TAG_compile_unit)
   1894     {
   1895         dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
   1896         const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
   1897         if (parent_decl_ctx_die && parent_decl_ctx_die != this)
   1898         {
   1899             if (parent_decl_ctx_die->Tag() != DW_TAG_compile_unit)
   1900                 parent_decl_ctx_die->GetDWARFDeclContext (dwarf2Data, cu, dwarf_decl_ctx);
   1901         }
   1902     }
   1903 }
   1904 
   1905 
   1906 bool
   1907 DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
   1908                                               DWARFCompileUnit* cu,
   1909                                               const DWARFDeclContext &dwarf_decl_ctx) const
   1910 {
   1911 
   1912     DWARFDeclContext this_dwarf_decl_ctx;
   1913     GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx);
   1914     return this_dwarf_decl_ctx == dwarf_decl_ctx;
   1915 }
   1916 
   1917 const DWARFDebugInfoEntry *
   1918 DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
   1919 											  DWARFCompileUnit* cu) const
   1920 {
   1921 	DWARFDebugInfoEntry::Attributes attributes;
   1922 	GetAttributes(dwarf2Data, cu, NULL, attributes);
   1923 	return GetParentDeclContextDIE (dwarf2Data, cu, attributes);
   1924 }
   1925 
   1926 const DWARFDebugInfoEntry *
   1927 DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
   1928 											  DWARFCompileUnit* cu,
   1929 											  const DWARFDebugInfoEntry::Attributes& attributes) const
   1930 {
   1931 	const DWARFDebugInfoEntry * die = this;
   1932 
   1933 	while (die != NULL)
   1934 	{
   1935 		// If this is the original DIE that we are searching for a declaration
   1936 		// for, then don't look in the cache as we don't want our own decl
   1937 		// context to be our decl context...
   1938 		if (die != this)
   1939 		{
   1940 			switch (die->Tag())
   1941 			{
   1942 				case DW_TAG_compile_unit:
   1943 				case DW_TAG_namespace:
   1944 				case DW_TAG_structure_type:
   1945 				case DW_TAG_union_type:
   1946 				case DW_TAG_class_type:
   1947 					return die;
   1948 
   1949 				default:
   1950 					break;
   1951 			}
   1952 		}
   1953 
   1954 		dw_offset_t die_offset;
   1955 
   1956 		die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_specification, DW_INVALID_OFFSET);
   1957 		if (die_offset != DW_INVALID_OFFSET)
   1958 		{
   1959 			const DWARFDebugInfoEntry *spec_die = cu->GetDIEPtr (die_offset);
   1960 			if (spec_die)
   1961 			{
   1962 				const DWARFDebugInfoEntry *spec_die_decl_ctx_die = spec_die->GetParentDeclContextDIE (dwarf2Data, cu);
   1963 				if (spec_die_decl_ctx_die)
   1964 					return spec_die_decl_ctx_die;
   1965 			}
   1966 		}
   1967 
   1968         die_offset = attributes.FormValueAsUnsigned(dwarf2Data, DW_AT_abstract_origin, DW_INVALID_OFFSET);
   1969 		if (die_offset != DW_INVALID_OFFSET)
   1970 		{
   1971 			const DWARFDebugInfoEntry *abs_die = cu->GetDIEPtr (die_offset);
   1972 			if (abs_die)
   1973 			{
   1974 				const DWARFDebugInfoEntry *abs_die_decl_ctx_die = abs_die->GetParentDeclContextDIE (dwarf2Data, cu);
   1975 				if (abs_die_decl_ctx_die)
   1976 					return abs_die_decl_ctx_die;
   1977 			}
   1978 		}
   1979 
   1980 		die = die->GetParent();
   1981 	}
   1982     return NULL;
   1983 }
   1984 
   1985 
   1986 const char *
   1987 DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
   1988 									   DWARFCompileUnit* cu,
   1989 									   std::string &storage) const
   1990 {
   1991 	DWARFDebugInfoEntry::Attributes attributes;
   1992 	GetAttributes(dwarf2Data, cu, NULL, attributes);
   1993 	return GetQualifiedName (dwarf2Data, cu, attributes, storage);
   1994 }
   1995 
   1996 const char*
   1997 DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
   1998 									   DWARFCompileUnit* cu,
   1999 									   const DWARFDebugInfoEntry::Attributes& attributes,
   2000 									   std::string &storage) const
   2001 {
   2002 
   2003 	const char *name = GetName (dwarf2Data, cu);
   2004 
   2005 	if (name)
   2006 	{
   2007 		const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
   2008 		storage.clear();
   2009 		// TODO: change this to get the correct decl context parent....
   2010 		while (parent_decl_ctx_die)
   2011 		{
   2012 			const dw_tag_t parent_tag = parent_decl_ctx_die->Tag();
   2013 			switch (parent_tag)
   2014 			{
   2015                 case DW_TAG_namespace:
   2016 				{
   2017 					const char *namespace_name = parent_decl_ctx_die->GetName (dwarf2Data, cu);
   2018 					if (namespace_name)
   2019 					{
   2020 						storage.insert (0, "::");
   2021 						storage.insert (0, namespace_name);
   2022 					}
   2023 					else
   2024 					{
   2025 						storage.insert (0, "(anonymous namespace)::");
   2026 					}
   2027 					parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu);
   2028 				}
   2029                     break;
   2030 
   2031                 case DW_TAG_class_type:
   2032                 case DW_TAG_structure_type:
   2033                 case DW_TAG_union_type:
   2034 				{
   2035 					const char *class_union_struct_name = parent_decl_ctx_die->GetName (dwarf2Data, cu);
   2036 
   2037 					if (class_union_struct_name)
   2038 					{
   2039 						storage.insert (0, "::");
   2040 						storage.insert (0, class_union_struct_name);
   2041 					}
   2042 					parent_decl_ctx_die = parent_decl_ctx_die->GetParentDeclContextDIE(dwarf2Data, cu);
   2043 				}
   2044                     break;
   2045 
   2046                 default:
   2047                     parent_decl_ctx_die = NULL;
   2048                     break;
   2049 			}
   2050 		}
   2051 
   2052 		if (storage.empty())
   2053 			storage.append ("::");
   2054 
   2055 		storage.append (name);
   2056 	}
   2057 	if (storage.empty())
   2058 		return NULL;
   2059 	return storage.c_str();
   2060 }
   2061 
   2062 
   2063 //----------------------------------------------------------------------
   2064 // LookupAddress
   2065 //----------------------------------------------------------------------
   2066 bool
   2067 DWARFDebugInfoEntry::LookupAddress
   2068 (
   2069     const dw_addr_t address,
   2070     SymbolFileDWARF* dwarf2Data,
   2071     const DWARFCompileUnit* cu,
   2072     DWARFDebugInfoEntry** function_die,
   2073     DWARFDebugInfoEntry** block_die
   2074 )
   2075 {
   2076     bool found_address = false;
   2077     if (m_tag)
   2078     {
   2079         bool check_children = false;
   2080         bool match_addr_range = false;
   2081     //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
   2082         switch (m_tag)
   2083         {
   2084         case DW_TAG_array_type                 : break;
   2085         case DW_TAG_class_type                 : check_children = true; break;
   2086         case DW_TAG_entry_point                : break;
   2087         case DW_TAG_enumeration_type           : break;
   2088         case DW_TAG_formal_parameter           : break;
   2089         case DW_TAG_imported_declaration       : break;
   2090         case DW_TAG_label                      : break;
   2091         case DW_TAG_lexical_block              : check_children = true; match_addr_range = true; break;
   2092         case DW_TAG_member                     : break;
   2093         case DW_TAG_pointer_type               : break;
   2094         case DW_TAG_reference_type             : break;
   2095         case DW_TAG_compile_unit               : match_addr_range = true; break;
   2096         case DW_TAG_string_type                : break;
   2097         case DW_TAG_structure_type             : check_children = true; break;
   2098         case DW_TAG_subroutine_type            : break;
   2099         case DW_TAG_typedef                    : break;
   2100         case DW_TAG_union_type                 : break;
   2101         case DW_TAG_unspecified_parameters     : break;
   2102         case DW_TAG_variant                    : break;
   2103         case DW_TAG_common_block               : check_children = true; break;
   2104         case DW_TAG_common_inclusion           : break;
   2105         case DW_TAG_inheritance                : break;
   2106         case DW_TAG_inlined_subroutine         : check_children = true; match_addr_range = true; break;
   2107         case DW_TAG_module                     : match_addr_range = true; break;
   2108         case DW_TAG_ptr_to_member_type         : break;
   2109         case DW_TAG_set_type                   : break;
   2110         case DW_TAG_subrange_type              : break;
   2111         case DW_TAG_with_stmt                  : break;
   2112         case DW_TAG_access_declaration         : break;
   2113         case DW_TAG_base_type                  : break;
   2114         case DW_TAG_catch_block                : match_addr_range = true; break;
   2115         case DW_TAG_const_type                 : break;
   2116         case DW_TAG_constant                   : break;
   2117         case DW_TAG_enumerator                 : break;
   2118         case DW_TAG_file_type                  : break;
   2119         case DW_TAG_friend                     : break;
   2120         case DW_TAG_namelist                   : break;
   2121         case DW_TAG_namelist_item              : break;
   2122         case DW_TAG_packed_type                : break;
   2123         case DW_TAG_subprogram                 : match_addr_range = true; break;
   2124         case DW_TAG_template_type_parameter    : break;
   2125         case DW_TAG_template_value_parameter   : break;
   2126         case DW_TAG_thrown_type                : break;
   2127         case DW_TAG_try_block                  : match_addr_range = true; break;
   2128         case DW_TAG_variant_part               : break;
   2129         case DW_TAG_variable                   : break;
   2130         case DW_TAG_volatile_type              : break;
   2131         case DW_TAG_dwarf_procedure            : break;
   2132         case DW_TAG_restrict_type              : break;
   2133         case DW_TAG_interface_type             : break;
   2134         case DW_TAG_namespace                  : check_children = true; break;
   2135         case DW_TAG_imported_module            : break;
   2136         case DW_TAG_unspecified_type           : break;
   2137         case DW_TAG_partial_unit               : break;
   2138         case DW_TAG_imported_unit              : break;
   2139         case DW_TAG_shared_type                : break;
   2140         default: break;
   2141         }
   2142 
   2143         if (match_addr_range)
   2144         {
   2145             dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
   2146             if (lo_pc != LLDB_INVALID_ADDRESS)
   2147             {
   2148                 dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
   2149                 if (hi_pc != LLDB_INVALID_ADDRESS)
   2150                 {
   2151                     //  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);
   2152                     if ((lo_pc <= address) && (address < hi_pc))
   2153                     {
   2154                         found_address = true;
   2155                     //  puts("***MATCH***");
   2156                         switch (m_tag)
   2157                         {
   2158                         case DW_TAG_compile_unit:       // File
   2159                             check_children = ((function_die != NULL) || (block_die != NULL));
   2160                             break;
   2161 
   2162                         case DW_TAG_subprogram:         // Function
   2163                             if (function_die)
   2164                                 *function_die = this;
   2165                             check_children = (block_die != NULL);
   2166                             break;
   2167 
   2168                         case DW_TAG_inlined_subroutine: // Inlined Function
   2169                         case DW_TAG_lexical_block:      // Block { } in code
   2170                             if (block_die)
   2171                             {
   2172                                 *block_die = this;
   2173                                 check_children = true;
   2174                             }
   2175                             break;
   2176 
   2177                         default:
   2178                             check_children = true;
   2179                             break;
   2180                         }
   2181                     }
   2182                 }
   2183                 else
   2184                 {   // compile units may not have a valid high/low pc when there
   2185                     // are address gaps in subroutines so we must always search
   2186                     // if there is no valid high and low PC
   2187                     check_children = (m_tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL));
   2188                 }
   2189             }
   2190             else
   2191             {
   2192                 dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
   2193                 if (debug_ranges_offset != DW_INVALID_OFFSET)
   2194                 {
   2195                     DWARFDebugRanges::RangeList ranges;
   2196                     DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
   2197                     debug_ranges->FindRanges(debug_ranges_offset, ranges);
   2198                     // All DW_AT_ranges are relative to the base address of the
   2199                     // compile unit. We add the compile unit base address to make
   2200                     // sure all the addresses are properly fixed up.
   2201                     ranges.Slide (cu->GetBaseAddress());
   2202                     if (ranges.FindEntryThatContains(address))
   2203                     {
   2204                         found_address = true;
   2205                     //  puts("***MATCH***");
   2206                         switch (m_tag)
   2207                         {
   2208                         case DW_TAG_compile_unit:       // File
   2209                             check_children = ((function_die != NULL) || (block_die != NULL));
   2210                             break;
   2211 
   2212                         case DW_TAG_subprogram:         // Function
   2213                             if (function_die)
   2214                                 *function_die = this;
   2215                             check_children = (block_die != NULL);
   2216                             break;
   2217 
   2218                         case DW_TAG_inlined_subroutine: // Inlined Function
   2219                         case DW_TAG_lexical_block:      // Block { } in code
   2220                             if (block_die)
   2221                             {
   2222                                 *block_die = this;
   2223                                 check_children = true;
   2224                             }
   2225                             break;
   2226 
   2227                         default:
   2228                             check_children = true;
   2229                             break;
   2230                         }
   2231                     }
   2232                     else
   2233                     {
   2234                         check_children = false;
   2235                     }
   2236                 }
   2237             }
   2238         }
   2239 
   2240 
   2241         if (check_children)
   2242         {
   2243         //  printf("checking children\n");
   2244             DWARFDebugInfoEntry* child = GetFirstChild();
   2245             while (child)
   2246             {
   2247                 if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
   2248                     return true;
   2249                 child = child->GetSibling();
   2250             }
   2251         }
   2252     }
   2253     return found_address;
   2254 }
   2255 
   2256 const DWARFAbbreviationDeclaration*
   2257 DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
   2258                                                     const DWARFCompileUnit *cu,
   2259                                                     lldb::offset_t &offset) const
   2260 {
   2261     if (dwarf2Data)
   2262     {
   2263         offset = GetOffset();
   2264 
   2265         const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
   2266         if (abbrev_decl)
   2267         {
   2268             // Make sure the abbreviation code still matches. If it doesn't and
   2269             // the DWARF data was mmap'ed, the backing file might have been modified
   2270             // which is bad news.
   2271             const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
   2272 
   2273             if (abbrev_decl->Code() == abbrev_code)
   2274                 return abbrev_decl;
   2275 
   2276             dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
   2277                                                                                    GetOffset(),
   2278                                                                                    (uint32_t)abbrev_decl->Code(),
   2279                                                                                    (uint32_t)abbrev_code);
   2280         }
   2281     }
   2282     offset = DW_INVALID_OFFSET;
   2283     return NULL;
   2284 }
   2285 
   2286 
   2287 bool
   2288 DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
   2289 {
   2290     return a.GetOffset() < b.GetOffset();
   2291 }
   2292 
   2293 void
   2294 DWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection)
   2295 {
   2296     DWARFDebugInfoEntry::const_iterator pos;
   2297     DWARFDebugInfoEntry::const_iterator end = die_collection.end();
   2298     strm.PutCString("\noffset    parent   sibling  child\n");
   2299     strm.PutCString("--------  -------- -------- --------\n");
   2300     for (pos = die_collection.begin(); pos != end; ++pos)
   2301     {
   2302         const DWARFDebugInfoEntry& die_ref = *pos;
   2303         const DWARFDebugInfoEntry* p = die_ref.GetParent();
   2304         const DWARFDebugInfoEntry* s = die_ref.GetSibling();
   2305         const DWARFDebugInfoEntry* c = die_ref.GetFirstChild();
   2306         strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n",
   2307                     die_ref.GetOffset(),
   2308                     p ? p->GetOffset() : 0,
   2309                     s ? s->GetOffset() : 0,
   2310                     c ? c->GetOffset() : 0,
   2311                     die_ref.Tag(),
   2312                     DW_TAG_value_to_name(die_ref.Tag()),
   2313                     die_ref.HasChildren() ? " *" : "");
   2314     }
   2315 }
   2316 
   2317 
   2318