[Lldb-commits] [lldb] r280751 - *** This commit represents a complete reformatting of the LLDB source code
Kate Stone via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 6 13:58:36 PDT 2016
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp Tue Sep 6 15:57:50 2016
@@ -19,13 +19,13 @@
#include "lldb/Symbol/ObjectFile.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
+#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
-#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
-#include "DWARFDebugRanges.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDwo.h"
@@ -33,159 +33,157 @@ using namespace lldb_private;
using namespace std;
extern int g_verbose;
-bool
-DWARFDebugInfoEntry::FastExtract
-(
- const DWARFDataExtractor& debug_info_data,
- const DWARFCompileUnit* cu,
- const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
- lldb::offset_t *offset_ptr
-)
-{
- m_offset = *offset_ptr;
- m_parent_idx = 0;
- m_sibling_idx = 0;
- m_empty_children = false;
- const uint64_t abbr_idx = debug_info_data.GetULEB128 (offset_ptr);
- assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
- m_abbr_idx = abbr_idx;
-
- //assert (fixed_form_sizes); // For best performance this should be specified!
-
- if (m_abbr_idx)
- {
- lldb::offset_t offset = *offset_ptr;
+bool DWARFDebugInfoEntry::FastExtract(
+ const DWARFDataExtractor &debug_info_data, const DWARFCompileUnit *cu,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ lldb::offset_t *offset_ptr) {
+ m_offset = *offset_ptr;
+ m_parent_idx = 0;
+ m_sibling_idx = 0;
+ m_empty_children = false;
+ const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
+ assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
+ m_abbr_idx = abbr_idx;
- const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
-
- if (abbrevDecl == NULL)
- {
- 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",
- m_offset,
- (unsigned)abbr_idx);
- // WE can't parse anymore if the DWARF is borked...
- *offset_ptr = UINT32_MAX;
- return false;
- }
- m_tag = abbrevDecl->Tag();
- m_has_children = abbrevDecl->HasChildren();
- // Skip all data in the .debug_info for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_form_t form;
- for (i=0; i<numAttributes; ++i)
- {
- form = abbrevDecl->GetFormByIndexUnchecked(i);
-
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
- if (fixed_skip_size)
- offset += fixed_skip_size;
+ // assert (fixed_form_sizes); // For best performance this should be
+ // specified!
+
+ if (m_abbr_idx) {
+ lldb::offset_t offset = *offset_ptr;
+
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
+
+ if (abbrevDecl == NULL) {
+ 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",
+ m_offset, (unsigned)abbr_idx);
+ // WE can't parse anymore if the DWARF is borked...
+ *offset_ptr = UINT32_MAX;
+ return false;
+ }
+ m_tag = abbrevDecl->Tag();
+ m_has_children = abbrevDecl->HasChildren();
+ // Skip all data in the .debug_info for the attributes
+ const uint32_t numAttributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_form_t form;
+ for (i = 0; i < numAttributes; ++i) {
+ form = abbrevDecl->GetFormByIndexUnchecked(i);
+
+ const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ if (fixed_skip_size)
+ offset += fixed_skip_size;
+ else {
+ bool form_is_indirect = false;
+ do {
+ form_is_indirect = false;
+ uint32_t form_size = 0;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data bytes
+ // inlined in the .debug_info
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ form_size = debug_info_data.GetULEB128(&offset);
+ break;
+ case DW_FORM_block1:
+ form_size = debug_info_data.GetU8_unchecked(&offset);
+ break;
+ case DW_FORM_block2:
+ form_size = debug_info_data.GetU16_unchecked(&offset);
+ break;
+ case DW_FORM_block4:
+ form_size = debug_info_data.GetU32_unchecked(&offset);
+ break;
+
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ debug_info_data.GetCStr(&offset);
+ break;
+
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ form_size = cu->GetAddressByteSize();
+ break;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ form_size = cu->GetAddressByteSize();
else
- {
- bool form_is_indirect = false;
- do
- {
- form_is_indirect = false;
- uint32_t form_size = 0;
- switch (form)
- {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
- case DW_FORM_exprloc :
- case DW_FORM_block : form_size = debug_info_data.GetULEB128 (&offset); break;
- case DW_FORM_block1 : form_size = debug_info_data.GetU8_unchecked (&offset); break;
- case DW_FORM_block2 : form_size = debug_info_data.GetU16_unchecked (&offset);break;
- case DW_FORM_block4 : form_size = debug_info_data.GetU32_unchecked (&offset);break;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string :
- debug_info_data.GetCStr (&offset);
- break;
-
- // Compile unit address sized values
- case DW_FORM_addr :
- form_size = cu->GetAddressByteSize();
- break;
- case DW_FORM_ref_addr :
- if (cu->GetVersion() <= 2)
- form_size = cu->GetAddressByteSize();
- else
- form_size = cu->IsDWARF64() ? 8 : 4;
- break;
-
- // 0 sized form
- case DW_FORM_flag_present:
- form_size = 0;
- break;
-
- // 1 byte values
- case DW_FORM_data1 :
- case DW_FORM_flag :
- case DW_FORM_ref1 :
- form_size = 1;
- break;
-
- // 2 byte values
- case DW_FORM_data2 :
- case DW_FORM_ref2 :
- form_size = 2;
- break;
-
- // 4 byte values
- case DW_FORM_data4 :
- case DW_FORM_ref4 :
- form_size = 4;
- break;
-
- // 8 byte values
- case DW_FORM_data8 :
- case DW_FORM_ref8 :
- case DW_FORM_ref_sig8 :
- form_size = 8;
- break;
-
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata :
- case DW_FORM_udata :
- case DW_FORM_ref_udata :
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index :
- debug_info_data.Skip_LEB128 (&offset);
- break;
-
- case DW_FORM_indirect :
- form_is_indirect = true;
- form = debug_info_data.GetULEB128 (&offset);
- break;
-
- case DW_FORM_strp :
- case DW_FORM_sec_offset :
- if (cu->IsDWARF64 ())
- debug_info_data.GetU64 (offset_ptr);
- else
- debug_info_data.GetU32 (offset_ptr);
- break;
-
- default:
- *offset_ptr = m_offset;
- return false;
- }
- offset += form_size;
+ form_size = cu->IsDWARF64() ? 8 : 4;
+ break;
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
- }
- else
- {
- m_tag = 0;
- m_has_children = false;
- return true; // NULL debug tag entry
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
+
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ form_size = 1;
+ break;
+
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ form_size = 2;
+ break;
+
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ form_size = 4;
+ break;
+
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ form_size = 8;
+ break;
+
+ // signed or unsigned LEB 128 values
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ debug_info_data.Skip_LEB128(&offset);
+ break;
+
+ case DW_FORM_indirect:
+ form_is_indirect = true;
+ form = debug_info_data.GetULEB128(&offset);
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_sec_offset:
+ if (cu->IsDWARF64())
+ debug_info_data.GetU64(offset_ptr);
+ else
+ debug_info_data.GetU32(offset_ptr);
+ break;
+
+ default:
+ *offset_ptr = m_offset;
+ return false;
+ }
+ offset += form_size;
+
+ } while (form_is_indirect);
+ }
}
+ *offset_ptr = offset;
+ return true;
+ } else {
+ m_tag = 0;
+ m_has_children = false;
+ return true; // NULL debug tag entry
+ }
- return false;
+ return false;
}
//----------------------------------------------------------------------
@@ -195,165 +193,164 @@ DWARFDebugInfoEntry::FastExtract
// .debug_info and .debug_abbrev data within the SymbolFileDWARF class
// starting at the given offset
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::Extract
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- lldb::offset_t *offset_ptr
-)
-{
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-// const DWARFDataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
- const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
- lldb::offset_t offset = *offset_ptr;
-// if (offset >= cu_end_offset)
-// Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
- if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
- {
- m_offset = offset;
-
- const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
- assert (abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
- m_abbr_idx = abbr_idx;
- if (abbr_idx)
- {
- const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
-
- if (abbrevDecl)
- {
- m_tag = abbrevDecl->Tag();
- m_has_children = abbrevDecl->HasChildren();
-
- bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
- if (cu && isCompileUnitTag)
- const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0);
-
- // Skip all data in the .debug_info for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- for (i=0; i<numAttributes; ++i)
- {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
-
- if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc)))
- {
- DWARFFormValue form_value(cu, form);
- if (form_value.ExtractValue(debug_info_data, &offset))
- {
- if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
- const_cast<DWARFCompileUnit*>(cu)->SetBaseAddress(form_value.Address());
- }
- }
- else
- {
- bool form_is_indirect = false;
- do
- {
- form_is_indirect = false;
- uint32_t form_size = 0;
- switch (form)
- {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
- case DW_FORM_exprloc :
- case DW_FORM_block : form_size = debug_info_data.GetULEB128(&offset); break;
- case DW_FORM_block1 : form_size = debug_info_data.GetU8(&offset); break;
- case DW_FORM_block2 : form_size = debug_info_data.GetU16(&offset); break;
- case DW_FORM_block4 : form_size = debug_info_data.GetU32(&offset); break;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string : debug_info_data.GetCStr(&offset); break;
-
- // Compile unit address sized values
- case DW_FORM_addr :
- form_size = cu->GetAddressByteSize();
- break;
- case DW_FORM_ref_addr :
- if (cu->GetVersion() <= 2)
- form_size = cu->GetAddressByteSize();
- else
- form_size = cu->IsDWARF64() ? 8 : 4;
- break;
-
- // 0 sized form
- case DW_FORM_flag_present:
- form_size = 0;
- break;
-
- // 1 byte values
- case DW_FORM_data1 :
- case DW_FORM_flag :
- case DW_FORM_ref1 :
- form_size = 1;
- break;
-
- // 2 byte values
- case DW_FORM_data2 :
- case DW_FORM_ref2 :
- form_size = 2;
- break;
-
- // 4 byte values
- case DW_FORM_data4 :
- case DW_FORM_ref4 :
- form_size = 4;
- break;
-
- // 8 byte values
- case DW_FORM_data8 :
- case DW_FORM_ref8 :
- case DW_FORM_ref_sig8 :
- form_size = 8;
- break;
-
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata :
- case DW_FORM_udata :
- case DW_FORM_ref_udata :
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index :
- debug_info_data.Skip_LEB128(&offset);
- break;
-
- case DW_FORM_indirect :
- form = debug_info_data.GetULEB128(&offset);
- form_is_indirect = true;
- break;
-
- case DW_FORM_strp :
- case DW_FORM_sec_offset :
- if (cu->IsDWARF64 ())
- debug_info_data.GetU64 (offset_ptr);
- else
- debug_info_data.GetU32 (offset_ptr);
- break;
-
- default:
- *offset_ptr = offset;
- return false;
- }
-
- offset += form_size;
- } while (form_is_indirect);
- }
- }
+bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ lldb::offset_t *offset_ptr) {
+ const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+ // const DWARFDataExtractor& debug_str_data =
+ // dwarf2Data->get_debug_str_data();
+ const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
+ lldb::offset_t offset = *offset_ptr;
+ // if (offset >= cu_end_offset)
+ // Log::Error("DIE at offset 0x%8.8x is beyond the end of the current
+ // compile unit (0x%8.8x)", m_offset, cu_end_offset);
+ if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) {
+ m_offset = offset;
+
+ const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
+ assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
+ m_abbr_idx = abbr_idx;
+ if (abbr_idx) {
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
+
+ if (abbrevDecl) {
+ m_tag = abbrevDecl->Tag();
+ m_has_children = abbrevDecl->HasChildren();
+
+ bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
+ if (cu && isCompileUnitTag)
+ const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0);
+
+ // Skip all data in the .debug_info for the attributes
+ const uint32_t numAttributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_attr_t attr;
+ dw_form_t form;
+ for (i = 0; i < numAttributes; ++i) {
+ abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+
+ if (isCompileUnitTag &&
+ ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
+ DWARFFormValue form_value(cu, form);
+ if (form_value.ExtractValue(debug_info_data, &offset)) {
+ if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
+ const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(
+ form_value.Address());
+ }
+ } else {
+ bool form_is_indirect = false;
+ do {
+ form_is_indirect = false;
+ uint32_t form_size = 0;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data
+ // bytes
+ // inlined in the .debug_info
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ form_size = debug_info_data.GetULEB128(&offset);
+ break;
+ case DW_FORM_block1:
+ form_size = debug_info_data.GetU8(&offset);
+ break;
+ case DW_FORM_block2:
+ form_size = debug_info_data.GetU16(&offset);
+ break;
+ case DW_FORM_block4:
+ form_size = debug_info_data.GetU32(&offset);
+ break;
+
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ debug_info_data.GetCStr(&offset);
+ break;
+
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ form_size = cu->GetAddressByteSize();
+ break;
+ case DW_FORM_ref_addr:
+ if (cu->GetVersion() <= 2)
+ form_size = cu->GetAddressByteSize();
+ else
+ form_size = cu->IsDWARF64() ? 8 : 4;
+ break;
+
+ // 0 sized form
+ case DW_FORM_flag_present:
+ form_size = 0;
+ break;
+
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ form_size = 1;
+ break;
+
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ form_size = 2;
+ break;
+
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ form_size = 4;
+ break;
+
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ form_size = 8;
+ break;
+
+ // signed or unsigned LEB 128 values
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ debug_info_data.Skip_LEB128(&offset);
+ break;
+
+ case DW_FORM_indirect:
+ form = debug_info_data.GetULEB128(&offset);
+ form_is_indirect = true;
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_sec_offset:
+ if (cu->IsDWARF64())
+ debug_info_data.GetU64(offset_ptr);
+ else
+ debug_info_data.GetU32(offset_ptr);
+ break;
+
+ default:
*offset_ptr = offset;
- return true;
- }
- }
- else
- {
- m_tag = 0;
- m_has_children = false;
- *offset_ptr = offset;
- return true; // NULL debug tag entry
+ return false;
+ }
+
+ offset += form_size;
+ } while (form_is_indirect);
+ }
}
+ *offset_ptr = offset;
+ return true;
+ }
+ } else {
+ m_tag = 0;
+ m_has_children = false;
+ *offset_ptr = offset;
+ return true; // NULL debug tag entry
}
+ }
- return false;
+ return false;
}
//----------------------------------------------------------------------
@@ -362,20 +359,15 @@ DWARFDebugInfoEntry::Extract
// Dumps all of a debug information entries parents up until oldest and
// all of it's attributes to the specified stream.
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::DumpAncestry
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const DWARFDebugInfoEntry* oldest,
- Stream &s,
- uint32_t recurse_depth
-) const
-{
- const DWARFDebugInfoEntry* parent = GetParent();
- if (parent && parent != oldest)
- parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
- Dump(dwarf2Data, cu, s, recurse_depth);
+void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const DWARFDebugInfoEntry *oldest,
+ Stream &s,
+ uint32_t recurse_depth) const {
+ const DWARFDebugInfoEntry *parent = GetParent();
+ if (parent && parent != oldest)
+ parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
+ Dump(dwarf2Data, cu, s, recurse_depth);
}
//----------------------------------------------------------------------
@@ -385,238 +377,206 @@ DWARFDebugInfoEntry::DumpAncestry
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
// attributes.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::GetDIENamesAndRanges
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const char * &name,
- const char * &mangled,
- DWARFRangeList& ranges,
- int& decl_file,
- int& decl_line,
- int& decl_column,
- int& call_file,
- int& call_line,
- int& call_column,
- DWARFExpression *frame_base
-) const
-{
- if (dwarf2Data == nullptr)
- return false;
-
- SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetDIENamesAndRanges(dwo_symbol_file,
- dwo_symbol_file->GetCompileUnit(),
- name,
- mangled,
- ranges,
- decl_file,
- decl_line,
- decl_column,
- call_file,
- call_line,
- call_column,
- frame_base);
-
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- std::vector<DIERef> die_refs;
- bool set_frame_base_loclist_addr = false;
-
- lldb::offset_t offset;
- const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
-
- if (abbrevDecl)
- {
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-
- if (!debug_info_data.ValidOffset(offset))
- return false;
-
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- bool do_offset = false;
-
- for (i=0; i<numAttributes; ++i)
- {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
- DWARFFormValue form_value(cu, form);
- if (form_value.ExtractValue(debug_info_data, &offset))
- {
- switch (attr)
- {
- case DW_AT_low_pc:
- lo_pc = form_value.Address();
-
- if (do_offset)
- hi_pc += lo_pc;
- do_offset = false;
- break;
-
- case DW_AT_entry_pc:
- lo_pc = form_value.Address();
- break;
-
- case DW_AT_high_pc:
- if (form_value.Form() == DW_FORM_addr ||
- form_value.Form() == DW_FORM_GNU_addr_index)
- {
- hi_pc = form_value.Address();
- }
- else
- {
- hi_pc = form_value.Unsigned();
- if (lo_pc == LLDB_INVALID_ADDRESS)
- do_offset = hi_pc != LLDB_INVALID_ADDRESS;
- else
- hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save on relocations
- }
- break;
-
- case DW_AT_ranges:
- {
- const DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
- if (debug_ranges)
- {
- debug_ranges->FindRanges(form_value.Unsigned(), ranges);
- // All DW_AT_ranges are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
- ranges.Slide(cu->GetBaseAddress());
- }
- else
- {
- cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute yet DWARF has no .debug_ranges, please file a bug and attach the file at the start of this error message",
- m_offset, form_value.Unsigned());
- }
- }
- break;
-
- case DW_AT_name:
- if (name == NULL)
- name = form_value.AsCString();
- break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (mangled == NULL)
- mangled = form_value.AsCString();
- break;
-
- case DW_AT_abstract_origin:
- die_refs.emplace_back(form_value);
- break;
-
- case DW_AT_specification:
- die_refs.emplace_back(form_value);
- break;
-
- case DW_AT_decl_file:
- if (decl_file == 0)
- decl_file = form_value.Unsigned();
- break;
-
- case DW_AT_decl_line:
- if (decl_line == 0)
- decl_line = form_value.Unsigned();
- break;
-
- case DW_AT_decl_column:
- if (decl_column == 0)
- decl_column = form_value.Unsigned();
- break;
-
- case DW_AT_call_file:
- if (call_file == 0)
- call_file = form_value.Unsigned();
- break;
-
- case DW_AT_call_line:
- if (call_line == 0)
- call_line = form_value.Unsigned();
- break;
-
- case DW_AT_call_column:
- if (call_column == 0)
- call_column = form_value.Unsigned();
- break;
-
- case DW_AT_frame_base:
- if (frame_base)
- {
- if (form_value.BlockData())
- {
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- frame_base->SetOpcodeData(module, debug_info_data, block_offset, block_length);
- }
- else
- {
- const DWARFDataExtractor &debug_loc_data = dwarf2Data->get_debug_loc_data();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(cu, debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0)
- {
- frame_base->SetOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
- if (lo_pc != LLDB_INVALID_ADDRESS)
- {
- assert (lo_pc >= cu->GetBaseAddress());
- frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
- }
- else
- {
- set_frame_base_loclist_addr = true;
- }
- }
- }
- }
- break;
+bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, const char *&name,
+ const char *&mangled, DWARFRangeList &ranges, int &decl_file,
+ int &decl_line, int &decl_column, int &call_file, int &call_line,
+ int &call_column, DWARFExpression *frame_base) const {
+ if (dwarf2Data == nullptr)
+ return false;
- default:
- break;
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
+ if (dwo_symbol_file)
+ return GetDIENamesAndRanges(
+ dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled,
+ ranges, decl_file, decl_line, decl_column, call_file, call_line,
+ call_column, frame_base);
+
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ std::vector<DIERef> die_refs;
+ bool set_frame_base_loclist_addr = false;
+
+ lldb::offset_t offset;
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+ lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
+
+ if (abbrevDecl) {
+ const DWARFDataExtractor &debug_info_data =
+ dwarf2Data->get_debug_info_data();
+
+ if (!debug_info_data.ValidOffset(offset))
+ return false;
+
+ const uint32_t numAttributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_attr_t attr;
+ dw_form_t form;
+ bool do_offset = false;
+
+ for (i = 0; i < numAttributes; ++i) {
+ abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+ DWARFFormValue form_value(cu, form);
+ if (form_value.ExtractValue(debug_info_data, &offset)) {
+ switch (attr) {
+ case DW_AT_low_pc:
+ lo_pc = form_value.Address();
+
+ if (do_offset)
+ hi_pc += lo_pc;
+ do_offset = false;
+ break;
+
+ case DW_AT_entry_pc:
+ lo_pc = form_value.Address();
+ break;
+
+ case DW_AT_high_pc:
+ if (form_value.Form() == DW_FORM_addr ||
+ form_value.Form() == DW_FORM_GNU_addr_index) {
+ hi_pc = form_value.Address();
+ } else {
+ hi_pc = form_value.Unsigned();
+ if (lo_pc == LLDB_INVALID_ADDRESS)
+ do_offset = hi_pc != LLDB_INVALID_ADDRESS;
+ else
+ hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
+ // on relocations
+ }
+ break;
+
+ case DW_AT_ranges: {
+ const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
+ if (debug_ranges) {
+ debug_ranges->FindRanges(form_value.Unsigned(), ranges);
+ // All DW_AT_ranges are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ ranges.Slide(cu->GetBaseAddress());
+ } else {
+ cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
+ ") attribute yet DWARF has no .debug_ranges, please file a bug "
+ "and attach the file at the start of this error message",
+ m_offset, form_value.Unsigned());
+ }
+ } break;
+
+ case DW_AT_name:
+ if (name == NULL)
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
+ if (mangled == NULL)
+ mangled = form_value.AsCString();
+ break;
+
+ case DW_AT_abstract_origin:
+ die_refs.emplace_back(form_value);
+ break;
+
+ case DW_AT_specification:
+ die_refs.emplace_back(form_value);
+ break;
+
+ case DW_AT_decl_file:
+ if (decl_file == 0)
+ decl_file = form_value.Unsigned();
+ break;
+
+ case DW_AT_decl_line:
+ if (decl_line == 0)
+ decl_line = form_value.Unsigned();
+ break;
+
+ case DW_AT_decl_column:
+ if (decl_column == 0)
+ decl_column = form_value.Unsigned();
+ break;
+
+ case DW_AT_call_file:
+ if (call_file == 0)
+ call_file = form_value.Unsigned();
+ break;
+
+ case DW_AT_call_line:
+ if (call_line == 0)
+ call_line = form_value.Unsigned();
+ break;
+
+ case DW_AT_call_column:
+ if (call_column == 0)
+ call_column = form_value.Unsigned();
+ break;
+
+ case DW_AT_frame_base:
+ if (frame_base) {
+ if (form_value.BlockData()) {
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ frame_base->SetOpcodeData(module, debug_info_data, block_offset,
+ block_length);
+ } else {
+ const DWARFDataExtractor &debug_loc_data =
+ dwarf2Data->get_debug_loc_data();
+ const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+ size_t loc_list_length = DWARFExpression::LocationListSize(
+ cu, debug_loc_data, debug_loc_offset);
+ if (loc_list_length > 0) {
+ frame_base->SetOpcodeData(module, debug_loc_data,
+ debug_loc_offset, loc_list_length);
+ if (lo_pc != LLDB_INVALID_ADDRESS) {
+ assert(lo_pc >= cu->GetBaseAddress());
+ frame_base->SetLocationListSlide(lo_pc -
+ cu->GetBaseAddress());
+ } else {
+ set_frame_base_loclist_addr = true;
}
+ }
}
- }
- }
+ }
+ break;
- if (ranges.IsEmpty())
- {
- if (lo_pc != LLDB_INVALID_ADDRESS)
- {
- if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
- ranges.Append(DWARFRangeList::Entry (lo_pc, hi_pc - lo_pc));
- else
- ranges.Append(DWARFRangeList::Entry (lo_pc, 0));
+ default:
+ break;
}
+ }
+ }
+ }
+
+ if (ranges.IsEmpty()) {
+ if (lo_pc != LLDB_INVALID_ADDRESS) {
+ if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
+ ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
+ else
+ ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
+ }
+ }
+
+ if (set_frame_base_loclist_addr) {
+ dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
+ assert(lowest_range_pc >= cu->GetBaseAddress());
+ frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
+ }
+
+ if (ranges.IsEmpty() || name == NULL || mangled == NULL) {
+ for (const DIERef &die_ref : die_refs) {
+ if (die_ref.die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE die = dwarf2Data->GetDIE(die_ref);
+ if (die)
+ die.GetDIE()->GetDIENamesAndRanges(
+ die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file,
+ decl_line, decl_column, call_file, call_line, call_column);
+ }
}
-
- if (set_frame_base_loclist_addr)
- {
- dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
- assert (lowest_range_pc >= cu->GetBaseAddress());
- frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress());
- }
-
- if (ranges.IsEmpty() || name == NULL || mangled == NULL)
- {
- for (const DIERef& die_ref : die_refs)
- {
- if (die_ref.die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE die = dwarf2Data->GetDIE(die_ref);
- if (die)
- die.GetDIE()->GetDIENamesAndRanges(die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
- }
- }
- }
- return !ranges.IsEmpty();
+ }
+ return !ranges.IsEmpty();
}
//----------------------------------------------------------------------
@@ -625,95 +585,74 @@ DWARFDebugInfoEntry::GetDIENamesAndRange
// Dumps a debug information entry and all of it's attributes to the
// specified stream.
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::Dump
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- Stream &s,
- uint32_t recurse_depth
-) const
-{
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
- lldb::offset_t offset = m_offset;
-
- if (debug_info_data.ValidOffset(offset))
- {
- dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
-
- s.Printf("\n0x%8.8x: ", m_offset);
- s.Indent();
- if (abbrCode != m_abbr_idx)
- {
- s.Printf( "error: DWARF has been modified\n");
- }
- else if (abbrCode)
- {
- const DWARFAbbreviationDeclaration* abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration (abbrCode);
-
- if (abbrevDecl)
- {
- s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
- s.Printf( " [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*':' ');
-
- // Dump all data in the .debug_info for the attributes
- const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- for (i=0; i<numAttributes; ++i)
- {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu, Stream &s,
+ uint32_t recurse_depth) const {
+ const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+ lldb::offset_t offset = m_offset;
+
+ if (debug_info_data.ValidOffset(offset)) {
+ dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);
+
+ s.Printf("\n0x%8.8x: ", m_offset);
+ s.Indent();
+ if (abbrCode != m_abbr_idx) {
+ s.Printf("error: DWARF has been modified\n");
+ } else if (abbrCode) {
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);
+
+ if (abbrevDecl) {
+ s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
+ s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');
- DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, form);
- }
+ // Dump all data in the .debug_info for the attributes
+ const uint32_t numAttributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_attr_t attr;
+ dw_form_t form;
+ for (i = 0; i < numAttributes; ++i) {
+ abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
- const DWARFDebugInfoEntry* child = GetFirstChild();
- if (recurse_depth > 0 && child)
- {
- s.IndentMore();
-
- while (child)
- {
- child->Dump(dwarf2Data, cu, s, recurse_depth-1);
- child = child->GetSibling();
- }
- s.IndentLess();
- }
- }
- else
- s.Printf( "Abbreviation code note found in 'debug_abbrev' class for code: %u\n", abbrCode);
- }
- else
- {
- s.Printf( "NULL\n");
+ DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
+ form);
}
- }
-}
-void
-DWARFDebugInfoEntry::DumpLocation
-(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- Stream &s
-) const
-{
- const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly();
- const char *cu_name = NULL;
- if (cu_die)
- cu_name = cu_die.GetName ();
- const char *obj_file_name = NULL;
- ObjectFile *obj_file = dwarf2Data->GetObjectFile();
- if (obj_file)
- obj_file_name = obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
- const char *die_name = GetName (dwarf2Data, cu);
- s.Printf ("0x%8.8x/0x%8.8x: %-30s (from %s in %s)",
- cu->GetOffset(),
- GetOffset(),
- die_name ? die_name : "",
- cu_name ? cu_name : "<NULL>",
- obj_file_name ? obj_file_name : "<NULL>");
+ const DWARFDebugInfoEntry *child = GetFirstChild();
+ if (recurse_depth > 0 && child) {
+ s.IndentMore();
+
+ while (child) {
+ child->Dump(dwarf2Data, cu, s, recurse_depth - 1);
+ child = child->GetSibling();
+ }
+ s.IndentLess();
+ }
+ } else
+ s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
+ "code: %u\n",
+ abbrCode);
+ } else {
+ s.Printf("NULL\n");
+ }
+ }
+}
+
+void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu, Stream &s) const {
+ const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly();
+ const char *cu_name = NULL;
+ if (cu_die)
+ cu_name = cu_die.GetName();
+ const char *obj_file_name = NULL;
+ ObjectFile *obj_file = dwarf2Data->GetObjectFile();
+ if (obj_file)
+ obj_file_name =
+ obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
+ const char *die_name = GetName(dwarf2Data, cu);
+ s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(),
+ GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>",
+ obj_file_name ? obj_file_name : "<NULL>");
}
//----------------------------------------------------------------------
@@ -723,162 +662,142 @@ DWARFDebugInfoEntry::DumpLocation
// special display of attributes is done (disassemble location lists,
// show enumeration values for attributes, etc).
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::DumpAttribute
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const DWARFDataExtractor& debug_info_data,
- lldb::offset_t *offset_ptr,
- Stream &s,
- dw_attr_t attr,
- dw_form_t form
-)
-{
- bool verbose = s.GetVerbose();
- bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
-
+void DWARFDebugInfoEntry::DumpAttribute(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
+ Stream &s, dw_attr_t attr, dw_form_t form) {
+ bool verbose = s.GetVerbose();
+ bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
+
+ if (verbose)
+ s.Offset(*offset_ptr);
+ else
+ s.Printf(" ");
+ s.Indent(DW_AT_value_to_name(attr));
+
+ if (show_form) {
+ s.Printf("[%s", DW_FORM_value_to_name(form));
+ }
+
+ DWARFFormValue form_value(cu, form);
+
+ if (!form_value.ExtractValue(debug_info_data, offset_ptr))
+ return;
+
+ if (show_form) {
+ if (form == DW_FORM_indirect) {
+ s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
+ }
+
+ s.PutCString("] ");
+ }
+
+ s.PutCString("( ");
+
+ // Always dump form value if verbose is enabled
+ if (verbose) {
+ form_value.Dump(s);
+ }
+
+ // Check to see if we have any special attribute formatters
+ switch (attr) {
+ case DW_AT_stmt_list:
if (verbose)
- s.Offset (*offset_ptr);
- else
- s.Printf (" ");
- s.Indent(DW_AT_value_to_name(attr));
-
- if (show_form)
- {
- s.Printf( "[%s", DW_FORM_value_to_name(form));
- }
-
- DWARFFormValue form_value(cu, form);
-
- if (!form_value.ExtractValue(debug_info_data, offset_ptr))
- return;
-
- if (show_form)
- {
- if (form == DW_FORM_indirect)
- {
- s.Printf( " [%s]", DW_FORM_value_to_name(form_value.Form()));
- }
-
- s.PutCString("] ");
- }
-
- s.PutCString("( ");
-
- // Always dump form value if verbose is enabled
+ s.PutCString(" ( ");
+ s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
if (verbose)
- {
- form_value.Dump(s);
- }
-
-
- // Check to see if we have any special attribute formatters
- switch (attr)
- {
- case DW_AT_stmt_list:
- if ( verbose ) s.PutCString(" ( ");
- s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
- if ( verbose ) s.PutCString(" )");
- break;
-
- case DW_AT_language:
- if ( verbose ) s.PutCString(" ( ");
- s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
- if ( verbose ) s.PutCString(" )");
- break;
+ s.PutCString(" )");
+ break;
- case DW_AT_encoding:
- if ( verbose ) s.PutCString(" ( ");
- s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
- if ( verbose ) s.PutCString(" )");
- break;
-
- case DW_AT_frame_base:
- case DW_AT_location:
- case DW_AT_data_member_location:
- {
- const uint8_t* blockData = form_value.BlockData();
- if (blockData)
- {
- if (!verbose)
- form_value.Dump(s);
-
- // Location description is inlined in data in the form value
- DWARFDataExtractor locationData(debug_info_data, (*offset_ptr) - form_value.Unsigned(), form_value.Unsigned());
- if ( verbose ) s.PutCString(" ( ");
- DWARFExpression::PrintDWARFExpression(s,
- locationData,
- DWARFCompileUnit::GetAddressByteSize(cu),
- 4,
- false);
- if ( verbose ) s.PutCString(" )");
- }
- else
- {
- // We have a location list offset as the value that is
- // the offset into the .debug_loc section that describes
- // the value over it's lifetime
- uint64_t debug_loc_offset = form_value.Unsigned();
- if (dwarf2Data)
- {
- if ( !verbose )
- form_value.Dump(s);
- DWARFExpression::PrintDWARFLocationList(s,
- cu,
- dwarf2Data->get_debug_loc_data(),
- debug_loc_offset);
- }
- else
- {
- if ( !verbose )
- form_value.Dump(s);
- }
- }
- }
- break;
+ case DW_AT_language:
+ if (verbose)
+ s.PutCString(" ( ");
+ s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
+ if (verbose)
+ s.PutCString(" )");
+ break;
- case DW_AT_abstract_origin:
- case DW_AT_specification:
- {
- uint64_t abstract_die_offset = form_value.Reference();
- form_value.Dump(s);
- // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
- if ( verbose ) s.PutCString(" ( ");
- GetName(dwarf2Data, cu, abstract_die_offset, s);
- if ( verbose ) s.PutCString(" )");
- }
- break;
+ case DW_AT_encoding:
+ if (verbose)
+ s.PutCString(" ( ");
+ s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
+ if (verbose)
+ s.PutCString(" )");
+ break;
- case DW_AT_type:
- {
- uint64_t type_die_offset = form_value.Reference();
- if (!verbose)
- form_value.Dump(s);
- s.PutCString(" ( ");
- AppendTypeName(dwarf2Data, cu, type_die_offset, s);
- s.PutCString(" )");
- }
- break;
+ case DW_AT_frame_base:
+ case DW_AT_location:
+ case DW_AT_data_member_location: {
+ const uint8_t *blockData = form_value.BlockData();
+ if (blockData) {
+ if (!verbose)
+ form_value.Dump(s);
- case DW_AT_ranges:
- {
- if ( !verbose )
- form_value.Dump(s);
- lldb::offset_t ranges_offset = form_value.Unsigned();
- dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- if (dwarf2Data)
- DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
- }
- break;
+ // Location description is inlined in data in the form value
+ DWARFDataExtractor locationData(debug_info_data,
+ (*offset_ptr) - form_value.Unsigned(),
+ form_value.Unsigned());
+ if (verbose)
+ s.PutCString(" ( ");
+ DWARFExpression::PrintDWARFExpression(
+ s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
+ if (verbose)
+ s.PutCString(" )");
+ } else {
+ // We have a location list offset as the value that is
+ // the offset into the .debug_loc section that describes
+ // the value over it's lifetime
+ uint64_t debug_loc_offset = form_value.Unsigned();
+ if (dwarf2Data) {
+ if (!verbose)
+ form_value.Dump(s);
+ DWARFExpression::PrintDWARFLocationList(
+ s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
+ } else {
+ if (!verbose)
+ form_value.Dump(s);
+ }
+ }
+ } break;
+
+ case DW_AT_abstract_origin:
+ case DW_AT_specification: {
+ uint64_t abstract_die_offset = form_value.Reference();
+ form_value.Dump(s);
+ // *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
+ if (verbose)
+ s.PutCString(" ( ");
+ GetName(dwarf2Data, cu, abstract_die_offset, s);
+ if (verbose)
+ s.PutCString(" )");
+ } break;
- default:
- if ( !verbose )
- form_value.Dump(s);
- break;
- }
+ case DW_AT_type: {
+ uint64_t type_die_offset = form_value.Reference();
+ if (!verbose)
+ form_value.Dump(s);
+ s.PutCString(" ( ");
+ AppendTypeName(dwarf2Data, cu, type_die_offset, s);
+ s.PutCString(" )");
+ } break;
+
+ case DW_AT_ranges: {
+ if (!verbose)
+ form_value.Dump(s);
+ lldb::offset_t ranges_offset = form_value.Unsigned();
+ dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
+ if (dwarf2Data)
+ DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
+ &ranges_offset, base_addr);
+ } break;
+
+ default:
+ if (!verbose)
+ form_value.Dump(s);
+ break;
+ }
- s.PutCString(" )\n");
+ s.PutCString(" )\n");
}
//----------------------------------------------------------------------
@@ -887,94 +806,78 @@ DWARFDebugInfoEntry::DumpAttribute
// the results. Any duplicate attributes will have the first instance
// take precedence (this can happen for declaration attributes).
//----------------------------------------------------------------------
-size_t
-DWARFDebugInfoEntry::GetAttributes (const DWARFCompileUnit* cu,
- DWARFFormValue::FixedFormSizes fixed_form_sizes,
- DWARFAttributes& attributes,
- uint32_t curr_depth) const
-{
- SymbolFileDWARF* dwarf2Data = nullptr;
- const DWARFAbbreviationDeclaration* abbrevDecl = nullptr;
- lldb::offset_t offset = 0;
- if (cu)
- {
- if (m_tag != DW_TAG_compile_unit)
- {
- SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file)
- return GetAttributes(dwo_symbol_file->GetCompileUnit(),
- fixed_form_sizes,
- attributes,
- curr_depth);
- }
-
- dwarf2Data = cu->GetSymbolFileDWARF();
- abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
- }
-
- if (abbrevDecl)
- {
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-
- if (fixed_form_sizes.Empty())
- fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
- cu->GetAddressByteSize(), cu->IsDWARF64());
-
- const uint32_t num_attributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- for (i=0; i<num_attributes; ++i)
- {
- abbrevDecl->GetAttrAndFormByIndexUnchecked (i, attr, form);
-
- // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
- // attributes, the depth will be non-zero. We need to omit certain
- // attributes that don't make sense.
- switch (attr)
- {
- case DW_AT_sibling:
- case DW_AT_declaration:
- if (curr_depth > 0)
- {
- // This attribute doesn't make sense when combined with
- // the DIE that references this DIE. We know a DIE is
- // referencing this DIE because curr_depth is not zero
- break;
- }
- LLVM_FALLTHROUGH;
- default:
- attributes.Append(cu, offset, attr, form);
- break;
- }
+size_t DWARFDebugInfoEntry::GetAttributes(
+ const DWARFCompileUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
+ DWARFAttributes &attributes, uint32_t curr_depth) const {
+ SymbolFileDWARF *dwarf2Data = nullptr;
+ const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
+ lldb::offset_t offset = 0;
+ if (cu) {
+ if (m_tag != DW_TAG_compile_unit) {
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
+ if (dwo_symbol_file)
+ return GetAttributes(dwo_symbol_file->GetCompileUnit(),
+ fixed_form_sizes, attributes, curr_depth);
+ }
+
+ dwarf2Data = cu->GetSymbolFileDWARF();
+ abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+ }
+
+ if (abbrevDecl) {
+ const DWARFDataExtractor &debug_info_data =
+ dwarf2Data->get_debug_info_data();
+
+ if (fixed_form_sizes.Empty())
+ fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
+ cu->GetAddressByteSize(), cu->IsDWARF64());
+
+ const uint32_t num_attributes = abbrevDecl->NumAttributes();
+ uint32_t i;
+ dw_attr_t attr;
+ dw_form_t form;
+ for (i = 0; i < num_attributes; ++i) {
+ abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+
+ // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
+ // attributes, the depth will be non-zero. We need to omit certain
+ // attributes that don't make sense.
+ switch (attr) {
+ case DW_AT_sibling:
+ case DW_AT_declaration:
+ if (curr_depth > 0) {
+ // This attribute doesn't make sense when combined with
+ // the DIE that references this DIE. We know a DIE is
+ // referencing this DIE because curr_depth is not zero
+ break;
+ }
+ LLVM_FALLTHROUGH;
+ default:
+ attributes.Append(cu, offset, attr, form);
+ break;
+ }
- if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))
- {
- DWARFFormValue form_value (cu, form);
- if (form_value.ExtractValue(debug_info_data, &offset))
- {
- dw_offset_t die_offset = form_value.Reference();
- DWARFDIE spec_die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(die_offset);
- if (spec_die)
- spec_die.GetAttributes(attributes, curr_depth + 1);
- }
- }
- else
- {
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
- if (fixed_skip_size)
- offset += fixed_skip_size;
- else
- DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
- }
- }
- }
- else
- {
- attributes.Clear();
+ if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
+ DWARFFormValue form_value(cu, form);
+ if (form_value.ExtractValue(debug_info_data, &offset)) {
+ dw_offset_t die_offset = form_value.Reference();
+ DWARFDIE spec_die =
+ const_cast<DWARFCompileUnit *>(cu)->GetDIE(die_offset);
+ if (spec_die)
+ spec_die.GetAttributes(attributes, curr_depth + 1);
+ }
+ } else {
+ const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ if (fixed_skip_size)
+ offset += fixed_skip_size;
+ else
+ DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
+ }
}
- return attributes.Size();
-
+ } else {
+ attributes.Clear();
+ }
+ return attributes.Size();
}
//----------------------------------------------------------------------
@@ -985,105 +888,84 @@ DWARFDebugInfoEntry::GetAttributes (cons
// if we fail since an offset of zero is invalid for an attribute (it
// would be a compile unit header).
//----------------------------------------------------------------------
-dw_offset_t
-DWARFDebugInfoEntry::GetAttributeValue
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- DWARFFormValue& form_value,
- dw_offset_t* end_attr_offset_ptr,
- bool check_specification_or_abstract_origin
-) const
-{
- SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
- if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
- return GetAttributeValue(dwo_symbol_file,
- dwo_symbol_file->GetCompileUnit(),
- attr,
- form_value,
- end_attr_offset_ptr,
- check_specification_or_abstract_origin);
-
- lldb::offset_t offset;
- const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- if (abbrevDecl)
- {
- uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
-
- if (attr_idx != DW_INVALID_INDEX)
- {
- const DWARFDataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
-
- uint32_t idx=0;
- while (idx<attr_idx)
- DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), debug_info_data, &offset, cu);
-
- const dw_offset_t attr_offset = offset;
- form_value.SetCompileUnit(cu);
- form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
- if (form_value.ExtractValue(debug_info_data, &offset))
- {
- if (end_attr_offset_ptr)
- *end_attr_offset_ptr = offset;
- return attr_offset;
- }
- }
- }
-
- if (check_specification_or_abstract_origin)
- {
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
- {
- DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
- if (die)
- {
- dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(die.GetDWARF(),
- die.GetCU(),
- attr,
- form_value,
- end_attr_offset_ptr,
- false);
- if (die_offset)
- return die_offset;
- }
- }
-
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value))
- {
- DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
- if (die)
- {
- dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(die.GetDWARF(),
- die.GetCU(),
- attr,
- form_value,
- end_attr_offset_ptr,
- false);
- if (die_offset)
- return die_offset;
- }
- }
- }
-
- if (!dwo_symbol_file)
- return 0;
-
- DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
- if (!dwo_cu)
- return 0;
-
- DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
- if (!dwo_cu_die.IsValid())
- return 0;
-
- return dwo_cu_die.GetDIE()->GetAttributeValue(dwo_symbol_file,
- dwo_cu,
- attr,
- form_value,
- end_attr_offset_ptr,
- check_specification_or_abstract_origin);
+dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, DWARFFormValue &form_value,
+ dw_offset_t *end_attr_offset_ptr,
+ bool check_specification_or_abstract_origin) const {
+ SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
+ if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
+ return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
+ attr, form_value, end_attr_offset_ptr,
+ check_specification_or_abstract_origin);
+
+ lldb::offset_t offset;
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+ if (abbrevDecl) {
+ uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
+
+ if (attr_idx != DW_INVALID_INDEX) {
+ const DWARFDataExtractor &debug_info_data =
+ dwarf2Data->get_debug_info_data();
+
+ uint32_t idx = 0;
+ while (idx < attr_idx)
+ DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
+ debug_info_data, &offset, cu);
+
+ const dw_offset_t attr_offset = offset;
+ form_value.SetCompileUnit(cu);
+ form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
+ if (form_value.ExtractValue(debug_info_data, &offset)) {
+ if (end_attr_offset_ptr)
+ *end_attr_offset_ptr = offset;
+ return attr_offset;
+ }
+ }
+ }
+
+ if (check_specification_or_abstract_origin) {
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
+ DWARFDIE die =
+ const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
+ if (die) {
+ dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
+ die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
+ false);
+ if (die_offset)
+ return die_offset;
+ }
+ }
+
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
+ DWARFDIE die =
+ const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
+ if (die) {
+ dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
+ die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
+ false);
+ if (die_offset)
+ return die_offset;
+ }
+ }
+ }
+
+ if (!dwo_symbol_file)
+ return 0;
+
+ DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
+ if (!dwo_cu)
+ return 0;
+
+ DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
+ if (!dwo_cu_die.IsValid())
+ return 0;
+
+ return dwo_cu_die.GetDIE()->GetAttributeValue(
+ dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr,
+ check_specification_or_abstract_origin);
}
//----------------------------------------------------------------------
@@ -1094,19 +976,15 @@ DWARFDebugInfoEntry::GetAttributeValue
// and will only be available as long as the SymbolFileDWARF is still around
// and it's content doesn't change.
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetAttributeValueAsString
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- const char* fail_value,
- bool check_specification_or_abstract_origin) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.AsCString();
- return fail_value;
+const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, const char *fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.AsCString();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1114,20 +992,15 @@ DWARFDebugInfoEntry::GetAttributeValueAs
//
// Get the value of an attribute as unsigned and return it.
//----------------------------------------------------------------------
-uint64_t
-DWARFDebugInfoEntry::GetAttributeValueAsUnsigned
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Unsigned();
- return fail_value;
+uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Unsigned();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1135,20 +1008,15 @@ DWARFDebugInfoEntry::GetAttributeValueAs
//
// Get the value of an attribute a signed value and return it.
//----------------------------------------------------------------------
-int64_t
-DWARFDebugInfoEntry::GetAttributeValueAsSigned
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- int64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Signed();
- return fail_value;
+int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, int64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Signed();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1157,36 +1025,26 @@ DWARFDebugInfoEntry::GetAttributeValueAs
// Get the value of an attribute as reference and fix up and compile
// unit relative offsets as needed.
//----------------------------------------------------------------------
-uint64_t
-DWARFDebugInfoEntry::GetAttributeValueAsReference
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Reference();
- return fail_value;
-}
-
-uint64_t
-DWARFDebugInfoEntry::GetAttributeValueAsAddress
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr, check_specification_or_abstract_origin))
- return form_value.Address();
- return fail_value;
+uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Reference();
+ return fail_value;
+}
+
+uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
+ check_specification_or_abstract_origin))
+ return form_value.Address();
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1197,27 +1055,20 @@ DWARFDebugInfoEntry::GetAttributeValueAs
//
// Returns the hi_pc or fail_value.
//----------------------------------------------------------------------
-dw_addr_t
-DWARFDebugInfoEntry::GetAttributeHighPC
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t lo_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- DWARFFormValue form_value;
- if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr, check_specification_or_abstract_origin))
- {
- dw_form_t form = form_value.Form();
- if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
- return form_value.Address();
-
- // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
- return lo_pc + form_value.Unsigned();
- }
- return fail_value;
+dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t lo_pc,
+ uint64_t fail_value, bool check_specification_or_abstract_origin) const {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
+ check_specification_or_abstract_origin)) {
+ dw_form_t form = form_value.Form();
+ if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
+ return form_value.Address();
+
+ // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
+ return lo_pc + form_value.Unsigned();
+ }
+ return fail_value;
}
//----------------------------------------------------------------------
@@ -1228,61 +1079,48 @@ DWARFDebugInfoEntry::GetAttributeHighPC
//
// Returns true or sets lo_pc and hi_pc to fail_value.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::GetAttributeAddressRange
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t& lo_pc,
- dw_addr_t& hi_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin
-) const
-{
- lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value, check_specification_or_abstract_origin);
- if (lo_pc != fail_value)
- {
- hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value, check_specification_or_abstract_origin);
- if (hi_pc != fail_value)
- return true;
- }
- lo_pc = fail_value;
- hi_pc = fail_value;
- return false;
-}
-
-size_t
-DWARFDebugInfoEntry::GetAttributeAddressRanges (SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFRangeList &ranges,
- bool check_hi_lo_pc,
- bool check_specification_or_abstract_origin) const
-{
- ranges.Clear();
-
- dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data,
- cu,
- DW_AT_ranges,
- DW_INVALID_OFFSET,
- check_specification_or_abstract_origin);
- if (debug_ranges_offset != DW_INVALID_OFFSET)
- {
- DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
-
- debug_ranges->FindRanges(debug_ranges_offset, ranges);
- ranges.Slide (cu->GetBaseAddress());
- }
- else if (check_hi_lo_pc)
- {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange (dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS, check_specification_or_abstract_origin))
- {
- if (lo_pc < hi_pc)
- ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
- }
+bool DWARFDebugInfoEntry::GetAttributeAddressRange(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
+ dw_addr_t &hi_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin) const {
+ lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
+ check_specification_or_abstract_origin);
+ if (lo_pc != fail_value) {
+ hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value,
+ check_specification_or_abstract_origin);
+ if (hi_pc != fail_value)
+ return true;
+ }
+ lo_pc = fail_value;
+ hi_pc = fail_value;
+ return false;
+}
+
+size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFRangeList &ranges, bool check_hi_lo_pc,
+ bool check_specification_or_abstract_origin) const {
+ ranges.Clear();
+
+ dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
+ dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET,
+ check_specification_or_abstract_origin);
+ if (debug_ranges_offset != DW_INVALID_OFFSET) {
+ DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
+
+ debug_ranges->FindRanges(debug_ranges_offset, ranges);
+ ranges.Slide(cu->GetBaseAddress());
+ } else if (check_hi_lo_pc) {
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
+ LLDB_INVALID_ADDRESS,
+ check_specification_or_abstract_origin)) {
+ if (lo_pc < hi_pc)
+ ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
}
- return ranges.GetSize();
+ }
+ return ranges.GetSize();
}
//----------------------------------------------------------------------
@@ -1291,14 +1129,9 @@ DWARFDebugInfoEntry::GetAttributeAddress
// Get value of the DW_AT_name attribute and return it if one exists,
// else return NULL.
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu
-) const
-{
- return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const {
+ return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
}
//----------------------------------------------------------------------
@@ -1307,31 +1140,28 @@ DWARFDebugInfoEntry::GetName
// Get value of the DW_AT_MIPS_linkage_name attribute and return it if
// one exists, else return the value of the DW_AT_name attribute
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetMangledName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- bool substitute_name_allowed
-) const
-{
- const char* name = nullptr;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true);
- if (name)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true);
- if (name)
- return name;
-
- if (!substitute_name_allowed)
- return nullptr;
+const char *
+DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ bool substitute_name_allowed) const {
+ const char *name = nullptr;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
+ nullptr, true);
+ if (name)
+ return name;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
+ true);
+ if (name)
return name;
-}
+ if (!substitute_name_allowed)
+ return nullptr;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ return name;
+}
//----------------------------------------------------------------------
// GetPubname
@@ -1339,29 +1169,25 @@ DWARFDebugInfoEntry::GetMangledName
// Get value the name for a DIE as it should appear for a
// .debug_pubnames or .debug_pubtypes section.
//----------------------------------------------------------------------
-const char*
-DWARFDebugInfoEntry::GetPubname
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu
-) const
-{
- const char* name = nullptr;
- if (!dwarf2Data)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr, true);
- if (name)
- return name;
-
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr, true);
- if (name)
- return name;
+const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const {
+ const char *name = nullptr;
+ if (!dwarf2Data)
+ return name;
- name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
+ nullptr, true);
+ if (name)
+ return name;
+
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
+ true);
+ if (name)
return name;
-}
+ name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+ return name;
+}
//----------------------------------------------------------------------
// GetName
@@ -1372,41 +1198,30 @@ DWARFDebugInfoEntry::GetPubname
// into the stream, and if no DW_AT_name attribute exists for the DIE
// then nothing is printed.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::GetName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- Stream &s
-)
-{
- if (dwarf2Data == NULL)
- {
- s.PutCString("NULL");
- return false;
- }
-
- DWARFDebugInfoEntry die;
- lldb::offset_t offset = die_offset;
- if (die.Extract(dwarf2Data, cu, &offset))
- {
- if (die.IsNULL())
- {
- s.PutCString("NULL");
- return true;
- }
- else
- {
- const char* name = die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
- if (name)
- {
- s.PutCString(name);
- return true;
- }
- }
- }
+bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset, Stream &s) {
+ if (dwarf2Data == NULL) {
+ s.PutCString("NULL");
return false;
+ }
+
+ DWARFDebugInfoEntry die;
+ lldb::offset_t offset = die_offset;
+ if (die.Extract(dwarf2Data, cu, &offset)) {
+ if (die.IsNULL()) {
+ s.PutCString("NULL");
+ return true;
+ } else {
+ const char *name = die.GetAttributeValueAsString(
+ dwarf2Data, cu, DW_AT_name, nullptr, true);
+ if (name) {
+ s.PutCString(name);
+ return true;
+ }
+ }
+ }
+ return false;
}
//----------------------------------------------------------------------
@@ -1417,144 +1232,168 @@ DWARFDebugInfoEntry::GetName
// the supplied stream. This is used to show the name of types given
// a type identifier.
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::AppendTypeName
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- Stream &s
-)
-{
- if (dwarf2Data == NULL)
- {
- s.PutCString("NULL");
- return false;
- }
-
- DWARFDebugInfoEntry die;
- lldb::offset_t offset = die_offset;
- if (die.Extract(dwarf2Data, cu, &offset))
- {
- if (die.IsNULL())
- {
- s.PutCString("NULL");
- return true;
- }
- else
- {
- const char* name = die.GetPubname(dwarf2Data, cu);
- if (name)
- s.PutCString(name);
- else
- {
- bool result = true;
- const DWARFAbbreviationDeclaration* abbrevDecl = die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
- if (abbrevDecl == NULL)
- return false;
-
- switch (abbrevDecl->Tag())
- {
- case DW_TAG_array_type: break; // print out a "[]" after printing the full type of the element below
- case DW_TAG_base_type: s.PutCString("base "); break;
- case DW_TAG_class_type: s.PutCString("class "); break;
- case DW_TAG_const_type: s.PutCString("const "); break;
- case DW_TAG_enumeration_type: s.PutCString("enum "); break;
- case DW_TAG_file_type: s.PutCString("file "); break;
- case DW_TAG_interface_type: s.PutCString("interface "); break;
- case DW_TAG_packed_type: s.PutCString("packed "); break;
- case DW_TAG_pointer_type: break; // print out a '*' after printing the full type below
- case DW_TAG_ptr_to_member_type: break; // print out a '*' after printing the full type below
- case DW_TAG_reference_type: break; // print out a '&' after printing the full type below
- case DW_TAG_restrict_type: s.PutCString("restrict "); break;
- case DW_TAG_set_type: s.PutCString("set "); break;
- case DW_TAG_shared_type: s.PutCString("shared "); break;
- case DW_TAG_string_type: s.PutCString("string "); break;
- case DW_TAG_structure_type: s.PutCString("struct "); break;
- case DW_TAG_subrange_type: s.PutCString("subrange "); break;
- case DW_TAG_subroutine_type: s.PutCString("function "); break;
- case DW_TAG_thrown_type: s.PutCString("thrown "); break;
- case DW_TAG_union_type: s.PutCString("union "); break;
- case DW_TAG_unspecified_type: s.PutCString("unspecified "); break;
- case DW_TAG_volatile_type: s.PutCString("volatile "); break;
- default:
- return false;
- }
+bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset,
+ Stream &s) {
+ if (dwarf2Data == NULL) {
+ s.PutCString("NULL");
+ return false;
+ }
- // Follow the DW_AT_type if possible
- DWARFFormValue form_value;
- if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value))
- {
- uint64_t next_die_offset = form_value.Reference();
- result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
- }
+ DWARFDebugInfoEntry die;
+ lldb::offset_t offset = die_offset;
+ if (die.Extract(dwarf2Data, cu, &offset)) {
+ if (die.IsNULL()) {
+ s.PutCString("NULL");
+ return true;
+ } else {
+ const char *name = die.GetPubname(dwarf2Data, cu);
+ if (name)
+ s.PutCString(name);
+ else {
+ bool result = true;
+ const DWARFAbbreviationDeclaration *abbrevDecl =
+ die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
- switch (abbrevDecl->Tag())
- {
- case DW_TAG_array_type: s.PutCString("[]"); break;
- case DW_TAG_pointer_type: s.PutChar('*'); break;
- case DW_TAG_ptr_to_member_type: s.PutChar('*'); break;
- case DW_TAG_reference_type: s.PutChar('&'); break;
- default:
- break;
- }
- return result;
- }
- }
- }
- return false;
-}
+ if (abbrevDecl == NULL)
+ return false;
-bool
-DWARFDebugInfoEntry::Contains (const DWARFDebugInfoEntry *die) const
-{
- if (die)
- {
- const dw_offset_t die_offset = die->GetOffset();
- if (die_offset > GetOffset())
- {
- const DWARFDebugInfoEntry *sibling = GetSibling();
- assert (sibling); // TODO: take this out
- if (sibling)
- return die_offset < sibling->GetOffset();
- }
+ switch (abbrevDecl->Tag()) {
+ case DW_TAG_array_type:
+ break; // print out a "[]" after printing the full type of the element
+ // below
+ case DW_TAG_base_type:
+ s.PutCString("base ");
+ break;
+ case DW_TAG_class_type:
+ s.PutCString("class ");
+ break;
+ case DW_TAG_const_type:
+ s.PutCString("const ");
+ break;
+ case DW_TAG_enumeration_type:
+ s.PutCString("enum ");
+ break;
+ case DW_TAG_file_type:
+ s.PutCString("file ");
+ break;
+ case DW_TAG_interface_type:
+ s.PutCString("interface ");
+ break;
+ case DW_TAG_packed_type:
+ s.PutCString("packed ");
+ break;
+ case DW_TAG_pointer_type:
+ break; // print out a '*' after printing the full type below
+ case DW_TAG_ptr_to_member_type:
+ break; // print out a '*' after printing the full type below
+ case DW_TAG_reference_type:
+ break; // print out a '&' after printing the full type below
+ case DW_TAG_restrict_type:
+ s.PutCString("restrict ");
+ break;
+ case DW_TAG_set_type:
+ s.PutCString("set ");
+ break;
+ case DW_TAG_shared_type:
+ s.PutCString("shared ");
+ break;
+ case DW_TAG_string_type:
+ s.PutCString("string ");
+ break;
+ case DW_TAG_structure_type:
+ s.PutCString("struct ");
+ break;
+ case DW_TAG_subrange_type:
+ s.PutCString("subrange ");
+ break;
+ case DW_TAG_subroutine_type:
+ s.PutCString("function ");
+ break;
+ case DW_TAG_thrown_type:
+ s.PutCString("thrown ");
+ break;
+ case DW_TAG_union_type:
+ s.PutCString("union ");
+ break;
+ case DW_TAG_unspecified_type:
+ s.PutCString("unspecified ");
+ break;
+ case DW_TAG_volatile_type:
+ s.PutCString("volatile ");
+ break;
+ default:
+ return false;
+ }
+
+ // Follow the DW_AT_type if possible
+ DWARFFormValue form_value;
+ if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
+ uint64_t next_die_offset = form_value.Reference();
+ result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
+ }
+
+ switch (abbrevDecl->Tag()) {
+ case DW_TAG_array_type:
+ s.PutCString("[]");
+ break;
+ case DW_TAG_pointer_type:
+ s.PutChar('*');
+ break;
+ case DW_TAG_ptr_to_member_type:
+ s.PutChar('*');
+ break;
+ case DW_TAG_reference_type:
+ s.PutChar('&');
+ break;
+ default:
+ break;
+ }
+ return result;
+ }
+ }
+ }
+ return false;
+}
+
+bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const {
+ if (die) {
+ const dw_offset_t die_offset = die->GetOffset();
+ if (die_offset > GetOffset()) {
+ const DWARFDebugInfoEntry *sibling = GetSibling();
+ assert(sibling); // TODO: take this out
+ if (sibling)
+ return die_offset < sibling->GetOffset();
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// BuildAddressRangeTable
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::BuildAddressRangeTable
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges
-) const
-{
- if (m_tag)
- {
- if (m_tag == DW_TAG_subprogram)
- {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
- {
- /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
- debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
- }
- }
-
-
- const DWARFDebugInfoEntry* child = GetFirstChild();
- while (child)
- {
- child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
- child = child->GetSibling();
- }
+void DWARFDebugInfoEntry::BuildAddressRangeTable(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const {
+ if (m_tag) {
+ if (m_tag == DW_TAG_subprogram) {
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
+ LLDB_INVALID_ADDRESS)) {
+ /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
+ /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
+ debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
+ }
+ }
+
+ const DWARFDebugInfoEntry *child = GetFirstChild();
+ while (child) {
+ child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
+ child = child->GetSibling();
}
+ }
}
//----------------------------------------------------------------------
@@ -1565,477 +1404,478 @@ DWARFDebugInfoEntry::BuildAddressRangeTa
// table instead of the compile unit offset (which is the way the
// standard .debug_aranges section does it).
//----------------------------------------------------------------------
-void
-DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
-(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges
-) const
-{
- if (m_tag)
- {
- if (m_tag == DW_TAG_subprogram)
- {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS))
- {
- // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
- debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
- }
- }
-
- const DWARFDebugInfoEntry* child = GetFirstChild();
- while (child)
- {
- child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
- child = child->GetSibling();
- }
- }
+void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const {
+ if (m_tag) {
+ if (m_tag == DW_TAG_subprogram) {
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
+ LLDB_INVALID_ADDRESS)) {
+ // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
+ // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
+ debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
+ }
+ }
+
+ const DWARFDebugInfoEntry *child = GetFirstChild();
+ while (child) {
+ child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
+ child = child->GetSibling();
+ }
+ }
+}
+
+void DWARFDebugInfoEntry::GetDeclContextDIEs(
+ DWARFCompileUnit *cu, DWARFDIECollection &decl_context_dies) const {
+
+ DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
+ die.GetDeclContextDIEs(decl_context_dies);
+}
+
+void DWARFDebugInfoEntry::GetDWARFDeclContext(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ DWARFDeclContext &dwarf_decl_ctx) const {
+ const dw_tag_t tag = Tag();
+ if (tag != DW_TAG_compile_unit) {
+ dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
+ DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
+ if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
+ if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit)
+ parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
+ parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
+ dwarf_decl_ctx);
+ }
+ }
+}
+
+bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ const DWARFDeclContext &dwarf_decl_ctx) const {
+
+ DWARFDeclContext this_dwarf_decl_ctx;
+ GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx);
+ return this_dwarf_decl_ctx == dwarf_decl_ctx;
}
-void
-DWARFDebugInfoEntry::GetDeclContextDIEs (DWARFCompileUnit* cu,
- DWARFDIECollection &decl_context_dies) const
-{
-
- DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this));
- die.GetDeclContextDIEs(decl_context_dies);
-}
-
-void
-DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDeclContext &dwarf_decl_ctx) const
-{
- const dw_tag_t tag = Tag();
- if (tag != DW_TAG_compile_unit)
- {
- dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
- if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this)
- {
- if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit)
- parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext (parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(), dwarf_decl_ctx);
- }
- }
+DWARFDIE
+DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu) const {
+ DWARFAttributes attributes;
+ GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+ return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
}
+DWARFDIE
+DWARFDebugInfoEntry::GetParentDeclContextDIE(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes) const {
+ DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
+
+ while (die) {
+ // If this is the original DIE that we are searching for a declaration
+ // for, then don't look in the cache as we don't want our own decl
+ // context to be our decl context...
+ if (die.GetDIE() != this) {
+ switch (die.Tag()) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ return die;
-bool
-DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFDeclContext &dwarf_decl_ctx) const
-{
-
- DWARFDeclContext this_dwarf_decl_ctx;
- GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx);
- return this_dwarf_decl_ctx == dwarf_decl_ctx;
-}
+ default:
+ break;
+ }
+ }
-DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu) const
-{
- DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
- return GetParentDeclContextDIE (dwarf2Data, cu, attributes);
-}
+ dw_offset_t die_offset;
-DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes) const
-{
- DWARFDIE die (cu, const_cast<DWARFDebugInfoEntry *>(this));
-
- while (die)
- {
- // If this is the original DIE that we are searching for a declaration
- // for, then don't look in the cache as we don't want our own decl
- // context to be our decl context...
- if (die.GetDIE() != this)
- {
- switch (die.Tag())
- {
- case DW_TAG_compile_unit:
- case DW_TAG_namespace:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- return die;
-
- default:
- break;
- }
- }
-
- dw_offset_t die_offset;
-
- die_offset = attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE spec_die = cu->GetDIE (die_offset);
- if (spec_die)
- {
- DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
- }
-
- die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin, DW_INVALID_OFFSET);
- if (die_offset != DW_INVALID_OFFSET)
- {
- DWARFDIE abs_die = cu->GetDIE (die_offset);
- if (abs_die)
- {
- DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
- if (decl_ctx_die)
- return decl_ctx_die;
- }
- }
-
- die = die.GetParent();
- }
- return DWARFDIE();
-}
+ die_offset =
+ attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
+ if (die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE spec_die = cu->GetDIE(die_offset);
+ if (spec_die) {
+ DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+ }
+
+ die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
+ DW_INVALID_OFFSET);
+ if (die_offset != DW_INVALID_OFFSET) {
+ DWARFDIE abs_die = cu->GetDIE(die_offset);
+ if (abs_die) {
+ DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+ }
+
+ die = die.GetParent();
+ }
+ return DWARFDIE();
+}
+
+const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ std::string &storage) const {
+ DWARFAttributes attributes;
+ GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+ return GetQualifiedName(dwarf2Data, cu, attributes, storage);
+}
+
+const char *DWARFDebugInfoEntry::GetQualifiedName(
+ SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes, std::string &storage) const {
+
+ const char *name = GetName(dwarf2Data, cu);
+
+ if (name) {
+ DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
+ storage.clear();
+ // TODO: change this to get the correct decl context parent....
+ while (parent_decl_ctx_die) {
+ const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
+ switch (parent_tag) {
+ case DW_TAG_namespace: {
+ const char *namespace_name = parent_decl_ctx_die.GetName();
+ if (namespace_name) {
+ storage.insert(0, "::");
+ storage.insert(0, namespace_name);
+ } else {
+ storage.insert(0, "(anonymous namespace)::");
+ }
+ parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
+ } break;
+
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type: {
+ const char *class_union_struct_name = parent_decl_ctx_die.GetName();
+
+ if (class_union_struct_name) {
+ storage.insert(0, "::");
+ storage.insert(0, class_union_struct_name);
+ }
+ parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
+ } break;
+ default:
+ parent_decl_ctx_die.Clear();
+ break;
+ }
+ }
-const char *
-DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- std::string &storage) const
-{
- DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
- return GetQualifiedName (dwarf2Data, cu, attributes, storage);
-}
-
-const char*
-DWARFDebugInfoEntry::GetQualifiedName (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes,
- std::string &storage) const
-{
-
- const char *name = GetName (dwarf2Data, cu);
-
- if (name)
- {
- DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
- storage.clear();
- // TODO: change this to get the correct decl context parent....
- while (parent_decl_ctx_die)
- {
- const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
- switch (parent_tag)
- {
- case DW_TAG_namespace:
- {
- const char *namespace_name = parent_decl_ctx_die.GetName ();
- if (namespace_name)
- {
- storage.insert (0, "::");
- storage.insert (0, namespace_name);
- }
- else
- {
- storage.insert (0, "(anonymous namespace)::");
- }
- parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
- }
- break;
-
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- {
- const char *class_union_struct_name = parent_decl_ctx_die.GetName ();
-
- if (class_union_struct_name)
- {
- storage.insert (0, "::");
- storage.insert (0, class_union_struct_name);
- }
- parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
- }
- break;
-
- default:
- parent_decl_ctx_die.Clear();
- break;
- }
- }
-
- if (storage.empty())
- storage.append ("::");
-
- storage.append (name);
- }
- if (storage.empty())
- return NULL;
- return storage.c_str();
-}
+ if (storage.empty())
+ storage.append("::");
+ storage.append(name);
+ }
+ if (storage.empty())
+ return NULL;
+ return storage.c_str();
+}
//----------------------------------------------------------------------
// LookupAddress
//----------------------------------------------------------------------
-bool
-DWARFDebugInfoEntry::LookupAddress
-(
- const dw_addr_t address,
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugInfoEntry** function_die,
- DWARFDebugInfoEntry** block_die
-)
-{
- bool found_address = false;
- if (m_tag)
- {
- bool check_children = false;
- bool match_addr_range = false;
- // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, DW_TAG_value_to_name(tag), address);
- switch (m_tag)
- {
- case DW_TAG_array_type : break;
- case DW_TAG_class_type : check_children = true; break;
- case DW_TAG_entry_point : break;
- case DW_TAG_enumeration_type : break;
- case DW_TAG_formal_parameter : break;
- case DW_TAG_imported_declaration : break;
- case DW_TAG_label : break;
- case DW_TAG_lexical_block : check_children = true; match_addr_range = true; break;
- case DW_TAG_member : break;
- case DW_TAG_pointer_type : break;
- case DW_TAG_reference_type : break;
- case DW_TAG_compile_unit : match_addr_range = true; break;
- case DW_TAG_string_type : break;
- case DW_TAG_structure_type : check_children = true; break;
- case DW_TAG_subroutine_type : break;
- case DW_TAG_typedef : break;
- case DW_TAG_union_type : break;
- case DW_TAG_unspecified_parameters : break;
- case DW_TAG_variant : break;
- case DW_TAG_common_block : check_children = true; break;
- case DW_TAG_common_inclusion : break;
- case DW_TAG_inheritance : break;
- case DW_TAG_inlined_subroutine : check_children = true; match_addr_range = true; break;
- case DW_TAG_module : match_addr_range = true; break;
- case DW_TAG_ptr_to_member_type : break;
- case DW_TAG_set_type : break;
- case DW_TAG_subrange_type : break;
- case DW_TAG_with_stmt : break;
- case DW_TAG_access_declaration : break;
- case DW_TAG_base_type : break;
- case DW_TAG_catch_block : match_addr_range = true; break;
- case DW_TAG_const_type : break;
- case DW_TAG_constant : break;
- case DW_TAG_enumerator : break;
- case DW_TAG_file_type : break;
- case DW_TAG_friend : break;
- case DW_TAG_namelist : break;
- case DW_TAG_namelist_item : break;
- case DW_TAG_packed_type : break;
- case DW_TAG_subprogram : match_addr_range = true; break;
- case DW_TAG_template_type_parameter : break;
- case DW_TAG_template_value_parameter : break;
- case DW_TAG_thrown_type : break;
- case DW_TAG_try_block : match_addr_range = true; break;
- case DW_TAG_variant_part : break;
- case DW_TAG_variable : break;
- case DW_TAG_volatile_type : break;
- case DW_TAG_dwarf_procedure : break;
- case DW_TAG_restrict_type : break;
- case DW_TAG_interface_type : break;
- case DW_TAG_namespace : check_children = true; break;
- case DW_TAG_imported_module : break;
- case DW_TAG_unspecified_type : break;
- case DW_TAG_partial_unit : break;
- case DW_TAG_imported_unit : break;
- case DW_TAG_shared_type : break;
- default: break;
- }
-
- if (match_addr_range)
- {
- dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (lo_pc != LLDB_INVALID_ADDRESS)
- {
- dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
- if (hi_pc != LLDB_INVALID_ADDRESS)
- {
- // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
- if ((lo_pc <= address) && (address < hi_pc))
- {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag)
- {
- case DW_TAG_compile_unit: // File
- check_children = ((function_die != NULL) || (block_die != NULL));
- break;
-
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != NULL);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die)
- {
- *block_die = this;
- check_children = true;
- }
- break;
-
- default:
- check_children = true;
- break;
- }
- }
- }
- else
- { // compile units may not have a valid high/low pc when there
- // are address gaps in subroutines so we must always search
- // if there is no valid high and low PC
- check_children = (m_tag == DW_TAG_compile_unit) && ((function_die != NULL) || (block_die != NULL));
- }
- }
- else
- {
- dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
- if (debug_ranges_offset != DW_INVALID_OFFSET)
- {
- DWARFRangeList ranges;
- DWARFDebugRanges* debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(debug_ranges_offset, ranges);
- // All DW_AT_ranges are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
- ranges.Slide (cu->GetBaseAddress());
- if (ranges.FindEntryThatContains(address))
- {
- found_address = true;
- // puts("***MATCH***");
- switch (m_tag)
- {
- case DW_TAG_compile_unit: // File
- check_children = ((function_die != NULL) || (block_die != NULL));
- break;
-
- case DW_TAG_subprogram: // Function
- if (function_die)
- *function_die = this;
- check_children = (block_die != NULL);
- break;
-
- case DW_TAG_inlined_subroutine: // Inlined Function
- case DW_TAG_lexical_block: // Block { } in code
- if (block_die)
- {
- *block_die = this;
- check_children = true;
- }
- break;
-
- default:
- check_children = true;
- break;
- }
- }
- else
- {
- check_children = false;
- }
- }
- }
- }
+bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
+ SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugInfoEntry **function_die,
+ DWARFDebugInfoEntry **block_die) {
+ bool found_address = false;
+ if (m_tag) {
+ bool check_children = false;
+ bool match_addr_range = false;
+ // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
+ // DW_TAG_value_to_name(tag), address);
+ switch (m_tag) {
+ case DW_TAG_array_type:
+ break;
+ case DW_TAG_class_type:
+ check_children = true;
+ break;
+ case DW_TAG_entry_point:
+ break;
+ case DW_TAG_enumeration_type:
+ break;
+ case DW_TAG_formal_parameter:
+ break;
+ case DW_TAG_imported_declaration:
+ break;
+ case DW_TAG_label:
+ break;
+ case DW_TAG_lexical_block:
+ check_children = true;
+ match_addr_range = true;
+ break;
+ case DW_TAG_member:
+ break;
+ case DW_TAG_pointer_type:
+ break;
+ case DW_TAG_reference_type:
+ break;
+ case DW_TAG_compile_unit:
+ match_addr_range = true;
+ break;
+ case DW_TAG_string_type:
+ break;
+ case DW_TAG_structure_type:
+ check_children = true;
+ break;
+ case DW_TAG_subroutine_type:
+ break;
+ case DW_TAG_typedef:
+ break;
+ case DW_TAG_union_type:
+ break;
+ case DW_TAG_unspecified_parameters:
+ break;
+ case DW_TAG_variant:
+ break;
+ case DW_TAG_common_block:
+ check_children = true;
+ break;
+ case DW_TAG_common_inclusion:
+ break;
+ case DW_TAG_inheritance:
+ break;
+ case DW_TAG_inlined_subroutine:
+ check_children = true;
+ match_addr_range = true;
+ break;
+ case DW_TAG_module:
+ match_addr_range = true;
+ break;
+ case DW_TAG_ptr_to_member_type:
+ break;
+ case DW_TAG_set_type:
+ break;
+ case DW_TAG_subrange_type:
+ break;
+ case DW_TAG_with_stmt:
+ break;
+ case DW_TAG_access_declaration:
+ break;
+ case DW_TAG_base_type:
+ break;
+ case DW_TAG_catch_block:
+ match_addr_range = true;
+ break;
+ case DW_TAG_const_type:
+ break;
+ case DW_TAG_constant:
+ break;
+ case DW_TAG_enumerator:
+ break;
+ case DW_TAG_file_type:
+ break;
+ case DW_TAG_friend:
+ break;
+ case DW_TAG_namelist:
+ break;
+ case DW_TAG_namelist_item:
+ break;
+ case DW_TAG_packed_type:
+ break;
+ case DW_TAG_subprogram:
+ match_addr_range = true;
+ break;
+ case DW_TAG_template_type_parameter:
+ break;
+ case DW_TAG_template_value_parameter:
+ break;
+ case DW_TAG_thrown_type:
+ break;
+ case DW_TAG_try_block:
+ match_addr_range = true;
+ break;
+ case DW_TAG_variant_part:
+ break;
+ case DW_TAG_variable:
+ break;
+ case DW_TAG_volatile_type:
+ break;
+ case DW_TAG_dwarf_procedure:
+ break;
+ case DW_TAG_restrict_type:
+ break;
+ case DW_TAG_interface_type:
+ break;
+ case DW_TAG_namespace:
+ check_children = true;
+ break;
+ case DW_TAG_imported_module:
+ break;
+ case DW_TAG_unspecified_type:
+ break;
+ case DW_TAG_partial_unit:
+ break;
+ case DW_TAG_imported_unit:
+ break;
+ case DW_TAG_shared_type:
+ break;
+ default:
+ break;
+ }
+ if (match_addr_range) {
+ dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc,
+ LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS) {
+ dw_addr_t hi_pc =
+ GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS) {
+ // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ",
+ // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
+ if ((lo_pc <= address) && (address < hi_pc)) {
+ found_address = true;
+ // puts("***MATCH***");
+ switch (m_tag) {
+ case DW_TAG_compile_unit: // File
+ check_children = ((function_die != NULL) || (block_die != NULL));
+ break;
+
+ case DW_TAG_subprogram: // Function
+ if (function_die)
+ *function_die = this;
+ check_children = (block_die != NULL);
+ break;
+
+ case DW_TAG_inlined_subroutine: // Inlined Function
+ case DW_TAG_lexical_block: // Block { } in code
+ if (block_die) {
+ *block_die = this;
+ check_children = true;
+ }
+ break;
- if (check_children)
- {
- // printf("checking children\n");
- DWARFDebugInfoEntry* child = GetFirstChild();
- while (child)
- {
- if (child->LookupAddress(address, dwarf2Data, cu, function_die, block_die))
- return true;
- child = child->GetSibling();
+ default:
+ check_children = true;
+ break;
}
- }
- }
- return found_address;
-}
-
-const DWARFAbbreviationDeclaration*
-DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit *cu,
- lldb::offset_t &offset) const
-{
- if (dwarf2Data)
- {
- offset = GetOffset();
+ }
+ } else { // compile units may not have a valid high/low pc when there
+ // are address gaps in subroutines so we must always search
+ // if there is no valid high and low PC
+ check_children = (m_tag == DW_TAG_compile_unit) &&
+ ((function_die != NULL) || (block_die != NULL));
+ }
+ } else {
+ dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
+ dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
+ if (debug_ranges_offset != DW_INVALID_OFFSET) {
+ DWARFRangeList ranges;
+ DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
+ debug_ranges->FindRanges(debug_ranges_offset, ranges);
+ // All DW_AT_ranges are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ ranges.Slide(cu->GetBaseAddress());
+ if (ranges.FindEntryThatContains(address)) {
+ found_address = true;
+ // puts("***MATCH***");
+ switch (m_tag) {
+ case DW_TAG_compile_unit: // File
+ check_children = ((function_die != NULL) || (block_die != NULL));
+ break;
+
+ case DW_TAG_subprogram: // Function
+ if (function_die)
+ *function_die = this;
+ check_children = (block_die != NULL);
+ break;
+
+ case DW_TAG_inlined_subroutine: // Inlined Function
+ case DW_TAG_lexical_block: // Block { } in code
+ if (block_die) {
+ *block_die = this;
+ check_children = true;
+ }
+ break;
- const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
- if (abbrev_set)
- {
- const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx);
- if (abbrev_decl)
- {
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
-
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
- GetOffset(),
- (uint32_t)abbrev_decl->Code(),
- (uint32_t)abbrev_code);
+ default:
+ check_children = true;
+ break;
}
- }
+ } else {
+ check_children = false;
+ }
+ }
+ }
+ }
+
+ if (check_children) {
+ // printf("checking children\n");
+ DWARFDebugInfoEntry *child = GetFirstChild();
+ while (child) {
+ if (child->LookupAddress(address, dwarf2Data, cu, function_die,
+ block_die))
+ return true;
+ child = child->GetSibling();
+ }
}
- offset = DW_INVALID_OFFSET;
- return NULL;
+ }
+ return found_address;
}
-
-bool
-DWARFDebugInfoEntry::OffsetLessThan (const DWARFDebugInfoEntry& a, const DWARFDebugInfoEntry& b)
-{
- return a.GetOffset() < b.GetOffset();
-}
-
-void
-DWARFDebugInfoEntry::DumpDIECollection (Stream &strm, DWARFDebugInfoEntry::collection &die_collection)
-{
- DWARFDebugInfoEntry::const_iterator pos;
- DWARFDebugInfoEntry::const_iterator end = die_collection.end();
- strm.PutCString("\noffset parent sibling child\n");
- strm.PutCString("-------- -------- -------- --------\n");
- for (pos = die_collection.begin(); pos != end; ++pos)
- {
- const DWARFDebugInfoEntry& die_ref = *pos;
- const DWARFDebugInfoEntry* p = die_ref.GetParent();
- const DWARFDebugInfoEntry* s = die_ref.GetSibling();
- const DWARFDebugInfoEntry* c = die_ref.GetFirstChild();
- strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n",
- die_ref.GetOffset(),
- p ? p->GetOffset() : 0,
- s ? s->GetOffset() : 0,
- c ? c->GetOffset() : 0,
- die_ref.Tag(),
- DW_TAG_value_to_name(die_ref.Tag()),
- die_ref.HasChildren() ? " *" : "");
- }
+const DWARFAbbreviationDeclaration *
+DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ lldb::offset_t &offset) const {
+ if (dwarf2Data) {
+ offset = GetOffset();
+
+ const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ if (abbrev_set) {
+ const DWARFAbbreviationDeclaration *abbrev_decl =
+ abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
+ if (abbrev_decl) {
+ // Make sure the abbreviation code still matches. If it doesn't and
+ // the DWARF data was mmap'ed, the backing file might have been modified
+ // which is bad news.
+ const uint64_t abbrev_code =
+ dwarf2Data->get_debug_info_data().GetULEB128(&offset);
+
+ if (abbrev_decl->Code() == abbrev_code)
+ return abbrev_decl;
+
+ dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "0x%8.8x: the DWARF debug information has been modified (abbrev "
+ "code was %u, and is now %u)",
+ GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
+ }
+ }
+ }
+ offset = DW_INVALID_OFFSET;
+ return NULL;
+}
+
+bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a,
+ const DWARFDebugInfoEntry &b) {
+ return a.GetOffset() < b.GetOffset();
+}
+
+void DWARFDebugInfoEntry::DumpDIECollection(
+ Stream &strm, DWARFDebugInfoEntry::collection &die_collection) {
+ DWARFDebugInfoEntry::const_iterator pos;
+ DWARFDebugInfoEntry::const_iterator end = die_collection.end();
+ strm.PutCString("\noffset parent sibling child\n");
+ strm.PutCString("-------- -------- -------- --------\n");
+ for (pos = die_collection.begin(); pos != end; ++pos) {
+ const DWARFDebugInfoEntry &die_ref = *pos;
+ const DWARFDebugInfoEntry *p = die_ref.GetParent();
+ const DWARFDebugInfoEntry *s = die_ref.GetSibling();
+ const DWARFDebugInfoEntry *c = die_ref.GetFirstChild();
+ strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(),
+ p ? p->GetOffset() : 0, s ? s->GetOffset() : 0,
+ c ? c->GetOffset() : 0, die_ref.Tag(),
+ DW_TAG_value_to_name(die_ref.Tag()),
+ die_ref.HasChildren() ? " *" : "");
+ }
}
-
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Tue Sep 6 15:57:50 2016
@@ -13,390 +13,295 @@
#include "SymbolFileDWARF.h"
#include "llvm/ADT/SmallVector.h"
-#include "DWARFDebugAbbrev.h"
#include "DWARFAbbreviationDeclaration.h"
+#include "DWARFDebugAbbrev.h"
#include "DWARFDebugRanges.h"
-#include <vector>
#include <map>
#include <set>
+#include <vector>
-typedef std::map<const DWARFDebugInfoEntry*, dw_addr_t> DIEToAddressMap;
-typedef DIEToAddressMap::iterator DIEToAddressMapIter;
-typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter;
-
-typedef std::map<dw_addr_t, const DWARFDebugInfoEntry*> AddressToDIEMap;
-typedef AddressToDIEMap::iterator AddressToDIEMapIter;
-typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter;
-
-
-typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap;
-typedef DIEToDIEMap::iterator DIEToDIEMapIter;
-typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter;
-
-typedef std::map<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMap;
-typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter;
-typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter;
-
-typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap;
-typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter;
-typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
+typedef std::map<const DWARFDebugInfoEntry *, dw_addr_t> DIEToAddressMap;
+typedef DIEToAddressMap::iterator DIEToAddressMapIter;
+typedef DIEToAddressMap::const_iterator DIEToAddressMapConstIter;
+
+typedef std::map<dw_addr_t, const DWARFDebugInfoEntry *> AddressToDIEMap;
+typedef AddressToDIEMap::iterator AddressToDIEMapIter;
+typedef AddressToDIEMap::const_iterator AddressToDIEMapConstIter;
+
+typedef std::map<dw_offset_t, dw_offset_t> DIEToDIEMap;
+typedef DIEToDIEMap::iterator DIEToDIEMapIter;
+typedef DIEToDIEMap::const_iterator DIEToDIEMapConstIter;
+
+typedef std::map<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMap;
+typedef UInt32ToDIEMap::iterator UInt32ToDIEMapIter;
+typedef UInt32ToDIEMap::const_iterator UInt32ToDIEMapConstIter;
+
+typedef std::multimap<uint32_t, const DWARFDebugInfoEntry *> UInt32ToDIEMMap;
+typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter;
+typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
class DWARFDeclContext;
#define DIE_SIBLING_IDX_BITSIZE 31
#define DIE_ABBR_IDX_BITSIZE 15
-class DWARFDebugInfoEntry
-{
+class DWARFDebugInfoEntry {
public:
- typedef std::vector<DWARFDebugInfoEntry> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- typedef std::vector<dw_offset_t> offset_collection;
- typedef offset_collection::iterator offset_collection_iterator;
- typedef offset_collection::const_iterator offset_collection_const_iterator;
-
- DWARFDebugInfoEntry():
- m_offset (DW_INVALID_OFFSET),
- m_parent_idx (0),
- m_sibling_idx (0),
- m_empty_children(false),
- m_abbr_idx (0),
- m_has_children (false),
- m_tag (0)
- {
- }
-
- void Clear ()
- {
- m_offset = DW_INVALID_OFFSET;
- m_parent_idx = 0;
- m_sibling_idx = 0;
- m_empty_children = false;
- m_abbr_idx = 0;
- m_has_children = false;
- m_tag = 0;
- }
-
- bool Contains (const DWARFDebugInfoEntry *die) const;
-
- void BuildAddressRangeTable(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges) const;
-
- void BuildFunctionAddressRangeTable(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugAranges* debug_aranges) const;
-
- bool FastExtract(
- const lldb_private::DWARFDataExtractor& debug_info_data,
- const DWARFCompileUnit* cu,
- const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
- lldb::offset_t* offset_ptr);
-
- bool Extract(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- lldb::offset_t* offset_ptr);
-
- bool LookupAddress(
- const dw_addr_t address,
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFDebugInfoEntry** function_die,
- DWARFDebugInfoEntry** block_die);
-
- size_t GetAttributes(
- const DWARFCompileUnit* cu,
- DWARFFormValue::FixedFormSizes fixed_form_sizes,
- DWARFAttributes& attrs,
- uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
-
- dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- DWARFFormValue& formValue,
- dw_offset_t* end_attr_offset_ptr = nullptr,
- bool check_specification_or_abstract_origin = false) const;
-
- const char* GetAttributeValueAsString(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- const char* fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- uint64_t GetAttributeValueAsUnsigned(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- uint64_t GetAttributeValueAsReference(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- int64_t GetAttributeValueAsSigned(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- int64_t fail_value,
+ typedef std::vector<DWARFDebugInfoEntry> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ typedef std::vector<dw_offset_t> offset_collection;
+ typedef offset_collection::iterator offset_collection_iterator;
+ typedef offset_collection::const_iterator offset_collection_const_iterator;
+
+ DWARFDebugInfoEntry()
+ : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
+ m_empty_children(false), m_abbr_idx(0), m_has_children(false),
+ m_tag(0) {}
+
+ void Clear() {
+ m_offset = DW_INVALID_OFFSET;
+ m_parent_idx = 0;
+ m_sibling_idx = 0;
+ m_empty_children = false;
+ m_abbr_idx = 0;
+ m_has_children = false;
+ m_tag = 0;
+ }
+
+ bool Contains(const DWARFDebugInfoEntry *die) const;
+
+ void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const;
+
+ void BuildFunctionAddressRangeTable(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugAranges *debug_aranges) const;
+
+ bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data,
+ const DWARFCompileUnit *cu,
+ const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
+ lldb::offset_t *offset_ptr);
+
+ bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ lldb::offset_t *offset_ptr);
+
+ bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ DWARFDebugInfoEntry **function_die,
+ DWARFDebugInfoEntry **block_die);
+
+ size_t GetAttributes(const DWARFCompileUnit *cu,
+ DWARFFormValue::FixedFormSizes fixed_form_sizes,
+ DWARFAttributes &attrs,
+ uint32_t curr_depth = 0)
+ const; // "curr_depth" for internal use only, don't set this yourself!!!
+
+ dw_offset_t
+ GetAttributeValue(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, DWARFFormValue &formValue,
+ dw_offset_t *end_attr_offset_ptr = nullptr,
bool check_specification_or_abstract_origin = false) const;
- uint64_t GetAttributeValueAsAddress(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_attr_t attr,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
+ const char *GetAttributeValueAsString(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, const char *fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ uint64_t GetAttributeValueAsUnsigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ uint64_t GetAttributeValueAsReference(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ int64_t GetAttributeValueAsSigned(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, int64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ uint64_t GetAttributeValueAsAddress(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_attr_t attr, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ dw_addr_t
+ GetAttributeHighPC(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ dw_addr_t lo_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ bool GetAttributeAddressRange(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
+ dw_addr_t &hi_pc, uint64_t fail_value,
+ bool check_specification_or_abstract_origin = false) const;
+
+ size_t GetAttributeAddressRanges(
+ SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ DWARFRangeList &ranges, bool check_hi_lo_pc,
+ bool check_specification_or_abstract_origin = false) const;
+
+ const char *GetName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const;
+
+ const char *GetMangledName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ bool substitute_name_allowed = true) const;
+
+ const char *GetPubname(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu) const;
+
+ static bool GetName(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset, lldb_private::Stream &s);
+
+ static bool AppendTypeName(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ const dw_offset_t die_offset,
+ lldb_private::Stream &s);
+
+ const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ std::string &storage) const;
+
+ const char *GetQualifiedName(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes,
+ std::string &storage) const;
- dw_addr_t GetAttributeHighPC(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t lo_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
+ static bool OffsetLessThan(const DWARFDebugInfoEntry &a,
+ const DWARFDebugInfoEntry &b);
- bool GetAttributeAddressRange(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- dw_addr_t& lo_pc,
- dw_addr_t& hi_pc,
- uint64_t fail_value,
- bool check_specification_or_abstract_origin = false) const;
-
- size_t GetAttributeAddressRanges (
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- DWARFRangeList &ranges,
- bool check_hi_lo_pc,
- bool check_specification_or_abstract_origin = false) const;
+ void Dump(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ lldb_private::Stream &s, uint32_t recurse_depth) const;
- const char* GetName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu) const;
-
- const char* GetMangledName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- bool substitute_name_allowed = true) const;
-
- const char* GetPubname(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu) const;
-
- static bool GetName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- lldb_private::Stream &s);
-
- static bool AppendTypeName(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const dw_offset_t die_offset,
- lldb_private::Stream &s);
-
- const char * GetQualifiedName (
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- std::string &storage) const;
-
- const char * GetQualifiedName (
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes,
- std::string &storage) const;
-
- static bool OffsetLessThan (
- const DWARFDebugInfoEntry& a,
- const DWARFDebugInfoEntry& b);
-
- void Dump(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- lldb_private::Stream &s,
+ void DumpAncestry(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const DWARFDebugInfoEntry *oldest, lldb_private::Stream &s,
uint32_t recurse_depth) const;
- void DumpAncestry(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const DWARFDebugInfoEntry* oldest,
- lldb_private::Stream &s,
- uint32_t recurse_depth) const;
-
- static void DumpAttribute(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const lldb_private::DWARFDataExtractor& debug_info_data,
- lldb::offset_t *offset_ptr,
- lldb_private::Stream &s,
- dw_attr_t attr,
- dw_form_t form);
- // This one dumps the comp unit name, objfile name and die offset for this die so the stream S.
- void DumpLocation(
- SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
+ static void
+ DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const lldb_private::DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr, lldb_private::Stream &s,
+ dw_attr_t attr, dw_form_t form);
+ // This one dumps the comp unit name, objfile name and die offset for this die
+ // so the stream S.
+ void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
lldb_private::Stream &s) const;
-
- bool GetDIENamesAndRanges(
- SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit* cu,
- const char * &name,
- const char * &mangled,
- DWARFRangeList& rangeList,
- int& decl_file,
- int& decl_line,
- int& decl_column,
- int& call_file,
- int& call_line,
- int& call_column,
- lldb_private::DWARFExpression *frame_base = NULL) const;
-
- const DWARFAbbreviationDeclaration*
- GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
- const DWARFCompileUnit *cu,
- lldb::offset_t &offset) const;
-
- dw_tag_t
- Tag () const
- {
- return m_tag;
- }
-
- bool
- IsNULL() const
- {
- return m_abbr_idx == 0;
- }
-
- dw_offset_t
- GetOffset () const
- {
- return m_offset;
- }
-
- void
- SetOffset (dw_offset_t offset)
- {
- m_offset = offset;
- }
-
- bool
- HasChildren () const
- {
- return m_has_children;
- }
-
- void
- SetHasChildren (bool b)
- {
- m_has_children = b;
- }
-
- // We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- DWARFDebugInfoEntry* GetParent() { return m_parent_idx > 0 ? this - m_parent_idx : NULL; }
- const DWARFDebugInfoEntry* GetParent() const { return m_parent_idx > 0 ? this - m_parent_idx : NULL; }
- // We know we are kept in a vector of contiguous entries, so we know
- // our sibling will be some index after "this".
- DWARFDebugInfoEntry* GetSibling() { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; }
- const DWARFDebugInfoEntry* GetSibling() const { return m_sibling_idx > 0 ? this + m_sibling_idx : NULL; }
- // We know we are kept in a vector of contiguous entries, so we know
- // we don't need to store our child pointer, if we have a child it will
- // be the next entry in the list...
- DWARFDebugInfoEntry* GetFirstChild() { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; }
- const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; }
-
-
- void GetDeclContextDIEs (DWARFCompileUnit* cu,
- DWARFDIECollection &decl_context_dies) const;
-
- void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- DWARFDeclContext &dwarf_decl_ctx) const;
-
-
- bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFDeclContext &dwarf_decl_ctx) const;
-
- DWARFDIE GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu) const;
- DWARFDIE GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
- DWARFCompileUnit* cu,
- const DWARFAttributes& attributes) const;
-
- void
- SetParent (DWARFDebugInfoEntry* parent)
- {
- if (parent)
- {
- // We know we are kept in a vector of contiguous entries, so we know
- // our parent will be some index behind "this".
- m_parent_idx = this - parent;
- }
- else
- m_parent_idx = 0;
- }
- void
- SetSibling (DWARFDebugInfoEntry* sibling)
- {
- if (sibling)
- {
- // We know we are kept in a vector of contiguous entries, so we know
- // our sibling will be some index after "this".
- m_sibling_idx = sibling - this;
- sibling->SetParent(GetParent());
- }
- else
- m_sibling_idx = 0;
- }
-
- void
- SetSiblingIndex (uint32_t idx)
- {
- m_sibling_idx = idx;
- }
-
- void
- SetParentIndex (uint32_t idx)
- {
- m_parent_idx = idx;
- }
-
- bool
- GetEmptyChildren () const
- {
- return m_empty_children;
- }
-
- void
- SetEmptyChildren (bool b)
- {
- m_empty_children = b;
- }
-
- static void
- DumpDIECollection (lldb_private::Stream &strm,
- DWARFDebugInfoEntry::collection &die_collection);
-protected:
+ bool
+ GetDIENamesAndRanges(SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
+ const char *&name, const char *&mangled,
+ DWARFRangeList &rangeList, int &decl_file,
+ int &decl_line, int &decl_column, int &call_file,
+ int &call_line, int &call_column,
+ lldb_private::DWARFExpression *frame_base = NULL) const;
+
+ const DWARFAbbreviationDeclaration *
+ GetAbbreviationDeclarationPtr(SymbolFileDWARF *dwarf2Data,
+ const DWARFCompileUnit *cu,
+ lldb::offset_t &offset) const;
+
+ dw_tag_t Tag() const { return m_tag; }
+
+ bool IsNULL() const { return m_abbr_idx == 0; }
+
+ dw_offset_t GetOffset() const { return m_offset; }
+
+ void SetOffset(dw_offset_t offset) { m_offset = offset; }
+
+ bool HasChildren() const { return m_has_children; }
+
+ void SetHasChildren(bool b) { m_has_children = b; }
+
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our parent will be some index behind "this".
+ DWARFDebugInfoEntry *GetParent() {
+ return m_parent_idx > 0 ? this - m_parent_idx : NULL;
+ }
+ const DWARFDebugInfoEntry *GetParent() const {
+ return m_parent_idx > 0 ? this - m_parent_idx : NULL;
+ }
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our sibling will be some index after "this".
+ DWARFDebugInfoEntry *GetSibling() {
+ return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;
+ }
+ const DWARFDebugInfoEntry *GetSibling() const {
+ return m_sibling_idx > 0 ? this + m_sibling_idx : NULL;
+ }
+ // We know we are kept in a vector of contiguous entries, so we know
+ // we don't need to store our child pointer, if we have a child it will
+ // be the next entry in the list...
+ DWARFDebugInfoEntry *GetFirstChild() {
+ return (HasChildren() && !m_empty_children) ? this + 1 : NULL;
+ }
+ const DWARFDebugInfoEntry *GetFirstChild() const {
+ return (HasChildren() && !m_empty_children) ? this + 1 : NULL;
+ }
+
+ void GetDeclContextDIEs(DWARFCompileUnit *cu,
+ DWARFDIECollection &decl_context_dies) const;
+
+ void GetDWARFDeclContext(SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
+ DWARFDeclContext &dwarf_decl_ctx) const;
+
+ bool MatchesDWARFDeclContext(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ const DWARFDeclContext &dwarf_decl_ctx) const;
+
+ DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu) const;
+ DWARFDIE GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
+ DWARFCompileUnit *cu,
+ const DWARFAttributes &attributes) const;
+
+ void SetParent(DWARFDebugInfoEntry *parent) {
+ if (parent) {
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our parent will be some index behind "this".
+ m_parent_idx = this - parent;
+ } else
+ m_parent_idx = 0;
+ }
+ void SetSibling(DWARFDebugInfoEntry *sibling) {
+ if (sibling) {
+ // We know we are kept in a vector of contiguous entries, so we know
+ // our sibling will be some index after "this".
+ m_sibling_idx = sibling - this;
+ sibling->SetParent(GetParent());
+ } else
+ m_sibling_idx = 0;
+ }
+
+ void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
+
+ void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
+
+ bool GetEmptyChildren() const { return m_empty_children; }
+
+ void SetEmptyChildren(bool b) { m_empty_children = b; }
+
+ static void
+ DumpDIECollection(lldb_private::Stream &strm,
+ DWARFDebugInfoEntry::collection &die_collection);
- dw_offset_t m_offset; // Offset within the .debug_info of the start of this entry
- uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. If zero this die has no parent
- uint32_t m_sibling_idx:31, // How many to add to "this" to get the sibling.
- m_empty_children:1; // If a DIE says it had children, yet it just contained a NULL tag, this will be set.
- uint32_t m_abbr_idx:DIE_ABBR_IDX_BITSIZE,
- m_has_children:1, // Set to 1 if this DIE has children
- m_tag:16; // A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table
+protected:
+ dw_offset_t
+ m_offset; // Offset within the .debug_info of the start of this entry
+ uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
+ // If zero this die has no parent
+ uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
+ m_empty_children : 1; // If a DIE says it had children, yet it just
+ // contained a NULL tag, this will be set.
+ uint32_t m_abbr_idx : DIE_ABBR_IDX_BITSIZE,
+ m_has_children : 1, // Set to 1 if this DIE has children
+ m_tag : 16; // A copy of the DW_TAG value so we don't
+ // have to go through the compile unit
+ // abbrev table
};
-#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
+#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp Tue Sep 6 15:57:50 2016
@@ -18,8 +18,8 @@
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
-#include "SymbolFileDWARF.h"
#include "LogChannelDWARF.h"
+#include "SymbolFileDWARF.h"
using namespace lldb;
using namespace lldb_private;
@@ -31,359 +31,329 @@ using namespace std;
// Parse all information in the debug_line_data into an internal
// representation.
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Parse(const DWARFDataExtractor& debug_line_data)
-{
- m_lineTableMap.clear();
- lldb::offset_t offset = 0;
- LineTable::shared_ptr line_table_sp(new LineTable);
- while (debug_line_data.ValidOffset(offset))
- {
- const lldb::offset_t debug_line_offset = offset;
-
- if (line_table_sp.get() == NULL)
- break;
-
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get()))
- {
- // Make sure we don't don't loop infinitely
- if (offset <= debug_line_offset)
- break;
- //DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n", debug_line_offset);
- m_lineTableMap[debug_line_offset] = line_table_sp;
- line_table_sp.reset(new LineTable);
- }
- else
- ++offset; // Try next byte in line table
- }
+void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
+ m_lineTableMap.clear();
+ lldb::offset_t offset = 0;
+ LineTable::shared_ptr line_table_sp(new LineTable);
+ while (debug_line_data.ValidOffset(offset)) {
+ const lldb::offset_t debug_line_offset = offset;
+
+ if (line_table_sp.get() == NULL)
+ break;
+
+ if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) {
+ // Make sure we don't don't loop infinitely
+ if (offset <= debug_line_offset)
+ break;
+ // DEBUG_PRINTF("m_lineTableMap[0x%8.8x] = line_table_sp\n",
+ // debug_line_offset);
+ m_lineTableMap[debug_line_offset] = line_table_sp;
+ line_table_sp.reset(new LineTable);
+ } else
+ ++offset; // Try next byte in line table
+ }
+}
+
+void DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor &debug_line_data) {
+ if (m_lineTableMap.empty())
+ Parse(debug_line_data);
}
-void
-DWARFDebugLine::ParseIfNeeded(const DWARFDataExtractor& debug_line_data)
-{
- if (m_lineTableMap.empty())
- Parse(debug_line_data);
-}
-
-
//----------------------------------------------------------------------
// DWARFDebugLine::GetLineTable
//----------------------------------------------------------------------
DWARFDebugLine::LineTable::shared_ptr
-DWARFDebugLine::GetLineTable(const dw_offset_t offset) const
-{
- DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
- LineTableConstIter pos = m_lineTableMap.find(offset);
- if (pos != m_lineTableMap.end())
- line_table_shared_ptr = pos->second;
- return line_table_shared_ptr;
+DWARFDebugLine::GetLineTable(const dw_offset_t offset) const {
+ DWARFDebugLine::LineTable::shared_ptr line_table_shared_ptr;
+ LineTableConstIter pos = m_lineTableMap.find(offset);
+ if (pos != m_lineTableMap.end())
+ line_table_shared_ptr = pos->second;
+ return line_table_shared_ptr;
}
-
//----------------------------------------------------------------------
// DumpStateToFile
//----------------------------------------------------------------------
-static void
-DumpStateToFile (dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
-{
- Log *log = (Log *)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable)
- {
- // If the row is zero we are being called with the prologue only
- state.prologue->Dump (log);
- log->PutCString ("Address Line Column File");
- log->PutCString ("------------------ ------ ------ ------");
- }
- else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
- {
- // Done parsing line table
- }
- else
- {
- log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
- }
+static void DumpStateToFile(dw_offset_t offset,
+ const DWARFDebugLine::State &state,
+ void *userData) {
+ Log *log = (Log *)userData;
+ if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
+ // If the row is zero we are being called with the prologue only
+ state.prologue->Dump(log);
+ log->PutCString("Address Line Column File");
+ log->PutCString("------------------ ------ ------ ------");
+ } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
+ // Done parsing line table
+ } else {
+ log->Printf("0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line,
+ state.column, state.file, state.end_sequence ? " END" : "");
+ }
}
//----------------------------------------------------------------------
// DWARFDebugLine::DumpLineTableRows
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset)
-{
- const DWARFDataExtractor& debug_line_data = dwarf2Data->get_debug_line_data();
-
- if (debug_line_offset == DW_INVALID_OFFSET)
- {
- // Dump line table to a single file only
- debug_line_offset = 0;
- while (debug_line_data.ValidOffset(debug_line_offset))
- debug_line_offset = DumpStatementTable (log, debug_line_data, debug_line_offset);
- }
- else
- {
- // Dump line table to a single file only
- DumpStatementTable (log, debug_line_data, debug_line_offset);
- }
- return false;
+bool DWARFDebugLine::DumpLineTableRows(Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t debug_line_offset) {
+ const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
+
+ if (debug_line_offset == DW_INVALID_OFFSET) {
+ // Dump line table to a single file only
+ debug_line_offset = 0;
+ while (debug_line_data.ValidOffset(debug_line_offset))
+ debug_line_offset =
+ DumpStatementTable(log, debug_line_data, debug_line_offset);
+ } else {
+ // Dump line table to a single file only
+ DumpStatementTable(log, debug_line_data, debug_line_offset);
+ }
+ return false;
}
//----------------------------------------------------------------------
// DWARFDebugLine::DumpStatementTable
//----------------------------------------------------------------------
dw_offset_t
-DWARFDebugLine::DumpStatementTable(Log *log, const DWARFDataExtractor& debug_line_data, const dw_offset_t debug_line_offset)
-{
- if (debug_line_data.ValidOffset(debug_line_offset))
- {
- lldb::offset_t offset = debug_line_offset;
- log->Printf( "----------------------------------------------------------------------\n"
- "debug_line[0x%8.8x]\n"
- "----------------------------------------------------------------------\n", debug_line_offset);
+DWARFDebugLine::DumpStatementTable(Log *log,
+ const DWARFDataExtractor &debug_line_data,
+ const dw_offset_t debug_line_offset) {
+ if (debug_line_data.ValidOffset(debug_line_offset)) {
+ lldb::offset_t offset = debug_line_offset;
+ log->Printf("--------------------------------------------------------------"
+ "--------\n"
+ "debug_line[0x%8.8x]\n"
+ "--------------------------------------------------------------"
+ "--------\n",
+ debug_line_offset);
- if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
- return offset;
- else
- return debug_line_offset + 1; // Skip to next byte in .debug_line section
- }
+ if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
+ return offset;
+ else
+ return debug_line_offset + 1; // Skip to next byte in .debug_line section
+ }
- return DW_INVALID_OFFSET;
+ return DW_INVALID_OFFSET;
}
-
//----------------------------------------------------------------------
// DumpOpcodes
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t debug_line_offset, uint32_t dump_flags)
-{
- const DWARFDataExtractor& debug_line_data = dwarf2Data->get_debug_line_data();
-
- if (debug_line_data.GetByteSize() == 0)
- {
- log->Printf( "< EMPTY >\n");
- return false;
- }
+bool DWARFDebugLine::DumpOpcodes(Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t debug_line_offset,
+ uint32_t dump_flags) {
+ const DWARFDataExtractor &debug_line_data = dwarf2Data->get_debug_line_data();
- if (debug_line_offset == DW_INVALID_OFFSET)
- {
- // Dump line table to a single file only
- debug_line_offset = 0;
- while (debug_line_data.ValidOffset(debug_line_offset))
- debug_line_offset = DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags);
- }
- else
- {
- // Dump line table to a single file only
- DumpStatementOpcodes (log, debug_line_data, debug_line_offset, dump_flags);
- }
+ if (debug_line_data.GetByteSize() == 0) {
+ log->Printf("< EMPTY >\n");
return false;
+ }
+
+ if (debug_line_offset == DW_INVALID_OFFSET) {
+ // Dump line table to a single file only
+ debug_line_offset = 0;
+ while (debug_line_data.ValidOffset(debug_line_offset))
+ debug_line_offset = DumpStatementOpcodes(log, debug_line_data,
+ debug_line_offset, dump_flags);
+ } else {
+ // Dump line table to a single file only
+ DumpStatementOpcodes(log, debug_line_data, debug_line_offset, dump_flags);
+ }
+ return false;
}
//----------------------------------------------------------------------
// DumpStatementOpcodes
//----------------------------------------------------------------------
-dw_offset_t
-DWARFDebugLine::DumpStatementOpcodes(Log *log, const DWARFDataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags)
-{
- lldb::offset_t offset = debug_line_offset;
- if (debug_line_data.ValidOffset(offset))
- {
- Prologue prologue;
+dw_offset_t DWARFDebugLine::DumpStatementOpcodes(
+ Log *log, const DWARFDataExtractor &debug_line_data,
+ const dw_offset_t debug_line_offset, uint32_t flags) {
+ lldb::offset_t offset = debug_line_offset;
+ if (debug_line_data.ValidOffset(offset)) {
+ Prologue prologue;
- if (ParsePrologue(debug_line_data, &offset, &prologue))
- {
- log->PutCString ("----------------------------------------------------------------------");
- log->Printf ("debug_line[0x%8.8x]", debug_line_offset);
- log->PutCString ("----------------------------------------------------------------------\n");
- prologue.Dump (log);
- }
- else
- {
- offset = debug_line_offset;
- log->Printf( "0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
- return offset;
+ if (ParsePrologue(debug_line_data, &offset, &prologue)) {
+ log->PutCString("--------------------------------------------------------"
+ "--------------");
+ log->Printf("debug_line[0x%8.8x]", debug_line_offset);
+ log->PutCString("--------------------------------------------------------"
+ "--------------\n");
+ prologue.Dump(log);
+ } else {
+ offset = debug_line_offset;
+ log->Printf("0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset,
+ debug_line_data.GetU8(&offset));
+ return offset;
+ }
+
+ Row row(prologue.default_is_stmt);
+ const dw_offset_t end_offset = debug_line_offset + prologue.total_length +
+ sizeof(prologue.total_length);
+
+ assert(debug_line_data.ValidOffset(end_offset - 1));
+
+ while (offset < end_offset) {
+ const uint32_t op_offset = offset;
+ uint8_t opcode = debug_line_data.GetU8(&offset);
+ switch (opcode) {
+ case 0: // Extended Opcodes always start with a zero opcode followed by
+ { // a uleb128 length so you can skip ones you don't know about
+
+ dw_offset_t ext_offset = offset;
+ dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
+ dw_offset_t arg_size = len - (offset - ext_offset);
+ uint8_t sub_opcode = debug_line_data.GetU8(&offset);
+ // if (verbose)
+ // log->Printf( "Extended: <%u> %2.2x ", len,
+ // sub_opcode);
+
+ switch (sub_opcode) {
+ case DW_LNE_end_sequence:
+ log->Printf("0x%8.8x: DW_LNE_end_sequence", op_offset);
+ row.Dump(log);
+ row.Reset(prologue.default_is_stmt);
+ break;
+
+ case DW_LNE_set_address: {
+ row.address = debug_line_data.GetMaxU64(&offset, arg_size);
+ log->Printf("0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset,
+ row.address);
+ } break;
+
+ case DW_LNE_define_file: {
+ FileNameEntry fileEntry;
+ fileEntry.name = debug_line_data.GetCStr(&offset);
+ fileEntry.dir_idx = debug_line_data.GetULEB128(&offset);
+ fileEntry.mod_time = debug_line_data.GetULEB128(&offset);
+ fileEntry.length = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNE_define_file('%s', dir=%i, "
+ "mod_time=0x%8.8x, length=%i )",
+ op_offset, fileEntry.name, fileEntry.dir_idx,
+ fileEntry.mod_time, fileEntry.length);
+ prologue.file_names.push_back(fileEntry);
+ } break;
+
+ case DW_LNE_set_discriminator: {
+ uint64_t discriminator = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")",
+ op_offset, discriminator);
+ } break;
+ default:
+ log->Printf("0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode",
+ op_offset, opcode);
+ // Length doesn't include the zero opcode byte or the length itself,
+ // but
+ // it does include the sub_opcode, so we have to adjust for that below
+ offset += arg_size;
+ break;
}
+ } break;
- Row row(prologue.default_is_stmt);
- const dw_offset_t end_offset = debug_line_offset + prologue.total_length + sizeof(prologue.total_length);
-
- assert(debug_line_data.ValidOffset(end_offset-1));
-
- while (offset < end_offset)
- {
- const uint32_t op_offset = offset;
- uint8_t opcode = debug_line_data.GetU8(&offset);
- switch (opcode)
- {
- case 0: // Extended Opcodes always start with a zero opcode followed by
- { // a uleb128 length so you can skip ones you don't know about
-
- dw_offset_t ext_offset = offset;
- dw_uleb128_t len = debug_line_data.GetULEB128(&offset);
- dw_offset_t arg_size = len - (offset - ext_offset);
- uint8_t sub_opcode = debug_line_data.GetU8(&offset);
-// if (verbose)
-// log->Printf( "Extended: <%u> %2.2x ", len, sub_opcode);
-
- switch (sub_opcode)
- {
- case DW_LNE_end_sequence :
- log->Printf( "0x%8.8x: DW_LNE_end_sequence", op_offset);
- row.Dump(log);
- row.Reset(prologue.default_is_stmt);
- break;
-
- case DW_LNE_set_address :
- {
- row.address = debug_line_data.GetMaxU64(&offset, arg_size);
- log->Printf( "0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, row.address);
- }
- break;
-
- case DW_LNE_define_file:
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(&offset);
- fileEntry.dir_idx = debug_line_data.GetULEB128(&offset);
- fileEntry.mod_time = debug_line_data.GetULEB128(&offset);
- fileEntry.length = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNE_define_file('%s', dir=%i, mod_time=0x%8.8x, length=%i )",
- op_offset,
- fileEntry.name,
- fileEntry.dir_idx,
- fileEntry.mod_time,
- fileEntry.length);
- prologue.file_names.push_back(fileEntry);
- }
- break;
-
- case DW_LNE_set_discriminator:
- {
- uint64_t discriminator = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNE_set_discriminator (0x%" PRIx64 ")", op_offset, discriminator);
- }
- break;
- default:
- log->Printf( "0x%8.8x: DW_LNE_??? (%2.2x) - Skipping unknown upcode", op_offset, opcode);
- // Length doesn't include the zero opcode byte or the length itself, but
- // it does include the sub_opcode, so we have to adjust for that below
- offset += arg_size;
- break;
- }
- }
- break;
-
- // Standard Opcodes
- case DW_LNS_copy:
- log->Printf( "0x%8.8x: DW_LNS_copy", op_offset);
- row.Dump (log);
- break;
-
- case DW_LNS_advance_pc:
- {
- dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
- dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
- log->Printf( "0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset, addr_offset);
- row.address += addr_offset;
- }
- break;
-
- case DW_LNS_advance_line:
- {
- dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_advance_line (%i)", op_offset, line_offset);
- row.line += line_offset;
- }
- break;
-
- case DW_LNS_set_file:
- row.file = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
- break;
-
- case DW_LNS_set_column:
- row.column = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
- break;
-
- case DW_LNS_negate_stmt:
- row.is_stmt = !row.is_stmt;
- log->Printf( "0x%8.8x: DW_LNS_negate_stmt", op_offset);
- break;
-
- case DW_LNS_set_basic_block:
- row.basic_block = true;
- log->Printf( "0x%8.8x: DW_LNS_set_basic_block", op_offset);
- break;
-
- case DW_LNS_const_add_pc:
- {
- uint8_t adjust_opcode = 255 - prologue.opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", op_offset, addr_offset);
- row.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- {
- uint16_t pc_offset = debug_line_data.GetU16(&offset);
- log->Printf( "0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset, pc_offset);
- row.address += pc_offset;
- }
- break;
-
- case DW_LNS_set_prologue_end:
- row.prologue_end = true;
- log->Printf( "0x%8.8x: DW_LNS_set_prologue_end", op_offset);
- break;
-
- case DW_LNS_set_epilogue_begin:
- row.epilogue_begin = true;
- log->Printf( "0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
- break;
-
- case DW_LNS_set_isa:
- row.isa = debug_line_data.GetULEB128(&offset);
- log->Printf( "0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
- break;
-
- // Special Opcodes
- default:
- if (opcode < prologue.opcode_base)
- {
- // We have an opcode that this parser doesn't know about, skip
- // the number of ULEB128 numbers that is says to skip in the
- // prologue's standard_opcode_lengths array
- uint8_t n = prologue.standard_opcode_lengths[opcode-1];
- log->Printf( "0x%8.8x: Special : Unknown skipping %u ULEB128 values.", op_offset, n);
- while (n > 0)
- {
- debug_line_data.GetULEB128(&offset);
- --n;
- }
- }
- else
- {
- uint8_t adjust_opcode = opcode - prologue.opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range);
- log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
- row.address += addr_offset;
- row.line += line_offset;
- row.Dump (log);
- }
- break;
- }
+ // Standard Opcodes
+ case DW_LNS_copy:
+ log->Printf("0x%8.8x: DW_LNS_copy", op_offset);
+ row.Dump(log);
+ break;
+
+ case DW_LNS_advance_pc: {
+ dw_uleb128_t addr_offset_n = debug_line_data.GetULEB128(&offset);
+ dw_uleb128_t addr_offset = addr_offset_n * prologue.min_inst_length;
+ log->Printf("0x%8.8x: DW_LNS_advance_pc (0x%x)", op_offset,
+ addr_offset);
+ row.address += addr_offset;
+ } break;
+
+ case DW_LNS_advance_line: {
+ dw_sleb128_t line_offset = debug_line_data.GetSLEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_advance_line (%i)", op_offset,
+ line_offset);
+ row.line += line_offset;
+ } break;
+
+ case DW_LNS_set_file:
+ row.file = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_set_file (%u)", op_offset, row.file);
+ break;
+
+ case DW_LNS_set_column:
+ row.column = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_set_column (%u)", op_offset, row.column);
+ break;
+
+ case DW_LNS_negate_stmt:
+ row.is_stmt = !row.is_stmt;
+ log->Printf("0x%8.8x: DW_LNS_negate_stmt", op_offset);
+ break;
+
+ case DW_LNS_set_basic_block:
+ row.basic_block = true;
+ log->Printf("0x%8.8x: DW_LNS_set_basic_block", op_offset);
+ break;
+
+ case DW_LNS_const_add_pc: {
+ uint8_t adjust_opcode = 255 - prologue.opcode_base;
+ dw_addr_t addr_offset =
+ (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
+ log->Printf("0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")",
+ op_offset, addr_offset);
+ row.address += addr_offset;
+ } break;
+
+ case DW_LNS_fixed_advance_pc: {
+ uint16_t pc_offset = debug_line_data.GetU16(&offset);
+ log->Printf("0x%8.8x: DW_LNS_fixed_advance_pc (0x%4.4x)", op_offset,
+ pc_offset);
+ row.address += pc_offset;
+ } break;
+
+ case DW_LNS_set_prologue_end:
+ row.prologue_end = true;
+ log->Printf("0x%8.8x: DW_LNS_set_prologue_end", op_offset);
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ row.epilogue_begin = true;
+ log->Printf("0x%8.8x: DW_LNS_set_epilogue_begin", op_offset);
+ break;
+
+ case DW_LNS_set_isa:
+ row.isa = debug_line_data.GetULEB128(&offset);
+ log->Printf("0x%8.8x: DW_LNS_set_isa (%u)", op_offset, row.isa);
+ break;
+
+ // Special Opcodes
+ default:
+ if (opcode < prologue.opcode_base) {
+ // We have an opcode that this parser doesn't know about, skip
+ // the number of ULEB128 numbers that is says to skip in the
+ // prologue's standard_opcode_lengths array
+ uint8_t n = prologue.standard_opcode_lengths[opcode - 1];
+ log->Printf("0x%8.8x: Special : Unknown skipping %u ULEB128 values.",
+ op_offset, n);
+ while (n > 0) {
+ debug_line_data.GetULEB128(&offset);
+ --n;
+ }
+ } else {
+ uint8_t adjust_opcode = opcode - prologue.opcode_base;
+ dw_addr_t addr_offset =
+ (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
+ int32_t line_offset =
+ prologue.line_base + (adjust_opcode % prologue.line_range);
+ log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n",
+ op_offset, (uint64_t)addr_offset, line_offset);
+ row.address += addr_offset;
+ row.line += line_offset;
+ row.Dump(log);
}
- return end_offset;
+ break;
+ }
}
- return DW_INVALID_OFFSET;
+ return end_offset;
+ }
+ return DW_INVALID_OFFSET;
}
-
-
-
//----------------------------------------------------------------------
// Parse
//
@@ -391,120 +361,112 @@ DWARFDebugLine::DumpStatementOpcodes(Log
// new prologue is parsed and every time a new row is to be added to
// the line table.
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Parse(const DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData)
-{
- lldb::offset_t offset = 0;
- if (debug_line_data.ValidOffset(offset))
- {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
- ++offset; // Skip to next byte in .debug_line section
- }
+void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
+ DWARFDebugLine::State::Callback callback,
+ void *userData) {
+ lldb::offset_t offset = 0;
+ if (debug_line_data.ValidOffset(offset)) {
+ if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
+ ++offset; // Skip to next byte in .debug_line section
+ }
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::ParsePrologue(const DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue)
-{
- const lldb::offset_t prologue_offset = *offset_ptr;
-
- //DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
-
- prologue->Clear();
- uint32_t i;
- const char * s;
- prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
- prologue->version = debug_line_data.GetU16(offset_ptr);
- if (prologue->version < 2 || prologue->version > 4)
- return false;
-
- prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
- const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
- prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
- if (prologue->version >= 4)
- prologue->maximum_operations_per_instruction = debug_line_data.GetU8(offset_ptr);
+bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr,
+ Prologue *prologue) {
+ const lldb::offset_t prologue_offset = *offset_ptr;
+
+ // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
+
+ prologue->Clear();
+ uint32_t i;
+ const char *s;
+ prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
+ prologue->version = debug_line_data.GetU16(offset_ptr);
+ if (prologue->version < 2 || prologue->version > 4)
+ return false;
+
+ prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
+ const lldb::offset_t end_prologue_offset =
+ prologue->prologue_length + *offset_ptr;
+ prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
+ if (prologue->version >= 4)
+ prologue->maximum_operations_per_instruction =
+ debug_line_data.GetU8(offset_ptr);
+ else
+ prologue->maximum_operations_per_instruction = 1;
+ prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
+ prologue->line_base = debug_line_data.GetU8(offset_ptr);
+ prologue->line_range = debug_line_data.GetU8(offset_ptr);
+ prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
+
+ prologue->standard_opcode_lengths.reserve(prologue->opcode_base - 1);
+
+ for (i = 1; i < prologue->opcode_base; ++i) {
+ uint8_t op_len = debug_line_data.GetU8(offset_ptr);
+ prologue->standard_opcode_lengths.push_back(op_len);
+ }
+
+ while (*offset_ptr < end_prologue_offset) {
+ s = debug_line_data.GetCStr(offset_ptr);
+ if (s && s[0])
+ prologue->include_directories.push_back(s);
else
- prologue->maximum_operations_per_instruction = 1;
- prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
- prologue->line_base = debug_line_data.GetU8(offset_ptr);
- prologue->line_range = debug_line_data.GetU8(offset_ptr);
- prologue->opcode_base = debug_line_data.GetU8(offset_ptr);
-
- prologue->standard_opcode_lengths.reserve(prologue->opcode_base-1);
-
- for (i=1; i<prologue->opcode_base; ++i)
- {
- uint8_t op_len = debug_line_data.GetU8(offset_ptr);
- prologue->standard_opcode_lengths.push_back(op_len);
- }
+ break;
+ }
- while (*offset_ptr < end_prologue_offset)
- {
- s = debug_line_data.GetCStr(offset_ptr);
- if (s && s[0])
- prologue->include_directories.push_back(s);
- else
- break;
- }
+ while (*offset_ptr < end_prologue_offset) {
+ const char *name = debug_line_data.GetCStr(offset_ptr);
+ if (name && name[0]) {
+ FileNameEntry fileEntry;
+ fileEntry.name = name;
+ fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
+ prologue->file_names.push_back(fileEntry);
+ } else
+ break;
+ }
+
+ // XXX GNU as is broken for 64-Bit DWARF
+ if (*offset_ptr != end_prologue_offset) {
+ Host::SystemLog(Host::eSystemLogWarning,
+ "warning: parsing line table prologue at 0x%8.8" PRIx64
+ " should have ended at 0x%8.8" PRIx64
+ " but it ended at 0x%8.8" PRIx64 "\n",
+ prologue_offset, end_prologue_offset, *offset_ptr);
+ }
+ return end_prologue_offset;
+}
+
+bool DWARFDebugLine::ParseSupportFiles(
+ const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
+ const char *cu_comp_dir, dw_offset_t stmt_list,
+ FileSpecList &support_files) {
+ lldb::offset_t offset = stmt_list;
+
+ Prologue prologue;
+ if (!ParsePrologue(debug_line_data, &offset, &prologue)) {
+ Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
+ "at 0x%8.8x (parsing ended around "
+ "0x%8.8" PRIx64 "\n",
+ stmt_list, offset);
+ return false;
+ }
- while (*offset_ptr < end_prologue_offset)
- {
- const char* name = debug_line_data.GetCStr( offset_ptr );
- if (name && name[0])
- {
- FileNameEntry fileEntry;
- fileEntry.name = name;
- fileEntry.dir_idx = debug_line_data.GetULEB128( offset_ptr );
- fileEntry.mod_time = debug_line_data.GetULEB128( offset_ptr );
- fileEntry.length = debug_line_data.GetULEB128( offset_ptr );
- prologue->file_names.push_back(fileEntry);
- }
- else
- break;
- }
+ FileSpec file_spec;
+ std::string remapped_file;
- // XXX GNU as is broken for 64-Bit DWARF
- if (*offset_ptr != end_prologue_offset)
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8" PRIx64 " should have ended at 0x%8.8" PRIx64 " but it ended at 0x%8.8" PRIx64 "\n",
- prologue_offset,
- end_prologue_offset,
- *offset_ptr);
- }
- return end_prologue_offset;
-}
-
-bool
-DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp,
- const DWARFDataExtractor& debug_line_data,
- const char *cu_comp_dir,
- dw_offset_t stmt_list,
- FileSpecList &support_files)
-{
- lldb::offset_t offset = stmt_list;
-
- Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue))
- {
- Host::SystemLog (Host::eSystemLogError, "error: parsing line table prologue at 0x%8.8x (parsing ended around 0x%8.8" PRIx64 "\n", stmt_list, offset);
- return false;
- }
-
- FileSpec file_spec;
- std::string remapped_file;
-
- for (uint32_t file_idx = 1; prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx)
- {
- if (module_sp->RemapSourceFile(file_spec.GetCString(), remapped_file))
- file_spec.SetFile(remapped_file, false);
- support_files.Append(file_spec);
-
- }
- return true;
+ for (uint32_t file_idx = 1;
+ prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) {
+ if (module_sp->RemapSourceFile(file_spec.GetCString(), remapped_file))
+ file_spec.SetFile(remapped_file, false);
+ support_files.Append(file_spec);
+ }
+ return true;
}
//----------------------------------------------------------------------
@@ -514,304 +476,294 @@ DWARFDebugLine::ParseSupportFiles (const
// callback function once for the prologue (row in state will be zero)
// and each time a row is to be added to the line table.
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::ParseStatementTable
-(
- const DWARFDataExtractor& debug_line_data,
- lldb::offset_t* offset_ptr,
- DWARFDebugLine::State::Callback callback,
- void* userData
-)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
- Prologue::shared_ptr prologue(new Prologue());
-
-
- const dw_offset_t debug_line_offset = *offset_ptr;
-
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
- debug_line_offset);
-
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get()))
- {
- if (log)
- log->Error ("failed to parse DWARF line table prologue");
- // Restore our offset and return false to indicate failure!
- *offset_ptr = debug_line_offset;
- return false;
- }
+bool DWARFDebugLine::ParseStatementTable(
+ const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
+ DWARFDebugLine::State::Callback callback, void *userData) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
+ Prologue::shared_ptr prologue(new Prologue());
+
+ const dw_offset_t debug_line_offset = *offset_ptr;
+
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
+ debug_line_offset);
+ if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) {
if (log)
- prologue->Dump (log);
-
- const dw_offset_t end_offset = debug_line_offset + prologue->total_length + (debug_line_data.GetDWARFSizeofInitialLength());
-
- State state(prologue, log, callback, userData);
+ log->Error("failed to parse DWARF line table prologue");
+ // Restore our offset and return false to indicate failure!
+ *offset_ptr = debug_line_offset;
+ return false;
+ }
- while (*offset_ptr < end_offset)
- {
- //DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
- uint8_t opcode = debug_line_data.GetU8(offset_ptr);
+ if (log)
+ prologue->Dump(log);
- if (opcode == 0)
+ const dw_offset_t end_offset =
+ debug_line_offset + prologue->total_length +
+ (debug_line_data.GetDWARFSizeofInitialLength());
+
+ State state(prologue, log, callback, userData);
+
+ while (*offset_ptr < end_offset) {
+ // DEBUG_PRINTF("0x%8.8x: ", *offset_ptr);
+ uint8_t opcode = debug_line_data.GetU8(offset_ptr);
+
+ if (opcode == 0) {
+ // Extended Opcodes always start with a zero opcode followed by
+ // a uleb128 length so you can skip ones you don't know about
+ lldb::offset_t ext_offset = *offset_ptr;
+ dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
+ dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
+
+ // DEBUG_PRINTF("Extended: <%2u> ", len);
+ uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
+ switch (sub_opcode) {
+ case DW_LNE_end_sequence:
+ // Set the end_sequence register of the state machine to true and
+ // append a row to the matrix using the current values of the
+ // state-machine registers. Then reset the registers to the initial
+ // values specified above. Every statement program sequence must end
+ // with a DW_LNE_end_sequence instruction which creates a row whose
+ // address is that of the byte after the last target machine instruction
+ // of the sequence.
+ state.end_sequence = true;
+ state.AppendRowToMatrix(*offset_ptr);
+ state.Reset();
+ break;
+
+ case DW_LNE_set_address:
+ // Takes a single relocatable address as an operand. The size of the
+ // operand is the size appropriate to hold an address on the target
+ // machine. Set the address register to the value given by the
+ // relocatable address. All of the other statement program opcodes
+ // that affect the address register add a delta to it. This instruction
+ // stores a relocatable value into it instead.
+ if (arg_size == 4)
+ state.address = debug_line_data.GetU32(offset_ptr);
+ else // arg_size == 8
+ state.address = debug_line_data.GetU64(offset_ptr);
+ break;
+
+ case DW_LNE_define_file:
+ // Takes 4 arguments. The first is a null terminated string containing
+ // a source file name. The second is an unsigned LEB128 number
+ // representing
+ // the directory index of the directory in which the file was found. The
+ // third is an unsigned LEB128 number representing the time of last
+ // modification of the file. The fourth is an unsigned LEB128 number
+ // representing the length in bytes of the file. The time and length
+ // fields may contain LEB128(0) if the information is not available.
+ //
+ // The directory index represents an entry in the include_directories
+ // section of the statement program prologue. The index is LEB128(0)
+ // if the file was found in the current directory of the compilation,
+ // LEB128(1) if it was found in the first directory in the
+ // include_directories section, and so on. The directory index is
+ // ignored for file names that represent full path names.
+ //
+ // The files are numbered, starting at 1, in the order in which they
+ // appear; the names in the prologue come before names defined by
+ // the DW_LNE_define_file instruction. These numbers are used in the
+ // file register of the state machine.
{
- // Extended Opcodes always start with a zero opcode followed by
- // a uleb128 length so you can skip ones you don't know about
- lldb::offset_t ext_offset = *offset_ptr;
- dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
- dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
-
- //DEBUG_PRINTF("Extended: <%2u> ", len);
- uint8_t sub_opcode = debug_line_data.GetU8(offset_ptr);
- switch (sub_opcode)
- {
- case DW_LNE_end_sequence:
- // Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the
- // state-machine registers. Then reset the registers to the initial
- // values specified above. Every statement program sequence must end
- // with a DW_LNE_end_sequence instruction which creates a row whose
- // address is that of the byte after the last target machine instruction
- // of the sequence.
- state.end_sequence = true;
- state.AppendRowToMatrix(*offset_ptr);
- state.Reset();
- break;
-
- case DW_LNE_set_address:
- // Takes a single relocatable address as an operand. The size of the
- // operand is the size appropriate to hold an address on the target
- // machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes
- // that affect the address register add a delta to it. This instruction
- // stores a relocatable value into it instead.
- if (arg_size == 4)
- state.address = debug_line_data.GetU32(offset_ptr);
- else // arg_size == 8
- state.address = debug_line_data.GetU64(offset_ptr);
- break;
-
- case DW_LNE_define_file:
- // Takes 4 arguments. The first is a null terminated string containing
- // a source file name. The second is an unsigned LEB128 number representing
- // the directory index of the directory in which the file was found. The
- // third is an unsigned LEB128 number representing the time of last
- // modification of the file. The fourth is an unsigned LEB128 number
- // representing the length in bytes of the file. The time and length
- // fields may contain LEB128(0) if the information is not available.
- //
- // The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0)
- // if the file was found in the current directory of the compilation,
- // LEB128(1) if it was found in the first directory in the
- // include_directories section, and so on. The directory index is
- // ignored for file names that represent full path names.
- //
- // The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by
- // the DW_LNE_define_file instruction. These numbers are used in the
- // file register of the state machine.
- {
- FileNameEntry fileEntry;
- fileEntry.name = debug_line_data.GetCStr(offset_ptr);
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- state.prologue->file_names.push_back(fileEntry);
- }
- break;
-
- default:
- // Length doesn't include the zero opcode byte or the length itself, but
- // it does include the sub_opcode, so we have to adjust for that below
- (*offset_ptr) += arg_size;
- break;
- }
+ FileNameEntry fileEntry;
+ fileEntry.name = debug_line_data.GetCStr(offset_ptr);
+ fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
+ state.prologue->file_names.push_back(fileEntry);
}
- else if (opcode < prologue->opcode_base)
+ break;
+
+ default:
+ // Length doesn't include the zero opcode byte or the length itself, but
+ // it does include the sub_opcode, so we have to adjust for that below
+ (*offset_ptr) += arg_size;
+ break;
+ }
+ } else if (opcode < prologue->opcode_base) {
+ switch (opcode) {
+ // Standard Opcodes
+ case DW_LNS_copy:
+ // Takes no arguments. Append a row to the matrix using the
+ // current values of the state-machine registers. Then set
+ // the basic_block register to false.
+ state.AppendRowToMatrix(*offset_ptr);
+ break;
+
+ case DW_LNS_advance_pc:
+ // Takes a single unsigned LEB128 operand, multiplies it by the
+ // min_inst_length field of the prologue, and adds the
+ // result to the address register of the state machine.
+ state.address +=
+ debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
+ break;
+
+ case DW_LNS_advance_line:
+ // Takes a single signed LEB128 operand and adds that value to
+ // the line register of the state machine.
+ state.line += debug_line_data.GetSLEB128(offset_ptr);
+ break;
+
+ case DW_LNS_set_file:
+ // Takes a single unsigned LEB128 operand and stores it in the file
+ // register of the state machine.
+ state.file = debug_line_data.GetULEB128(offset_ptr);
+ break;
+
+ case DW_LNS_set_column:
+ // Takes a single unsigned LEB128 operand and stores it in the
+ // column register of the state machine.
+ state.column = debug_line_data.GetULEB128(offset_ptr);
+ break;
+
+ case DW_LNS_negate_stmt:
+ // Takes no arguments. Set the is_stmt register of the state
+ // machine to the logical negation of its current value.
+ state.is_stmt = !state.is_stmt;
+ break;
+
+ case DW_LNS_set_basic_block:
+ // Takes no arguments. Set the basic_block register of the
+ // state machine to true
+ state.basic_block = true;
+ break;
+
+ case DW_LNS_const_add_pc:
+ // Takes no arguments. Add to the address register of the state
+ // machine the address increment value corresponding to special
+ // opcode 255. The motivation for DW_LNS_const_add_pc is this:
+ // when the statement program needs to advance the address by a
+ // small amount, it can use a single special opcode, which occupies
+ // a single byte. When it needs to advance the address by up to
+ // twice the range of the last special opcode, it can use
+ // DW_LNS_const_add_pc followed by a special opcode, for a total
+ // of two bytes. Only if it needs to advance the address by more
+ // than twice that range will it need to use both DW_LNS_advance_pc
+ // and a special opcode, requiring three or more bytes.
{
- switch (opcode)
- {
- // Standard Opcodes
- case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the
- // current values of the state-machine registers. Then set
- // the basic_block register to false.
- state.AppendRowToMatrix(*offset_ptr);
- break;
-
- case DW_LNS_advance_pc:
- // Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the
- // result to the address register of the state machine.
- state.address += debug_line_data.GetULEB128(offset_ptr) * prologue->min_inst_length;
- break;
-
- case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to
- // the line register of the state machine.
- state.line += debug_line_data.GetSLEB128(offset_ptr);
- break;
-
- case DW_LNS_set_file:
- // Takes a single unsigned LEB128 operand and stores it in the file
- // register of the state machine.
- state.file = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
- state.column = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state
- // machine to the logical negation of its current value.
- state.is_stmt = !state.is_stmt;
- break;
-
- case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
- state.basic_block = true;
- break;
-
- case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state
- // machine the address increment value corresponding to special
- // opcode 255. The motivation for DW_LNS_const_add_pc is this:
- // when the statement program needs to advance the address by a
- // small amount, it can use a single special opcode, which occupies
- // a single byte. When it needs to advance the address by up to
- // twice the range of the last special opcode, it can use
- // DW_LNS_const_add_pc followed by a special opcode, for a total
- // of two bytes. Only if it needs to advance the address by more
- // than twice that range will it need to use both DW_LNS_advance_pc
- // and a special opcode, requiring three or more bytes.
- {
- uint8_t adjust_opcode = 255 - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- state.address += addr_offset;
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of
- // the state machine the value of the (unencoded) operand. This
- // is the only extended opcode that takes an argument that is not
- // a variable length number. The motivation for DW_LNS_fixed_advance_pc
- // is this: existing assemblers cannot emit DW_LNS_advance_pc or
- // special opcodes because they cannot encode LEB128 numbers or
- // judge when the computation of a special opcode overflows and
- // requires the use of DW_LNS_advance_pc. Such assemblers, however,
- // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
- state.address += debug_line_data.GetU16(offset_ptr);
- break;
-
- case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the
- // state machine to true
- state.prologue_end = true;
- break;
-
- case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
- state.epilogue_begin = true;
- break;
-
- case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
- state.isa = debug_line_data.GetULEB128(offset_ptr);
- break;
-
- default:
- // Handle any unknown standard opcodes here. We know the lengths
- // of such opcodes because they are specified in the prologue
- // as a multiple of LEB128 operands for each opcode.
- {
- uint8_t i;
- assert (static_cast<size_t>(opcode - 1) < prologue->standard_opcode_lengths.size());
- const uint8_t opcode_length = prologue->standard_opcode_lengths[opcode - 1];
- for (i=0; i<opcode_length; ++i)
- debug_line_data.Skip_LEB128(offset_ptr);
- }
- break;
- }
+ uint8_t adjust_opcode = 255 - prologue->opcode_base;
+ dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) *
+ prologue->min_inst_length;
+ state.address += addr_offset;
}
- else
- {
- // Special Opcodes
+ break;
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base
- // field in the header, plus the value of the line_range field,
- // minus 1 (line base + line range - 1). If the desired line
- // increment is greater than the maximum line increment, a standard
- // opcode must be used instead of a special opcode. The "address
- // advance" is calculated by dividing the desired address increment
- // by the minimum_instruction_length field from the header. The
- // special opcode is then calculated using the following formula:
- //
- // opcode = (desired line increment - line_base) + (line_range * address advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode
- // must be used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the
- // opcode itself to give the adjusted opcode. The amount to
- // increment the address register is the result of the adjusted
- // opcode divided by the line_range multiplied by the
- // minimum_instruction_length field from the header. That is:
- //
- // address increment = (adjusted opcode / line_range) * minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus
- // the result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- uint8_t adjust_opcode = opcode - prologue->opcode_base;
- dw_addr_t addr_offset = (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
- int32_t line_offset = prologue->line_base + (adjust_opcode % prologue->line_range);
- state.line += line_offset;
- state.address += addr_offset;
- state.AppendRowToMatrix(*offset_ptr);
+ case DW_LNS_fixed_advance_pc:
+ // Takes a single uhalf operand. Add to the address register of
+ // the state machine the value of the (unencoded) operand. This
+ // is the only extended opcode that takes an argument that is not
+ // a variable length number. The motivation for DW_LNS_fixed_advance_pc
+ // is this: existing assemblers cannot emit DW_LNS_advance_pc or
+ // special opcodes because they cannot encode LEB128 numbers or
+ // judge when the computation of a special opcode overflows and
+ // requires the use of DW_LNS_advance_pc. Such assemblers, however,
+ // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
+ state.address += debug_line_data.GetU16(offset_ptr);
+ break;
+
+ case DW_LNS_set_prologue_end:
+ // Takes no arguments. Set the prologue_end register of the
+ // state machine to true
+ state.prologue_end = true;
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ // Takes no arguments. Set the basic_block register of the
+ // state machine to true
+ state.epilogue_begin = true;
+ break;
+
+ case DW_LNS_set_isa:
+ // Takes a single unsigned LEB128 operand and stores it in the
+ // column register of the state machine.
+ state.isa = debug_line_data.GetULEB128(offset_ptr);
+ break;
+
+ default:
+ // Handle any unknown standard opcodes here. We know the lengths
+ // of such opcodes because they are specified in the prologue
+ // as a multiple of LEB128 operands for each opcode.
+ {
+ uint8_t i;
+ assert(static_cast<size_t>(opcode - 1) <
+ prologue->standard_opcode_lengths.size());
+ const uint8_t opcode_length =
+ prologue->standard_opcode_lengths[opcode - 1];
+ for (i = 0; i < opcode_length; ++i)
+ debug_line_data.Skip_LEB128(offset_ptr);
}
+ break;
+ }
+ } else {
+ // Special Opcodes
+
+ // A special opcode value is chosen based on the amount that needs
+ // to be added to the line and address registers. The maximum line
+ // increment for a special opcode is the value of the line_base
+ // field in the header, plus the value of the line_range field,
+ // minus 1 (line base + line range - 1). If the desired line
+ // increment is greater than the maximum line increment, a standard
+ // opcode must be used instead of a special opcode. The "address
+ // advance" is calculated by dividing the desired address increment
+ // by the minimum_instruction_length field from the header. The
+ // special opcode is then calculated using the following formula:
+ //
+ // opcode = (desired line increment - line_base) + (line_range * address
+ // advance) + opcode_base
+ //
+ // If the resulting opcode is greater than 255, a standard opcode
+ // must be used instead.
+ //
+ // To decode a special opcode, subtract the opcode_base from the
+ // opcode itself to give the adjusted opcode. The amount to
+ // increment the address register is the result of the adjusted
+ // opcode divided by the line_range multiplied by the
+ // minimum_instruction_length field from the header. That is:
+ //
+ // address increment = (adjusted opcode / line_range) *
+ // minimum_instruction_length
+ //
+ // The amount to increment the line register is the line_base plus
+ // the result of the adjusted opcode modulo the line_range. That is:
+ //
+ // line increment = line_base + (adjusted opcode % line_range)
+
+ uint8_t adjust_opcode = opcode - prologue->opcode_base;
+ dw_addr_t addr_offset =
+ (adjust_opcode / prologue->line_range) * prologue->min_inst_length;
+ int32_t line_offset =
+ prologue->line_base + (adjust_opcode % prologue->line_range);
+ state.line += line_offset;
+ state.address += addr_offset;
+ state.AppendRowToMatrix(*offset_ptr);
}
+ }
- state.Finalize( *offset_ptr );
+ state.Finalize(*offset_ptr);
- return end_offset;
+ return end_offset;
}
-
//----------------------------------------------------------------------
// ParseStatementTableCallback
//----------------------------------------------------------------------
-static void
-ParseStatementTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
-{
- DWARFDebugLine::LineTable* line_table = (DWARFDebugLine::LineTable*)userData;
- if (state.row == DWARFDebugLine::State::StartParsingLineTable)
- {
- // Just started parsing the line table, so lets keep a reference to
- // the prologue using the supplied shared pointer
- line_table->prologue = state.prologue;
- }
- else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
- {
- // Done parsing line table, nothing to do for the cleanup
- }
- else
- {
- // We have a new row, lets append it
- line_table->AppendRow(state);
- }
+static void ParseStatementTableCallback(dw_offset_t offset,
+ const DWARFDebugLine::State &state,
+ void *userData) {
+ DWARFDebugLine::LineTable *line_table = (DWARFDebugLine::LineTable *)userData;
+ if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
+ // Just started parsing the line table, so lets keep a reference to
+ // the prologue using the supplied shared pointer
+ line_table->prologue = state.prologue;
+ } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
+ // Done parsing line table, nothing to do for the cleanup
+ } else {
+ // We have a new row, lets append it
+ line_table->AppendRow(state);
+ }
}
//----------------------------------------------------------------------
@@ -820,75 +772,65 @@ ParseStatementTableCallback(dw_offset_t
// Parse a line table at offset and populate the LineTable class with
// the prologue and all rows.
//----------------------------------------------------------------------
-bool
-DWARFDebugLine::ParseStatementTable(const DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table)
-{
- return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table);
+bool DWARFDebugLine::ParseStatementTable(
+ const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
+ LineTable *line_table) {
+ return ParseStatementTable(debug_line_data, offset_ptr,
+ ParseStatementTableCallback, line_table);
}
-
-inline bool
-DWARFDebugLine::Prologue::IsValid() const
-{
- return SymbolFileDWARF::SupportedVersion(version);
+inline bool DWARFDebugLine::Prologue::IsValid() const {
+ return SymbolFileDWARF::SupportedVersion(version);
}
//----------------------------------------------------------------------
// DWARFDebugLine::Prologue::Dump
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Prologue::Dump(Log *log)
-{
- uint32_t i;
-
- log->Printf( "Line table prologue:");
- log->Printf( " total_length: 0x%8.8x", total_length);
- log->Printf( " version: %u", version);
- log->Printf( "prologue_length: 0x%8.8x", prologue_length);
- log->Printf( "min_inst_length: %u", min_inst_length);
- log->Printf( "default_is_stmt: %u", default_is_stmt);
- log->Printf( " line_base: %i", line_base);
- log->Printf( " line_range: %u", line_range);
- log->Printf( " opcode_base: %u", opcode_base);
-
- for (i=0; i<standard_opcode_lengths.size(); ++i)
- {
- log->Printf( "standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i+1), standard_opcode_lengths[i]);
- }
-
- if (!include_directories.empty())
- {
- for (i=0; i<include_directories.size(); ++i)
- {
- log->Printf( "include_directories[%3u] = '%s'", i+1, include_directories[i]);
- }
- }
+void DWARFDebugLine::Prologue::Dump(Log *log) {
+ uint32_t i;
- if (!file_names.empty())
- {
- log->PutCString (" Dir Mod Time File Len File Name");
- log->PutCString (" ---- ---------- ---------- ---------------------------");
- for (i=0; i<file_names.size(); ++i)
- {
- const FileNameEntry& fileEntry = file_names[i];
- log->Printf ("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s",
- i+1,
- fileEntry.dir_idx,
- fileEntry.mod_time,
- fileEntry.length,
- fileEntry.name);
- }
+ log->Printf("Line table prologue:");
+ log->Printf(" total_length: 0x%8.8x", total_length);
+ log->Printf(" version: %u", version);
+ log->Printf("prologue_length: 0x%8.8x", prologue_length);
+ log->Printf("min_inst_length: %u", min_inst_length);
+ log->Printf("default_is_stmt: %u", default_is_stmt);
+ log->Printf(" line_base: %i", line_base);
+ log->Printf(" line_range: %u", line_range);
+ log->Printf(" opcode_base: %u", opcode_base);
+
+ for (i = 0; i < standard_opcode_lengths.size(); ++i) {
+ log->Printf("standard_opcode_lengths[%s] = %u", DW_LNS_value_to_name(i + 1),
+ standard_opcode_lengths[i]);
+ }
+
+ if (!include_directories.empty()) {
+ for (i = 0; i < include_directories.size(); ++i) {
+ log->Printf("include_directories[%3u] = '%s'", i + 1,
+ include_directories[i]);
+ }
+ }
+
+ if (!file_names.empty()) {
+ log->PutCString(" Dir Mod Time File Len File Name");
+ log->PutCString(" ---- ---------- ---------- "
+ "---------------------------");
+ for (i = 0; i < file_names.size(); ++i) {
+ const FileNameEntry &fileEntry = file_names[i];
+ log->Printf("file_names[%3u] %4u 0x%8.8x 0x%8.8x %s", i + 1,
+ fileEntry.dir_idx, fileEntry.mod_time, fileEntry.length,
+ fileEntry.name);
}
+ }
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue::Append
//
// Append the contents of the prologue to the binary stream buffer
//----------------------------------------------------------------------
-//void
-//DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
+// void
+// DWARFDebugLine::Prologue::Append(BinaryStreamBuf& buff) const
//{
// uint32_t i;
//
@@ -906,7 +848,8 @@ DWARFDebugLine::Prologue::Dump(Log *log)
//
// for (i=0; i<include_directories.size(); ++i)
// buff.AppendCStr(include_directories[i].c_str());
-// buff.Append8(0); // Terminate the include directory section with empty string
+// buff.Append8(0); // Terminate the include directory section with empty
+// string
//
// for (i=0; i<file_names.size(); ++i)
// {
@@ -918,307 +861,242 @@ DWARFDebugLine::Prologue::Dump(Log *log)
// buff.Append8(0); // Terminate the file names section with empty string
//}
-
-bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir, FileSpec &file) const
-{
- uint32_t idx = file_idx - 1; // File indexes are 1 based...
- if (idx < file_names.size())
- {
- file.SetFile(file_names[idx].name, false);
- if (file.IsRelative())
- {
- if (file_names[idx].dir_idx > 0)
- {
- const uint32_t dir_idx = file_names[idx].dir_idx - 1;
- if (dir_idx < include_directories.size())
- {
- file.PrependPathComponent(include_directories[dir_idx]);
- if (!file.IsRelative())
- return true;
- }
- }
-
- if (comp_dir && comp_dir[0])
- file.PrependPathComponent(comp_dir);
+bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const char *comp_dir,
+ FileSpec &file) const {
+ uint32_t idx = file_idx - 1; // File indexes are 1 based...
+ if (idx < file_names.size()) {
+ file.SetFile(file_names[idx].name, false);
+ if (file.IsRelative()) {
+ if (file_names[idx].dir_idx > 0) {
+ const uint32_t dir_idx = file_names[idx].dir_idx - 1;
+ if (dir_idx < include_directories.size()) {
+ file.PrependPathComponent(include_directories[dir_idx]);
+ if (!file.IsRelative())
+ return true;
}
- return true;
+ }
+
+ if (comp_dir && comp_dir[0])
+ file.PrependPathComponent(comp_dir);
}
- return false;
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------------
// DWARFDebugLine::LineTable::Dump
//----------------------------------------------------------------------
-void
-DWARFDebugLine::LineTable::Dump(Log *log) const
-{
- if (prologue.get())
- prologue->Dump (log);
-
- if (!rows.empty())
- {
- log->PutCString ("Address Line Column File ISA Flags");
- log->PutCString ("------------------ ------ ------ ------ --- -------------");
- Row::const_iterator pos = rows.begin();
- Row::const_iterator end = rows.end();
- while (pos != end)
- {
- (*pos).Dump (log);
- ++pos;
- }
+void DWARFDebugLine::LineTable::Dump(Log *log) const {
+ if (prologue.get())
+ prologue->Dump(log);
+
+ if (!rows.empty()) {
+ log->PutCString("Address Line Column File ISA Flags");
+ log->PutCString(
+ "------------------ ------ ------ ------ --- -------------");
+ Row::const_iterator pos = rows.begin();
+ Row::const_iterator end = rows.end();
+ while (pos != end) {
+ (*pos).Dump(log);
+ ++pos;
}
+ }
}
-
-void
-DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row& state)
-{
- rows.push_back(state);
+void DWARFDebugLine::LineTable::AppendRow(const DWARFDebugLine::Row &state) {
+ rows.push_back(state);
}
-
-
//----------------------------------------------------------------------
-// Compare function for the binary search in DWARFDebugLine::LineTable::LookupAddress()
+// Compare function for the binary search in
+// DWARFDebugLine::LineTable::LookupAddress()
//----------------------------------------------------------------------
-static bool FindMatchingAddress (const DWARFDebugLine::Row& row1, const DWARFDebugLine::Row& row2)
-{
- return row1.address < row2.address;
+static bool FindMatchingAddress(const DWARFDebugLine::Row &row1,
+ const DWARFDebugLine::Row &row2) {
+ return row1.address < row2.address;
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::LineTable::LookupAddress
//----------------------------------------------------------------------
-uint32_t
-DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const
-{
- uint32_t index = UINT32_MAX;
- if (!rows.empty())
- {
- // Use the lower_bound algorithm to perform a binary search since we know
- // that our line table data is ordered by address.
- DWARFDebugLine::Row row;
- row.address = address;
- Row::const_iterator begin_pos = rows.begin();
- Row::const_iterator end_pos = rows.end();
- Row::const_iterator pos = lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
- if (pos == end_pos)
- {
- if (address < cu_high_pc)
- return rows.size()-1;
- }
+uint32_t DWARFDebugLine::LineTable::LookupAddress(dw_addr_t address,
+ dw_addr_t cu_high_pc) const {
+ uint32_t index = UINT32_MAX;
+ if (!rows.empty()) {
+ // Use the lower_bound algorithm to perform a binary search since we know
+ // that our line table data is ordered by address.
+ DWARFDebugLine::Row row;
+ row.address = address;
+ Row::const_iterator begin_pos = rows.begin();
+ Row::const_iterator end_pos = rows.end();
+ Row::const_iterator pos =
+ lower_bound(begin_pos, end_pos, row, FindMatchingAddress);
+ if (pos == end_pos) {
+ if (address < cu_high_pc)
+ return rows.size() - 1;
+ } else {
+ // Rely on fact that we are using a std::vector and we can do
+ // pointer arithmetic to find the row index (which will be one less
+ // that what we found since it will find the first position after
+ // the current address) since std::vector iterators are just
+ // pointers to the container type.
+ index = pos - begin_pos;
+ if (pos->address > address) {
+ if (index > 0)
+ --index;
else
- {
- // Rely on fact that we are using a std::vector and we can do
- // pointer arithmetic to find the row index (which will be one less
- // that what we found since it will find the first position after
- // the current address) since std::vector iterators are just
- // pointers to the container type.
- index = pos - begin_pos;
- if (pos->address > address)
- {
- if (index > 0)
- --index;
- else
- index = UINT32_MAX;
- }
- }
+ index = UINT32_MAX;
+ }
}
- return index; // Failed to find address
+ }
+ return index; // Failed to find address
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::Row::Row
//----------------------------------------------------------------------
-DWARFDebugLine::Row::Row(bool default_is_stmt) :
- address(0),
- line(1),
- column(0),
- file(1),
- is_stmt(default_is_stmt),
- basic_block(false),
- end_sequence(false),
- prologue_end(false),
- epilogue_begin(false),
- isa(0)
-{
-}
+DWARFDebugLine::Row::Row(bool default_is_stmt)
+ : address(0), line(1), column(0), file(1), is_stmt(default_is_stmt),
+ basic_block(false), end_sequence(false), prologue_end(false),
+ epilogue_begin(false), isa(0) {}
//----------------------------------------------------------------------
// Called after a row is appended to the matrix
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Row::PostAppend()
-{
- basic_block = false;
- prologue_end = false;
- epilogue_begin = false;
+void DWARFDebugLine::Row::PostAppend() {
+ basic_block = false;
+ prologue_end = false;
+ epilogue_begin = false;
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::Row::Reset
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Row::Reset(bool default_is_stmt)
-{
- address = 0;
- line = 1;
- column = 0;
- file = 1;
- is_stmt = default_is_stmt;
- basic_block = false;
- end_sequence = false;
- prologue_end = false;
- epilogue_begin = false;
- isa = 0;
+void DWARFDebugLine::Row::Reset(bool default_is_stmt) {
+ address = 0;
+ line = 1;
+ column = 0;
+ file = 1;
+ is_stmt = default_is_stmt;
+ basic_block = false;
+ end_sequence = false;
+ prologue_end = false;
+ epilogue_begin = false;
+ isa = 0;
}
//----------------------------------------------------------------------
// DWARFDebugLine::Row::Dump
//----------------------------------------------------------------------
-void
-DWARFDebugLine::Row::Dump(Log *log) const
-{
- log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s",
- address,
- line,
- column,
- file,
- isa,
- is_stmt ? " is_stmt" : "",
- basic_block ? " basic_block" : "",
- prologue_end ? " prologue_end" : "",
- epilogue_begin ? " epilogue_begin" : "",
- end_sequence ? " end_sequence" : "");
+void DWARFDebugLine::Row::Dump(Log *log) const {
+ log->Printf("0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s", address, line,
+ column, file, isa, is_stmt ? " is_stmt" : "",
+ basic_block ? " basic_block" : "",
+ prologue_end ? " prologue_end" : "",
+ epilogue_begin ? " epilogue_begin" : "",
+ end_sequence ? " end_sequence" : "");
}
//----------------------------------------------------------------------
// Compare function LineTable structures
//----------------------------------------------------------------------
-static bool AddressLessThan (const DWARFDebugLine::Row& a, const DWARFDebugLine::Row& b)
-{
- return a.address < b.address;
+static bool AddressLessThan(const DWARFDebugLine::Row &a,
+ const DWARFDebugLine::Row &b) {
+ return a.address < b.address;
}
-
-
// Insert a row at the correct address if the addresses can be out of
// order which can only happen when we are linking a line table that
// may have had it's contents rearranged.
-void
-DWARFDebugLine::Row::Insert(Row::collection& state_coll, const Row& state)
-{
- // If we don't have anything yet, or if the address of the last state in our
- // line table is less than the current one, just append the current state
- if (state_coll.empty() || AddressLessThan(state_coll.back(), state))
- {
- state_coll.push_back(state);
- }
- else
- {
- // Do a binary search for the correct entry
- pair<Row::iterator, Row::iterator> range(equal_range(state_coll.begin(), state_coll.end(), state, AddressLessThan));
-
- // If the addresses are equal, we can safely replace the previous entry
- // with the current one if the one it is replacing is an end_sequence entry.
- // We currently always place an extra end sequence when ever we exit a valid
- // address range for a function in case the functions get rearranged by
- // optimizations or by order specifications. These extra end sequences will
- // disappear by getting replaced with valid consecutive entries within a
- // compile unit if there are no gaps.
- if (range.first == range.second)
- {
- state_coll.insert(range.first, state);
- }
- else
- {
- if ((distance(range.first, range.second) == 1) && range.first->end_sequence == true)
- {
- *range.first = state;
- }
- else
- {
- state_coll.insert(range.second, state);
- }
- }
- }
-}
-
-void
-DWARFDebugLine::Row::Dump(Log *log, const Row::collection& state_coll)
-{
- std::for_each (state_coll.begin(), state_coll.end(), bind2nd(std::mem_fun_ref(&Row::Dump),log));
+void DWARFDebugLine::Row::Insert(Row::collection &state_coll,
+ const Row &state) {
+ // If we don't have anything yet, or if the address of the last state in our
+ // line table is less than the current one, just append the current state
+ if (state_coll.empty() || AddressLessThan(state_coll.back(), state)) {
+ state_coll.push_back(state);
+ } else {
+ // Do a binary search for the correct entry
+ pair<Row::iterator, Row::iterator> range(equal_range(
+ state_coll.begin(), state_coll.end(), state, AddressLessThan));
+
+ // If the addresses are equal, we can safely replace the previous entry
+ // with the current one if the one it is replacing is an end_sequence entry.
+ // We currently always place an extra end sequence when ever we exit a valid
+ // address range for a function in case the functions get rearranged by
+ // optimizations or by order specifications. These extra end sequences will
+ // disappear by getting replaced with valid consecutive entries within a
+ // compile unit if there are no gaps.
+ if (range.first == range.second) {
+ state_coll.insert(range.first, state);
+ } else {
+ if ((distance(range.first, range.second) == 1) &&
+ range.first->end_sequence == true) {
+ *range.first = state;
+ } else {
+ state_coll.insert(range.second, state);
+ }
+ }
+ }
+}
+
+void DWARFDebugLine::Row::Dump(Log *log, const Row::collection &state_coll) {
+ std::for_each(state_coll.begin(), state_coll.end(),
+ bind2nd(std::mem_fun_ref(&Row::Dump), log));
}
-
//----------------------------------------------------------------------
// DWARFDebugLine::State::State
//----------------------------------------------------------------------
-DWARFDebugLine::State::State(Prologue::shared_ptr& p, Log *l, DWARFDebugLine::State::Callback cb, void* userData) :
- Row (p->default_is_stmt),
- prologue (p),
- log (l),
- callback (cb),
- callbackUserData (userData),
- row (StartParsingLineTable)
-{
- // Call the callback with the initial row state of zero for the prologue
- if (callback)
- callback(0, *this, callbackUserData);
+DWARFDebugLine::State::State(Prologue::shared_ptr &p, Log *l,
+ DWARFDebugLine::State::Callback cb, void *userData)
+ : Row(p->default_is_stmt), prologue(p), log(l), callback(cb),
+ callbackUserData(userData), row(StartParsingLineTable) {
+ // Call the callback with the initial row state of zero for the prologue
+ if (callback)
+ callback(0, *this, callbackUserData);
}
//----------------------------------------------------------------------
// DWARFDebugLine::State::Reset
//----------------------------------------------------------------------
-void
-DWARFDebugLine::State::Reset()
-{
- Row::Reset(prologue->default_is_stmt);
-}
+void DWARFDebugLine::State::Reset() { Row::Reset(prologue->default_is_stmt); }
//----------------------------------------------------------------------
// DWARFDebugLine::State::AppendRowToMatrix
//----------------------------------------------------------------------
-void
-DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset)
-{
- // Each time we are to add an entry into the line table matrix
- // call the callback function so that someone can do something with
- // the current state of the state machine (like build a line table
- // or dump the line table!)
- if (log)
- {
- if (row == 0)
- {
- log->PutCString ("Address Line Column File ISA Flags");
- log->PutCString ("------------------ ------ ------ ------ --- -------------");
- }
- Dump (log);
- }
-
- ++row; // Increase the row number before we call our callback for a real row
- if (callback)
- callback(offset, *this, callbackUserData);
- PostAppend();
+void DWARFDebugLine::State::AppendRowToMatrix(dw_offset_t offset) {
+ // Each time we are to add an entry into the line table matrix
+ // call the callback function so that someone can do something with
+ // the current state of the state machine (like build a line table
+ // or dump the line table!)
+ if (log) {
+ if (row == 0) {
+ log->PutCString("Address Line Column File ISA Flags");
+ log->PutCString(
+ "------------------ ------ ------ ------ --- -------------");
+ }
+ Dump(log);
+ }
+
+ ++row; // Increase the row number before we call our callback for a real row
+ if (callback)
+ callback(offset, *this, callbackUserData);
+ PostAppend();
}
//----------------------------------------------------------------------
// DWARFDebugLine::State::Finalize
//----------------------------------------------------------------------
-void
-DWARFDebugLine::State::Finalize(dw_offset_t offset)
-{
- // Call the callback with a special row state when we are done parsing a
- // line table
- row = DoneParsingLineTable;
- if (callback)
- callback(offset, *this, callbackUserData);
+void DWARFDebugLine::State::Finalize(dw_offset_t offset) {
+ // Call the callback with a special row state when we are done parsing a
+ // line table
+ row = DoneParsingLineTable;
+ if (callback)
+ callback(offset, *this, callbackUserData);
}
-//void
-//DWARFDebugLine::AppendLineTableData
+// void
+// DWARFDebugLine::AppendLineTableData
//(
// const DWARFDebugLine::Prologue* prologue,
// const DWARFDebugLine::Row::collection& state_coll,
@@ -1240,7 +1118,8 @@ DWARFDebugLine::State::Finalize(dw_offse
// bool default_is_stmt = prologue->default_is_stmt;
// const DWARFDebugLine::Row reset_state(default_is_stmt);
// const DWARFDebugLine::Row* prev_state = &reset_state;
-// const int32_t max_line_increment_for_special_opcode = prologue->MaxLineIncrementForSpecialOpcode();
+// const int32_t max_line_increment_for_special_opcode =
+// prologue->MaxLineIncrementForSpecialOpcode();
// for (pos = state_coll.begin(); pos != end; ++pos)
// {
// const DWARFDebugLine::Row& curr_state = *pos;
@@ -1257,7 +1136,8 @@ DWARFDebugLine::State::Finalize(dw_offse
// if (prev_state == &reset_state)
// {
// debug_line_data.Append8(0); // Extended opcode
-// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of opcode bytes
+// debug_line_data.Append32_as_ULEB128(addr_size + 1); // Length of
+// opcode bytes
// debug_line_data.Append8(DW_LNE_set_address);
// debug_line_data.AppendMax64(curr_state.address, addr_size);
// addr_advance = 0;
@@ -1276,7 +1156,8 @@ DWARFDebugLine::State::Finalize(dw_offse
// }
//
// // Don't do anything fancy if we are at the end of a sequence
-// // as we don't want to push any extra rows since the DW_LNE_end_sequence
+// // as we don't want to push any extra rows since the
+// DW_LNE_end_sequence
// // will push a row itself!
// if (curr_state.end_sequence)
// {
@@ -1310,26 +1191,38 @@ DWARFDebugLine::State::Finalize(dw_offse
// line_increment = 0;
// }
//
-// uint32_t special_opcode = (line_increment >= prologue->line_base) ? ((line_increment - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
+// uint32_t special_opcode = (line_increment >=
+// prologue->line_base) ? ((line_increment -
+// prologue->line_base) + (prologue->line_range * addr_advance)
+// + prologue->opcode_base) : 256;
// if (special_opcode > 255)
// {
-// // Both the address and line won't fit in one special opcode
+// // Both the address and line won't fit in one special
+// opcode
// // check to see if just the line advance will?
-// uint32_t special_opcode_line = ((line_increment >= prologue->line_base) && (line_increment != 0)) ?
-// ((line_increment - prologue->line_base) + prologue->opcode_base) : 256;
+// uint32_t special_opcode_line = ((line_increment >=
+// prologue->line_base) && (line_increment != 0)) ?
+// ((line_increment - prologue->line_base) +
+// prologue->opcode_base) : 256;
//
//
// if (special_opcode_line > 255)
// {
-// // Nope, the line advance won't fit by itself, check the address increment by itself
+// // Nope, the line advance won't fit by itself, check
+// the address increment by itself
// uint32_t special_opcode_addr = addr_advance ?
-// ((0 - prologue->line_base) + (prologue->line_range * addr_advance) + prologue->opcode_base) : 256;
+// ((0 - prologue->line_base) +
+// (prologue->line_range * addr_advance) +
+// prologue->opcode_base) : 256;
//
// if (special_opcode_addr > 255)
// {
-// // Neither the address nor the line will fit in a
-// // special opcode, we must manually enter both then
-// // do a DW_LNS_copy to push a row (special opcode
+// // Neither the address nor the line will fit in
+// a
+// // special opcode, we must manually enter both
+// then
+// // do a DW_LNS_copy to push a row (special
+// opcode
// // automatically imply a new row is pushed)
// if (line_increment != 0)
// {
@@ -1349,9 +1242,12 @@ DWARFDebugLine::State::Finalize(dw_offse
// }
// else
// {
-// // The address increment alone will fit into a special opcode
-// // so modify our line change, then issue a special opcode
-// // for the address increment and it will push a row into the
+// // The address increment alone will fit into a
+// special opcode
+// // so modify our line change, then issue a
+// special opcode
+// // for the address increment and it will push a
+// row into the
// // line table
// if (line_increment != 0)
// {
@@ -1359,16 +1255,21 @@ DWARFDebugLine::State::Finalize(dw_offse
// debug_line_data.Append32_as_SLEB128(line_increment);
// }
//
-// // Advance of line and address will fit into a single byte special opcode
-// // and this will also push a row onto the line table
+// // Advance of line and address will fit into a
+// single byte special opcode
+// // and this will also push a row onto the line
+// table
// debug_line_data.Append8(special_opcode_addr);
// }
// }
// else
// {
-// // The line change alone will fit into a special opcode
-// // so modify our address increment first, then issue a
-// // special opcode for the line change and it will push
+// // The line change alone will fit into a special
+// opcode
+// // so modify our address increment first, then issue
+// a
+// // special opcode for the line change and it will
+// push
// // a row into the line table
// if (addr_advance > 0)
// {
@@ -1376,14 +1277,16 @@ DWARFDebugLine::State::Finalize(dw_offse
// debug_line_data.Append32_as_ULEB128(addr_advance);
// }
//
-// // Advance of line and address will fit into a single byte special opcode
+// // Advance of line and address will fit into a
+// single byte special opcode
// // and this will also push a row onto the line table
// debug_line_data.Append8(special_opcode_line);
// }
// }
// else
// {
-// // Advance of line and address will fit into a single byte special opcode
+// // Advance of line and address will fit into a single
+// byte special opcode
// // and this will also push a row onto the line table
// debug_line_data.Append8(special_opcode);
// }
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h Tue Sep 6 15:57:50 2016
@@ -11,8 +11,8 @@
#define SymbolFileDWARF_DWARFDebugLine_h_
#include <map>
-#include <vector>
#include <string>
+#include <vector>
#include "lldb/lldb-private.h"
@@ -24,199 +24,219 @@ class SymbolFileDWARF;
//----------------------------------------------------------------------
// DWARFDebugLine
//----------------------------------------------------------------------
-class DWARFDebugLine
-{
+class DWARFDebugLine {
public:
- //------------------------------------------------------------------
- // FileNameEntry
- //------------------------------------------------------------------
- struct FileNameEntry
- {
- FileNameEntry() :
- name(nullptr),
- dir_idx(0),
- mod_time(0),
- length(0)
- {
- }
-
- const char* name;
- dw_sleb128_t dir_idx;
- dw_sleb128_t mod_time;
- dw_sleb128_t length;
-
- };
-
- //------------------------------------------------------------------
- // Prologue
- //------------------------------------------------------------------
- struct Prologue
- {
-
- Prologue() :
- total_length(0),
- version(0),
- prologue_length(0),
- min_inst_length(0),
- default_is_stmt(0),
- line_base(0),
- line_range(0),
- opcode_base(0),
- standard_opcode_lengths(),
- include_directories(),
- file_names()
- {
- }
-
- typedef std::shared_ptr<Prologue> shared_ptr;
-
- uint32_t total_length; // The size in bytes of the statement information for this compilation unit (not including the total_length field itself).
- uint16_t version; // Version identifier for the statement information format.
- uint32_t prologue_length;// The number of bytes following the prologue_length field to the beginning of the first byte of the statement program itself.
- uint8_t min_inst_length;// The size in bytes of the smallest target machine instruction. Statement program opcodes that alter the address register first multiply their operands by this value.
- uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum number of individual operations that may be encoded in an instruction.
- uint8_t default_is_stmt;// The initial value of theis_stmtregister.
- int8_t line_base; // This parameter affects the meaning of the special opcodes. See below.
- uint8_t line_range; // This parameter affects the meaning of the special opcodes. See below.
- uint8_t opcode_base; // The number assigned to the first special opcode.
- std::vector<uint8_t> standard_opcode_lengths;
- std::vector<const char *> include_directories;
- std::vector<FileNameEntry> file_names;
-
- int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; }
- bool IsValid() const;
-// void Append(BinaryStreamBuf& buff) const;
- void Dump (lldb_private::Log *log);
- void Clear()
- {
- total_length = version = prologue_length = min_inst_length = line_base = line_range = opcode_base = 0;
- line_base = 0;
- standard_opcode_lengths.clear();
- include_directories.clear();
- file_names.clear();
- }
- bool GetFile(uint32_t file_idx, const char *comp_dir, lldb_private::FileSpec &file) const;
-
- };
-
- // Standard .debug_line state machine structure
- struct Row
- {
- typedef std::vector<Row> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- Row(bool default_is_stmt = false);
- virtual ~Row() {}
- void PostAppend ();
- void Reset(bool default_is_stmt);
- void Dump(lldb_private::Log *log) const;
- static void Insert(Row::collection& state_coll, const Row& state);
- static void Dump(lldb_private::Log *log, const Row::collection& state_coll);
-
- dw_addr_t address; // The program-counter value corresponding to a machine instruction generated by the compiler.
- uint32_t line; // An unsigned integer indicating a source line number. Lines are numbered beginning at 1. The compiler may emit the value 0 in cases where an instruction cannot be attributed to any source line.
- uint16_t column; // An unsigned integer indicating a column number within a source line. Columns are numbered beginning at 1. The value 0 is reserved to indicate that a statement begins at the 'left edge' of the line.
- uint16_t file; // An unsigned integer indicating the identity of the source file corresponding to a machine instruction.
- uint8_t is_stmt:1, // A boolean indicating that the current instruction is the beginning of a statement.
- basic_block:1, // A boolean indicating that the current instruction is the beginning of a basic block.
- end_sequence:1, // A boolean indicating that the current address is that of the first byte after the end of a sequence of target machine instructions.
- prologue_end:1, // A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an entry breakpoint of a function.
- epilogue_begin:1;// A boolean indicating that the current address is one (of possibly many) where execution should be suspended for an exit breakpoint of a function.
- uint32_t isa; // An unsigned integer whose value encodes the applicable instruction set architecture for the current instruction.
- };
-
-
- //------------------------------------------------------------------
- // LineTable
- //------------------------------------------------------------------
- struct LineTable
- {
- typedef std::shared_ptr<LineTable> shared_ptr;
-
- LineTable() :
- prologue(),
- rows()
- {
- }
-
- void AppendRow(const DWARFDebugLine::Row& state);
- void Clear()
- {
- prologue.reset();
- rows.clear();
- }
-
- uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
- void Dump(lldb_private::Log *log) const;
-
- Prologue::shared_ptr prologue;
- Row::collection rows;
- };
-
- //------------------------------------------------------------------
- // State
- //------------------------------------------------------------------
- struct State : public Row
- {
- typedef void (*Callback)(dw_offset_t offset, const State& state, void* userData);
-
- // Special row codes used when calling the callback
- enum
- {
- StartParsingLineTable = 0,
- DoneParsingLineTable = -1
- };
-
- State (Prologue::shared_ptr& prologue_sp,
- lldb_private::Log *log,
- Callback callback,
- void* userData);
-
- void
- AppendRowToMatrix (dw_offset_t offset);
-
- void
- Finalize (dw_offset_t offset);
-
- void
- Reset ();
-
- Prologue::shared_ptr prologue;
- lldb_private::Log *log;
- Callback callback; // Callback function that gets called each time an entry is to be added to the matrix
- void* callbackUserData;
- int row; // The row number that starts at zero for the prologue, and increases for each row added to the matrix
- private:
- DISALLOW_COPY_AND_ASSIGN (State);
- };
-
- static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
- static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
- static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DWARFDataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files);
- static bool ParsePrologue(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
- static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
- static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset);
- static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DWARFDataExtractor& debug_line_data, const dw_offset_t line_offset, uint32_t flags);
- static bool ParseStatementTable(const lldb_private::DWARFDataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table);
- static void Parse(const lldb_private::DWARFDataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
-// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
-
- DWARFDebugLine() :
- m_lineTableMap()
- {
+ //------------------------------------------------------------------
+ // FileNameEntry
+ //------------------------------------------------------------------
+ struct FileNameEntry {
+ FileNameEntry() : name(nullptr), dir_idx(0), mod_time(0), length(0) {}
+
+ const char *name;
+ dw_sleb128_t dir_idx;
+ dw_sleb128_t mod_time;
+ dw_sleb128_t length;
+ };
+
+ //------------------------------------------------------------------
+ // Prologue
+ //------------------------------------------------------------------
+ struct Prologue {
+
+ Prologue()
+ : total_length(0), version(0), prologue_length(0), min_inst_length(0),
+ default_is_stmt(0), line_base(0), line_range(0), opcode_base(0),
+ standard_opcode_lengths(), include_directories(), file_names() {}
+
+ typedef std::shared_ptr<Prologue> shared_ptr;
+
+ uint32_t total_length; // The size in bytes of the statement information for
+ // this compilation unit (not including the
+ // total_length field itself).
+ uint16_t
+ version; // Version identifier for the statement information format.
+ uint32_t prologue_length; // The number of bytes following the
+ // prologue_length field to the beginning of the
+ // first byte of the statement program itself.
+ uint8_t min_inst_length; // The size in bytes of the smallest target machine
+ // instruction. Statement program opcodes that
+ // alter the address register first multiply their
+ // operands by this value.
+ uint8_t maximum_operations_per_instruction; // New in DWARF4. The maximum
+ // number of individual
+ // operations that may be
+ // encoded in an instruction.
+ uint8_t default_is_stmt; // The initial value of theis_stmtregister.
+ int8_t line_base; // This parameter affects the meaning of the special
+ // opcodes. See below.
+ uint8_t line_range; // This parameter affects the meaning of the special
+ // opcodes. See below.
+ uint8_t opcode_base; // The number assigned to the first special opcode.
+ std::vector<uint8_t> standard_opcode_lengths;
+ std::vector<const char *> include_directories;
+ std::vector<FileNameEntry> file_names;
+
+ int32_t MaxLineIncrementForSpecialOpcode() const {
+ return line_base + (int8_t)line_range - 1;
}
+ bool IsValid() const;
+ // void Append(BinaryStreamBuf& buff) const;
+ void Dump(lldb_private::Log *log);
+ void Clear() {
+ total_length = version = prologue_length = min_inst_length = line_base =
+ line_range = opcode_base = 0;
+ line_base = 0;
+ standard_opcode_lengths.clear();
+ include_directories.clear();
+ file_names.clear();
+ }
+ bool GetFile(uint32_t file_idx, const char *comp_dir,
+ lldb_private::FileSpec &file) const;
+ };
+
+ // Standard .debug_line state machine structure
+ struct Row {
+ typedef std::vector<Row> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ Row(bool default_is_stmt = false);
+ virtual ~Row() {}
+ void PostAppend();
+ void Reset(bool default_is_stmt);
+ void Dump(lldb_private::Log *log) const;
+ static void Insert(Row::collection &state_coll, const Row &state);
+ static void Dump(lldb_private::Log *log, const Row::collection &state_coll);
+
+ dw_addr_t address; // The program-counter value corresponding to a machine
+ // instruction generated by the compiler.
+ uint32_t line; // An unsigned integer indicating a source line number. Lines
+ // are numbered beginning at 1. The compiler may emit the
+ // value 0 in cases where an instruction cannot be attributed
+ // to any source line.
+ uint16_t column; // An unsigned integer indicating a column number within a
+ // source line. Columns are numbered beginning at 1. The
+ // value 0 is reserved to indicate that a statement begins
+ // at the 'left edge' of the line.
+ uint16_t file; // An unsigned integer indicating the identity of the source
+ // file corresponding to a machine instruction.
+ uint8_t is_stmt : 1, // A boolean indicating that the current instruction is
+ // the beginning of a statement.
+ basic_block : 1, // A boolean indicating that the current instruction is
+ // the beginning of a basic block.
+ end_sequence : 1, // A boolean indicating that the current address is
+ // that of the first byte after the end of a sequence
+ // of target machine instructions.
+ prologue_end : 1, // A boolean indicating that the current address is
+ // one (of possibly many) where execution should be
+ // suspended for an entry breakpoint of a function.
+ epilogue_begin : 1; // A boolean indicating that the current address is
+ // one (of possibly many) where execution should be
+ // suspended for an exit breakpoint of a function.
+ uint32_t isa; // An unsigned integer whose value encodes the applicable
+ // instruction set architecture for the current instruction.
+ };
+
+ //------------------------------------------------------------------
+ // LineTable
+ //------------------------------------------------------------------
+ struct LineTable {
+ typedef std::shared_ptr<LineTable> shared_ptr;
+
+ LineTable() : prologue(), rows() {}
+
+ void AppendRow(const DWARFDebugLine::Row &state);
+ void Clear() {
+ prologue.reset();
+ rows.clear();
+ }
+
+ uint32_t LookupAddress(dw_addr_t address, dw_addr_t cu_high_pc) const;
+ void Dump(lldb_private::Log *log) const;
- void Parse(const lldb_private::DWARFDataExtractor& debug_line_data);
- void ParseIfNeeded(const lldb_private::DWARFDataExtractor& debug_line_data);
- LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
+ Prologue::shared_ptr prologue;
+ Row::collection rows;
+ };
+
+ //------------------------------------------------------------------
+ // State
+ //------------------------------------------------------------------
+ struct State : public Row {
+ typedef void (*Callback)(dw_offset_t offset, const State &state,
+ void *userData);
+
+ // Special row codes used when calling the callback
+ enum { StartParsingLineTable = 0, DoneParsingLineTable = -1 };
+
+ State(Prologue::shared_ptr &prologue_sp, lldb_private::Log *log,
+ Callback callback, void *userData);
+
+ void AppendRowToMatrix(dw_offset_t offset);
+
+ void Finalize(dw_offset_t offset);
+
+ void Reset();
+
+ Prologue::shared_ptr prologue;
+ lldb_private::Log *log;
+ Callback callback; // Callback function that gets called each time an entry
+ // is to be added to the matrix
+ void *callbackUserData;
+ int row; // The row number that starts at zero for the prologue, and
+ // increases for each row added to the matrix
+ private:
+ DISALLOW_COPY_AND_ASSIGN(State);
+ };
+
+ static bool DumpOpcodes(
+ lldb_private::Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t line_offset = DW_INVALID_OFFSET,
+ uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
+ static bool DumpLineTableRows(
+ lldb_private::Log *log, SymbolFileDWARF *dwarf2Data,
+ dw_offset_t line_offset =
+ DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
+ static bool
+ ParseSupportFiles(const lldb::ModuleSP &module_sp,
+ const lldb_private::DWARFDataExtractor &debug_line_data,
+ const char *cu_comp_dir, dw_offset_t stmt_list,
+ lldb_private::FileSpecList &support_files);
+ static bool
+ ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr, Prologue *prologue);
+ static bool
+ ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr, State::Callback callback,
+ void *userData);
+ static dw_offset_t
+ DumpStatementTable(lldb_private::Log *log,
+ const lldb_private::DWARFDataExtractor &debug_line_data,
+ const dw_offset_t line_offset);
+ static dw_offset_t
+ DumpStatementOpcodes(lldb_private::Log *log,
+ const lldb_private::DWARFDataExtractor &debug_line_data,
+ const dw_offset_t line_offset, uint32_t flags);
+ static bool
+ ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr, LineTable *line_table);
+ static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
+ DWARFDebugLine::State::Callback callback, void *userData);
+ // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
+ // const DWARFDebugLine::Row::collection& state_coll, const uint32_t
+ // addr_size, BinaryStreamBuf &debug_line_data);
+
+ DWARFDebugLine() : m_lineTableMap() {}
+
+ void Parse(const lldb_private::DWARFDataExtractor &debug_line_data);
+ void ParseIfNeeded(const lldb_private::DWARFDataExtractor &debug_line_data);
+ LineTable::shared_ptr GetLineTable(const dw_offset_t offset) const;
protected:
- typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
- typedef LineTableMap::iterator LineTableIter;
- typedef LineTableMap::const_iterator LineTableConstIter;
+ typedef std::map<dw_offset_t, LineTable::shared_ptr> LineTableMap;
+ typedef LineTableMap::iterator LineTableIter;
+ typedef LineTableMap::const_iterator LineTableConstIter;
- LineTableMap m_lineTableMap;
+ LineTableMap m_lineTableMap;
};
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
+#endif // SymbolFileDWARF_DWARFDebugLine_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp Tue Sep 6 15:57:50 2016
@@ -17,32 +17,23 @@
using namespace lldb_private;
using namespace std;
-DWARFDebugMacinfo::DWARFDebugMacinfo()
-{
-}
+DWARFDebugMacinfo::DWARFDebugMacinfo() {}
-DWARFDebugMacinfo::~DWARFDebugMacinfo()
-{
-}
+DWARFDebugMacinfo::~DWARFDebugMacinfo() {}
-void
-DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor& macinfo_data, lldb::offset_t offset)
-{
- DWARFDebugMacinfoEntry maninfo_entry;
- if (macinfo_data.GetByteSize() == 0)
- {
- s->PutCString("< EMPTY >\n");
- return;
- }
- if (offset == LLDB_INVALID_OFFSET)
- {
- offset = 0;
- while (maninfo_entry.Extract(macinfo_data, &offset))
- maninfo_entry.Dump(s);
- }
- else
- {
- if (maninfo_entry.Extract(macinfo_data, &offset))
- maninfo_entry.Dump(s);
- }
+void DWARFDebugMacinfo::Dump(Stream *s, const DWARFDataExtractor &macinfo_data,
+ lldb::offset_t offset) {
+ DWARFDebugMacinfoEntry maninfo_entry;
+ if (macinfo_data.GetByteSize() == 0) {
+ s->PutCString("< EMPTY >\n");
+ return;
+ }
+ if (offset == LLDB_INVALID_OFFSET) {
+ offset = 0;
+ while (maninfo_entry.Extract(macinfo_data, &offset))
+ maninfo_entry.Dump(s);
+ } else {
+ if (maninfo_entry.Extract(macinfo_data, &offset))
+ maninfo_entry.Dump(s);
+ }
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h Tue Sep 6 15:57:50 2016
@@ -12,18 +12,15 @@
#include "SymbolFileDWARF.h"
-class DWARFDebugMacinfo
-{
+class DWARFDebugMacinfo {
public:
- DWARFDebugMacinfo();
+ DWARFDebugMacinfo();
- ~DWARFDebugMacinfo();
+ ~DWARFDebugMacinfo();
- static void
- Dump (lldb_private::Stream *s,
- const lldb_private::DWARFDataExtractor& macinfo_data,
- lldb::offset_t offset = LLDB_INVALID_OFFSET);
+ static void Dump(lldb_private::Stream *s,
+ const lldb_private::DWARFDataExtractor &macinfo_data,
+ lldb::offset_t offset = LLDB_INVALID_OFFSET);
};
-
-#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp Tue Sep 6 15:57:50 2016
@@ -14,119 +14,98 @@
using namespace lldb_private;
using namespace std;
-DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry() :
- m_type_code(0),
- m_line(0),
- m_op2()
-{
- m_op2.cstr = NULL;
+DWARFDebugMacinfoEntry::DWARFDebugMacinfoEntry()
+ : m_type_code(0), m_line(0), m_op2() {
+ m_op2.cstr = NULL;
}
-DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry()
-{
-}
+DWARFDebugMacinfoEntry::~DWARFDebugMacinfoEntry() {}
-const char*
-DWARFDebugMacinfoEntry::GetCString() const
-{
- switch (m_type_code)
- {
- case 0:
- case DW_MACINFO_start_file:
- case DW_MACINFO_end_file:
- return NULL;
- default:
- break;
- }
- return m_op2.cstr;
+const char *DWARFDebugMacinfoEntry::GetCString() const {
+ switch (m_type_code) {
+ case 0:
+ case DW_MACINFO_start_file:
+ case DW_MACINFO_end_file:
+ return NULL;
+ default:
+ break;
+ }
+ return m_op2.cstr;
}
+void DWARFDebugMacinfoEntry::Dump(Stream *s) const {
+ if (m_type_code) {
+ s->PutCString(DW_MACINFO_value_to_name(m_type_code));
+
+ switch (m_type_code) {
+ case DW_MACINFO_define:
+ s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr);
+ break;
+
+ case DW_MACINFO_undef:
+ s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr);
+ break;
+ default:
+ s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr);
+ break;
-void
-DWARFDebugMacinfoEntry::Dump(Stream *s) const
-{
- if (m_type_code)
- {
- s->PutCString(DW_MACINFO_value_to_name(m_type_code));
-
- switch (m_type_code)
- {
- case DW_MACINFO_define:
- s->Printf(" line:%u #define %s\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- case DW_MACINFO_undef:
- s->Printf(" line:%u #undef %s\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- default:
- s->Printf(" line:%u str: '%s'\n", (uint32_t)m_line, m_op2.cstr);
- break;
-
- case DW_MACINFO_start_file:
- s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line, (uint32_t)m_op2.file_idx);
- break;
-
- case DW_MACINFO_end_file:
- break;
- }
- }
- else
- {
- s->PutCString(" END\n");
+ case DW_MACINFO_start_file:
+ s->Printf(" line:%u file index: '%u'\n", (uint32_t)m_line,
+ (uint32_t)m_op2.file_idx);
+ break;
+
+ case DW_MACINFO_end_file:
+ break;
}
+ } else {
+ s->PutCString(" END\n");
+ }
}
+bool DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor &mac_info_data,
+ lldb::offset_t *offset_ptr) {
+ if (mac_info_data.ValidOffset(*offset_ptr)) {
+ m_type_code = mac_info_data.GetU8(offset_ptr);
+
+ switch (m_type_code) {
+
+ case DW_MACINFO_define:
+ case DW_MACINFO_undef:
+ // 2 operands:
+ // Arg 1: operand encodes the line number of the source line on which
+ // the relevant defining or undefining pre-processor directives
+ // appeared.
+ m_line = mac_info_data.GetULEB128(offset_ptr);
+ // Arg 2: define string
+ m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
+ break;
+
+ case DW_MACINFO_start_file:
+ // 2 operands:
+ // Op 1: line number of the source line on which the inclusion
+ // pre-processor directive occurred.
+ m_line = mac_info_data.GetULEB128(offset_ptr);
+ // Op 2: a source file name index to a file number in the statement
+ // information table for the relevant compilation unit.
+ m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr);
+ break;
-bool
-DWARFDebugMacinfoEntry::Extract(const DWARFDataExtractor& mac_info_data, lldb::offset_t* offset_ptr)
-{
- if (mac_info_data.ValidOffset(*offset_ptr))
- {
- m_type_code = mac_info_data.GetU8(offset_ptr);
-
- switch (m_type_code)
- {
-
- case DW_MACINFO_define:
- case DW_MACINFO_undef:
- // 2 operands:
- // Arg 1: operand encodes the line number of the source line on which
- // the relevant defining or undefining pre-processor directives
- // appeared.
- m_line = mac_info_data.GetULEB128(offset_ptr);
- // Arg 2: define string
- m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
- break;
-
- case DW_MACINFO_start_file:
- // 2 operands:
- // Op 1: line number of the source line on which the inclusion
- // pre-processor directive occurred.
- m_line = mac_info_data.GetULEB128(offset_ptr);
- // Op 2: a source file name index to a file number in the statement
- // information table for the relevant compilation unit.
- m_op2.file_idx = mac_info_data.GetULEB128(offset_ptr);
- break;
-
- case 0: // End of list
- case DW_MACINFO_end_file:
- // No operands
- m_line = DW_INVALID_OFFSET;
- m_op2.cstr = NULL;
- break;
- default:
- // Vendor specific entries always have a ULEB128 and a string
- m_line = mac_info_data.GetULEB128(offset_ptr);
- m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
- break;
- }
- return true;
+ case 0: // End of list
+ case DW_MACINFO_end_file:
+ // No operands
+ m_line = DW_INVALID_OFFSET;
+ m_op2.cstr = NULL;
+ break;
+ default:
+ // Vendor specific entries always have a ULEB128 and a string
+ m_line = mac_info_data.GetULEB128(offset_ptr);
+ m_op2.cstr = mac_info_data.GetCStr(offset_ptr);
+ break;
}
- else
- m_type_code = 0;
+ return true;
+ } else
+ m_type_code = 0;
- return false;
+ return false;
}
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h Tue Sep 6 15:57:50 2016
@@ -12,46 +12,31 @@
#include "SymbolFileDWARF.h"
-class DWARFDebugMacinfoEntry
-{
+class DWARFDebugMacinfoEntry {
public:
- DWARFDebugMacinfoEntry();
+ DWARFDebugMacinfoEntry();
- ~DWARFDebugMacinfoEntry();
+ ~DWARFDebugMacinfoEntry();
- uint8_t
- TypeCode() const
- {
- return m_type_code;
- }
-
- uint8_t
- GetLineNumber() const
- {
- return m_line;
- }
-
- void
- Dump(lldb_private::Stream *s) const;
-
- const char*
- GetCString() const;
-
- bool
- Extract(const lldb_private::DWARFDataExtractor& mac_info_data,
- lldb::offset_t* offset_ptr);
+ uint8_t TypeCode() const { return m_type_code; }
-protected:
+ uint8_t GetLineNumber() const { return m_line; }
+
+ void Dump(lldb_private::Stream *s) const;
+
+ const char *GetCString() const;
+ bool Extract(const lldb_private::DWARFDataExtractor &mac_info_data,
+ lldb::offset_t *offset_ptr);
+
+protected:
private:
- uint8_t m_type_code;
- dw_uleb128_t m_line;
- union
- {
- dw_uleb128_t file_idx;
- const char* cstr;
- } m_op2;
+ uint8_t m_type_code;
+ dw_uleb128_t m_line;
+ union {
+ dw_uleb128_t file_idx;
+ const char *cstr;
+ } m_op2;
};
-
-#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfoEntry_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp Tue Sep 6 15:57:50 2016
@@ -17,112 +17,111 @@
using namespace lldb_private;
DWARFDebugMacroHeader
-DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
-{
- DWARFDebugMacroHeader header;
-
- // Skip over the version field in header.
- header.m_version = debug_macro_data.GetU16(offset);
-
- uint8_t flags = debug_macro_data.GetU8(offset);
- header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false;
-
- if (flags & DEBUG_LINE_OFFSET_MASK)
- {
- if (header.m_offset_is_64_bit)
- header.m_debug_line_offset = debug_macro_data.GetU64(offset);
- else
- header.m_debug_line_offset = debug_macro_data.GetU32(offset);
- }
-
- // Skip over the operands table if it is present.
- if (flags & OPCODE_OPERANDS_TABLE_MASK)
- SkipOperandTable(debug_macro_data, offset);
+DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset) {
+ DWARFDebugMacroHeader header;
+
+ // Skip over the version field in header.
+ header.m_version = debug_macro_data.GetU16(offset);
+
+ uint8_t flags = debug_macro_data.GetU8(offset);
+ header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false;
+
+ if (flags & DEBUG_LINE_OFFSET_MASK) {
+ if (header.m_offset_is_64_bit)
+ header.m_debug_line_offset = debug_macro_data.GetU64(offset);
+ else
+ header.m_debug_line_offset = debug_macro_data.GetU32(offset);
+ }
+
+ // Skip over the operands table if it is present.
+ if (flags & OPCODE_OPERANDS_TABLE_MASK)
+ SkipOperandTable(debug_macro_data, offset);
- return header;
+ return header;
}
-void
-DWARFDebugMacroHeader::SkipOperandTable(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
-{
- uint8_t entry_count = debug_macro_data.GetU8(offset);
- for (uint8_t i = 0; i < entry_count; i++)
- {
- // Skip over the opcode number.
- debug_macro_data.GetU8(offset);
-
- uint64_t operand_count = debug_macro_data.GetULEB128(offset);
-
- for (uint64_t j = 0; j < operand_count; j++)
- {
- // Skip over the operand form
- debug_macro_data.GetU8(offset);
- }
+void DWARFDebugMacroHeader::SkipOperandTable(
+ const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
+ uint8_t entry_count = debug_macro_data.GetU8(offset);
+ for (uint8_t i = 0; i < entry_count; i++) {
+ // Skip over the opcode number.
+ debug_macro_data.GetU8(offset);
+
+ uint64_t operand_count = debug_macro_data.GetULEB128(offset);
+
+ for (uint64_t j = 0; j < operand_count; j++) {
+ // Skip over the operand form
+ debug_macro_data.GetU8(offset);
}
+ }
}
-void
-DWARFDebugMacroEntry::ReadMacroEntries(const DWARFDataExtractor &debug_macro_data,
- const DWARFDataExtractor &debug_str_data,
- const bool offset_is_64_bit,
- lldb::offset_t *offset,
- SymbolFileDWARF *sym_file_dwarf,
- DebugMacrosSP &debug_macros_sp)
-{
- llvm::dwarf::MacroEntryType type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
- while (type != 0)
- {
- lldb::offset_t new_offset = 0, str_offset = 0;
- uint32_t line = 0;
- const char *macro_str = nullptr;
- uint32_t debug_line_file_idx = 0;
-
- switch (type)
- {
- case DW_MACRO_define:
- case DW_MACRO_undef:
- line = debug_macro_data.GetULEB128(offset);
- macro_str = debug_macro_data.GetCStr(offset);
- if (type == DW_MACRO_define)
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str));
- else
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str));
- break;
- case DW_MACRO_define_indirect:
- case DW_MACRO_undef_indirect:
- line = debug_macro_data.GetULEB128(offset);
- if (offset_is_64_bit)
- str_offset = debug_macro_data.GetU64(offset);
- else
- str_offset = debug_macro_data.GetU32(offset);
- macro_str = debug_str_data.GetCStr(&str_offset);
- if (type == DW_MACRO_define_indirect)
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str));
- else
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str));
- break;
- case DW_MACRO_start_file:
- line = debug_macro_data.GetULEB128(offset);
- debug_line_file_idx = debug_macro_data.GetULEB128(offset);
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
- break;
- case DW_MACRO_end_file:
- // This operation has no operands.
- debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
- break;
- case DW_MACRO_transparent_include:
- if (offset_is_64_bit)
- new_offset = debug_macro_data.GetU64(offset);
- else
- new_offset = debug_macro_data.GetU32(offset);
- debug_macros_sp->AddMacroEntry(
- DebugMacroEntry::CreateIndirectEntry(sym_file_dwarf->ParseDebugMacros(&new_offset)));
- break;
- default:
- // TODO: Add support for other standard operations.
- // TODO: Provide mechanism to hook handling of non-standard/extension operands.
- return;
- }
- type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
+void DWARFDebugMacroEntry::ReadMacroEntries(
+ const DWARFDataExtractor &debug_macro_data,
+ const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
+ lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
+ DebugMacrosSP &debug_macros_sp) {
+ llvm::dwarf::MacroEntryType type =
+ static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
+ while (type != 0) {
+ lldb::offset_t new_offset = 0, str_offset = 0;
+ uint32_t line = 0;
+ const char *macro_str = nullptr;
+ uint32_t debug_line_file_idx = 0;
+
+ switch (type) {
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ line = debug_macro_data.GetULEB128(offset);
+ macro_str = debug_macro_data.GetCStr(offset);
+ if (type == DW_MACRO_define)
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateDefineEntry(line, macro_str));
+ else
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateUndefEntry(line, macro_str));
+ break;
+ case DW_MACRO_define_indirect:
+ case DW_MACRO_undef_indirect:
+ line = debug_macro_data.GetULEB128(offset);
+ if (offset_is_64_bit)
+ str_offset = debug_macro_data.GetU64(offset);
+ else
+ str_offset = debug_macro_data.GetU32(offset);
+ macro_str = debug_str_data.GetCStr(&str_offset);
+ if (type == DW_MACRO_define_indirect)
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateDefineEntry(line, macro_str));
+ else
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateUndefEntry(line, macro_str));
+ break;
+ case DW_MACRO_start_file:
+ line = debug_macro_data.GetULEB128(offset);
+ debug_line_file_idx = debug_macro_data.GetULEB128(offset);
+ debug_macros_sp->AddMacroEntry(
+ DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
+ break;
+ case DW_MACRO_end_file:
+ // This operation has no operands.
+ debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
+ break;
+ case DW_MACRO_transparent_include:
+ if (offset_is_64_bit)
+ new_offset = debug_macro_data.GetU64(offset);
+ else
+ new_offset = debug_macro_data.GetU32(offset);
+ debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
+ sym_file_dwarf->ParseDebugMacros(&new_offset)));
+ break;
+ default:
+ // TODO: Add support for other standard operations.
+ // TODO: Provide mechanism to hook handling of non-standard/extension
+ // operands.
+ return;
}
+ type = static_cast<llvm::dwarf::MacroEntryType>(
+ debug_macro_data.GetU8(offset));
+ }
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h Tue Sep 6 15:57:50 2016
@@ -1,4 +1,5 @@
-//===-- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===//
+//===-- DWARFDebugMacro.h ----------------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,12 +13,11 @@
#include <map>
-#include "lldb/lldb-types.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Symbol/DebugMacros.h"
+#include "lldb/lldb-types.h"
-namespace lldb_private
-{
+namespace lldb_private {
class DWARFDataExtractor;
@@ -25,44 +25,38 @@ class DWARFDataExtractor;
class SymbolFileDWARF;
-class DWARFDebugMacroHeader
-{
+class DWARFDebugMacroHeader {
public:
- enum HeaderFlagMask
- {
- OFFSET_SIZE_MASK = 0x1,
- DEBUG_LINE_OFFSET_MASK = 0x2,
- OPCODE_OPERANDS_TABLE_MASK = 0x4
- };
-
- static DWARFDebugMacroHeader
- ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset);
-
- bool
- OffsetIs64Bit() const
- {
- return m_offset_is_64_bit;
- }
+ enum HeaderFlagMask {
+ OFFSET_SIZE_MASK = 0x1,
+ DEBUG_LINE_OFFSET_MASK = 0x2,
+ OPCODE_OPERANDS_TABLE_MASK = 0x4
+ };
+
+ static DWARFDebugMacroHeader
+ ParseHeader(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset);
-private:
- static void
- SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset);
+ bool OffsetIs64Bit() const { return m_offset_is_64_bit; }
- uint16_t m_version;
- bool m_offset_is_64_bit;
- uint64_t m_debug_line_offset;
+private:
+ static void
+ SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ lldb::offset_t *offset);
+
+ uint16_t m_version;
+ bool m_offset_is_64_bit;
+ uint64_t m_debug_line_offset;
};
-class DWARFDebugMacroEntry
-{
+class DWARFDebugMacroEntry {
public:
- static void
- ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data,
- const lldb_private::DWARFDataExtractor &debug_str_data,
- const bool offset_is_64_bit,
- lldb::offset_t *sect_offset,
- SymbolFileDWARF *sym_file_dwarf,
- lldb_private::DebugMacrosSP &debug_macros_sp);
+ static void
+ ReadMacroEntries(const lldb_private::DWARFDataExtractor &debug_macro_data,
+ const lldb_private::DWARFDataExtractor &debug_str_data,
+ const bool offset_is_64_bit, lldb::offset_t *sect_offset,
+ SymbolFileDWARF *sym_file_dwarf,
+ lldb_private::DebugMacrosSP &debug_macros_sp);
};
#endif // SymbolFileDWARF_DWARFDebugMacro_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp Tue Sep 6 15:57:50 2016
@@ -12,268 +12,242 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
-#include "DWARFDebugInfo.h"
+#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
+#include "DWARFDebugInfo.h"
#include "DWARFFormValue.h"
-#include "DWARFCompileUnit.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
-
using namespace lldb;
using namespace lldb_private;
-DWARFDebugPubnames::DWARFDebugPubnames() :
- m_sets()
-{
-}
-
-bool
-DWARFDebugPubnames::Extract(const DWARFDataExtractor& data)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
- (uint64_t)data.GetByteSize());
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
- if (log)
- log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", (uint64_t)data.GetByteSize());
+DWARFDebugPubnames::DWARFDebugPubnames() : m_sets() {}
- if (data.ValidOffset(0))
- {
- lldb::offset_t offset = 0;
-
- DWARFDebugPubnamesSet set;
- while (data.ValidOffset(offset))
- {
- if (set.Extract(data, &offset))
- {
- m_sets.push_back(set);
- offset = set.GetOffsetOfNextEntry();
- }
- else
- break;
- }
- if (log)
- Dump (log);
- return true;
+bool DWARFDebugPubnames::Extract(const DWARFDataExtractor &data) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
+ (uint64_t)data.GetByteSize());
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
+ if (log)
+ log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
+ (uint64_t)data.GetByteSize());
+
+ if (data.ValidOffset(0)) {
+ lldb::offset_t offset = 0;
+
+ DWARFDebugPubnamesSet set;
+ while (data.ValidOffset(offset)) {
+ if (set.Extract(data, &offset)) {
+ m_sets.push_back(set);
+ offset = set.GetOffsetOfNextEntry();
+ } else
+ break;
}
- return false;
-}
-
-
-bool
-DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "DWARFDebugPubnames::GeneratePubnames (data = %p)",
- static_cast<void*>(dwarf2Data));
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
if (log)
- log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)",
- static_cast<void*>(dwarf2Data));
-
- m_sets.clear();
- DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
-
- DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(),
- cu->IsDWARF64());
-
- bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
-
- DWARFDIECollection dies;
- const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_subprogram, dies) +
- cu->AppendDIEsWithTag (DW_TAG_variable, dies);
-
- dw_offset_t cu_offset = cu->GetOffset();
- DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);
-
- size_t die_idx;
- for (die_idx = 0; die_idx < die_count; ++die_idx)
- {
- DWARFDIE die = dies.GetDIEAtIndex(die_idx);
- DWARFAttributes attributes;
- const char *name = NULL;
- const char *mangled = NULL;
- bool add_die = false;
- const size_t num_attributes = die.GetDIE()->GetAttributes(die.GetCU(), fixed_form_sizes, attributes);
- if (num_attributes > 0)
- {
- uint32_t i;
-
- dw_tag_t tag = die.Tag();
-
- for (i=0; i<num_attributes; ++i)
- {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- switch (attr)
- {
- case DW_AT_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- name = form_value.AsCString();
- break;
-
- case DW_AT_MIPS_linkage_name:
- case DW_AT_linkage_name:
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- mangled = form_value.AsCString();
- break;
-
- case DW_AT_low_pc:
- case DW_AT_ranges:
- case DW_AT_entry_pc:
- if (tag == DW_TAG_subprogram)
- add_die = true;
- break;
-
- case DW_AT_location:
- if (tag == DW_TAG_variable)
- {
- DWARFDIE parent_die = die.GetParent();
- while ( parent_die )
- {
- switch (parent_die.Tag())
- {
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- case DW_TAG_inlined_subroutine:
- // Even if this is a function level static, we don't add it. We could theoretically
- // add these if we wanted to by introspecting into the DW_AT_location and seeing
- // if the location describes a hard coded address, but we don't want the performance
- // penalty of that right now.
- add_die = false;
- parent_die.Clear(); // Terminate the while loop.
- break;
-
- case DW_TAG_compile_unit:
- add_die = true;
- parent_die.Clear(); // Terminate the while loop.
- break;
-
- default:
- parent_die = parent_die.GetParent(); // Keep going in the while loop.
- break;
- }
- }
- }
- break;
- }
- }
- }
-
- if (add_die && (name || mangled))
- {
- pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), mangled ? mangled : name);
- }
- }
-
- if (pubnames_set.NumDescriptors() > 0)
- {
- m_sets.push_back(pubnames_set);
- }
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed
- if (clear_dies)
- cu->ClearDIEs (true);
- }
- }
- if (m_sets.empty())
- return false;
- if (log)
- Dump (log);
+ Dump(log);
return true;
+ }
+ return false;
}
-bool
-DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data)
-{
- m_sets.clear();
- DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx = 0;
- const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
- for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- DWARFDIECollection dies;
- const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_base_type, dies);
- dw_offset_t cu_offset = cu->GetOffset();
- DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);
-
- size_t die_idx;
- for (die_idx = 0; die_idx < die_count; ++die_idx)
- {
- DWARFDIE die = dies.GetDIEAtIndex (die_idx);
- const char *name = die.GetName();
-
- if (name)
- pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name);
- }
-
- if (pubnames_set.NumDescriptors() > 0)
- {
- m_sets.push_back(pubnames_set);
+bool DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF *dwarf2Data) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "DWARFDebugPubnames::GeneratePubnames (data = %p)",
+ static_cast<void *>(dwarf2Data));
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
+ if (log)
+ log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)",
+ static_cast<void *>(dwarf2Data));
+
+ m_sets.clear();
+ DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx = 0;
+ const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+ for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+
+ DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(
+ cu->GetAddressByteSize(), cu->IsDWARF64());
+
+ bool clear_dies = cu->ExtractDIEsIfNeeded(false) > 1;
+
+ DWARFDIECollection dies;
+ const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_subprogram, dies) +
+ cu->AppendDIEsWithTag(DW_TAG_variable, dies);
+
+ dw_offset_t cu_offset = cu->GetOffset();
+ DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset,
+ cu->GetNextCompileUnitOffset() -
+ cu_offset);
+
+ size_t die_idx;
+ for (die_idx = 0; die_idx < die_count; ++die_idx) {
+ DWARFDIE die = dies.GetDIEAtIndex(die_idx);
+ DWARFAttributes attributes;
+ const char *name = NULL;
+ const char *mangled = NULL;
+ bool add_die = false;
+ const size_t num_attributes = die.GetDIE()->GetAttributes(
+ die.GetCU(), fixed_form_sizes, attributes);
+ if (num_attributes > 0) {
+ uint32_t i;
+
+ dw_tag_t tag = die.Tag();
+
+ for (i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ switch (attr) {
+ case DW_AT_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ name = form_value.AsCString();
+ break;
+
+ case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
+ if (attributes.ExtractFormValueAtIndex(i, form_value))
+ mangled = form_value.AsCString();
+ break;
+
+ case DW_AT_low_pc:
+ case DW_AT_ranges:
+ case DW_AT_entry_pc:
+ if (tag == DW_TAG_subprogram)
+ add_die = true;
+ break;
+
+ case DW_AT_location:
+ if (tag == DW_TAG_variable) {
+ DWARFDIE parent_die = die.GetParent();
+ while (parent_die) {
+ switch (parent_die.Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block:
+ case DW_TAG_inlined_subroutine:
+ // Even if this is a function level static, we don't add it.
+ // We could theoretically
+ // add these if we wanted to by introspecting into the
+ // DW_AT_location and seeing
+ // if the location describes a hard coded address, but we
+ // don't want the performance
+ // penalty of that right now.
+ add_die = false;
+ parent_die.Clear(); // Terminate the while loop.
+ break;
+
+ case DW_TAG_compile_unit:
+ add_die = true;
+ parent_die.Clear(); // Terminate the while loop.
+ break;
+
+ default:
+ parent_die =
+ parent_die.GetParent(); // Keep going in the while loop.
+ break;
+ }
+ }
+ }
+ break;
}
+ }
}
- }
- return !m_sets.empty();
-}
-void
-DWARFDebugPubnames::Dump(Log *s) const
-{
- if (m_sets.empty())
- s->PutCString("< EMPTY >\n");
- else
- {
- const_iterator pos;
- const_iterator end = m_sets.end();
+ if (add_die && (name || mangled)) {
+ pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(),
+ mangled ? mangled : name);
+ }
+ }
- for (pos = m_sets.begin(); pos != end; ++pos)
- (*pos).Dump(s);
+ if (pubnames_set.NumDescriptors() > 0) {
+ m_sets.push_back(pubnames_set);
+ }
+
+ // Keep memory down by clearing DIEs if this generate function
+ // caused them to be parsed
+ if (clear_dies)
+ cu->ClearDIEs(true);
}
-}
-
-bool
-DWARFDebugPubnames::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const
-{
+ }
+ if (m_sets.empty())
+ return false;
+ if (log)
+ Dump(log);
+ return true;
+}
+
+bool DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data) {
+ m_sets.clear();
+ DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx = 0;
+ const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
+ for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ DWARFDIECollection dies;
+ const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_base_type, dies);
+ dw_offset_t cu_offset = cu->GetOffset();
+ DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset,
+ cu->GetNextCompileUnitOffset() -
+ cu_offset);
+
+ size_t die_idx;
+ for (die_idx = 0; die_idx < die_count; ++die_idx) {
+ DWARFDIE die = dies.GetDIEAtIndex(die_idx);
+ const char *name = die.GetName();
+
+ if (name)
+ pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name);
+ }
+
+ if (pubnames_set.NumDescriptors() > 0) {
+ m_sets.push_back(pubnames_set);
+ }
+ }
+ }
+ return !m_sets.empty();
+}
+
+void DWARFDebugPubnames::Dump(Log *s) const {
+ if (m_sets.empty())
+ s->PutCString("< EMPTY >\n");
+ else {
const_iterator pos;
const_iterator end = m_sets.end();
- die_offsets.clear();
-
for (pos = m_sets.begin(); pos != end; ++pos)
- {
- (*pos).Find(name, ignore_case, die_offsets);
- }
+ (*pos).Dump(s);
+ }
+}
+
+bool DWARFDebugPubnames::Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offsets) const {
+ const_iterator pos;
+ const_iterator end = m_sets.end();
+
+ die_offsets.clear();
- return !die_offsets.empty();
+ for (pos = m_sets.begin(); pos != end; ++pos) {
+ (*pos).Find(name, ignore_case, die_offsets);
+ }
+
+ return !die_offsets.empty();
}
-bool
-DWARFDebugPubnames::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const
-{
- const_iterator pos;
- const_iterator end = m_sets.end();
+bool DWARFDebugPubnames::Find(const RegularExpression ®ex,
+ std::vector<dw_offset_t> &die_offsets) const {
+ const_iterator pos;
+ const_iterator end = m_sets.end();
- die_offsets.clear();
+ die_offsets.clear();
- for (pos = m_sets.begin(); pos != end; ++pos)
- {
- (*pos).Find(regex, die_offsets);
- }
+ for (pos = m_sets.begin(); pos != end; ++pos) {
+ (*pos).Find(regex, die_offsets);
+ }
- return !die_offsets.empty();
+ return !die_offsets.empty();
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h Tue Sep 6 15:57:50 2016
@@ -16,23 +16,25 @@
#include "DWARFDebugPubnamesSet.h"
-class DWARFDebugPubnames
-{
+class DWARFDebugPubnames {
public:
- DWARFDebugPubnames();
- bool Extract(const lldb_private::DWARFDataExtractor& data);
- bool GeneratePubnames(SymbolFileDWARF* dwarf2Data);
- bool GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data);
-
- void Dump(lldb_private::Log *s) const;
- bool Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
- bool Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const;
+ DWARFDebugPubnames();
+ bool Extract(const lldb_private::DWARFDataExtractor &data);
+ bool GeneratePubnames(SymbolFileDWARF *dwarf2Data);
+ bool GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data);
+
+ void Dump(lldb_private::Log *s) const;
+ bool Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offset_coll) const;
+ bool Find(const lldb_private::RegularExpression ®ex,
+ std::vector<dw_offset_t> &die_offsets) const;
+
protected:
- typedef std::list<DWARFDebugPubnamesSet> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
+ typedef std::list<DWARFDebugPubnamesSet> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
- collection m_sets;
+ collection m_sets;
};
-#endif // SymbolFileDWARF_DWARFDebugPubnames_h_
+#endif // SymbolFileDWARF_DWARFDebugPubnames_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp Tue Sep 6 15:57:50 2016
@@ -9,158 +9,138 @@
#include "DWARFDebugPubnamesSet.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/RegularExpression.h"
#include "SymbolFileDWARF.h"
using namespace lldb_private;
-DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
- m_offset(DW_INVALID_OFFSET),
- m_header(),
- m_descriptors(),
- m_name_to_descriptor_index()
-{
-}
-
-DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
- m_offset(debug_aranges_offset),
- m_header(),
- m_descriptors(),
- m_name_to_descriptor_index()
-{
- m_header.length = 10; // set the length to only include the header right for now
- m_header.version = 2; // The DWARF version number
- m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
- m_header.die_length = cu_die_length;// compile unit .debug_info length
-}
-
-void
-DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
-{
- if (name && name[0])
- {
- // Adjust our header length
- m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
- Descriptor pubnameDesc(cu_rel_offset, name);
- m_descriptors.push_back(pubnameDesc);
- }
-}
-
-void
-DWARFDebugPubnamesSet::Clear()
-{
- m_offset = DW_INVALID_OFFSET;
- m_header.length = 10;
- m_header.version = 2;
- m_header.die_offset = DW_INVALID_OFFSET;
- m_header.die_length = 0;
- m_descriptors.clear();
+DWARFDebugPubnamesSet::DWARFDebugPubnamesSet()
+ : m_offset(DW_INVALID_OFFSET), m_header(), m_descriptors(),
+ m_name_to_descriptor_index() {}
+
+DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
+ dw_offset_t cu_die_offset,
+ dw_offset_t cu_die_length)
+ : m_offset(debug_aranges_offset), m_header(), m_descriptors(),
+ m_name_to_descriptor_index() {
+ m_header.length =
+ 10; // set the length to only include the header right for now
+ m_header.version = 2; // The DWARF version number
+ m_header.die_offset = cu_die_offset; // compile unit .debug_info offset
+ m_header.die_length = cu_die_length; // compile unit .debug_info length
+}
+
+void DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset,
+ const char *name) {
+ if (name && name[0]) {
+ // Adjust our header length
+ m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
+ Descriptor pubnameDesc(cu_rel_offset, name);
+ m_descriptors.push_back(pubnameDesc);
+ }
+}
+
+void DWARFDebugPubnamesSet::Clear() {
+ m_offset = DW_INVALID_OFFSET;
+ m_header.length = 10;
+ m_header.version = 2;
+ m_header.die_offset = DW_INVALID_OFFSET;
+ m_header.die_length = 0;
+ m_descriptors.clear();
}
-
//----------------------------------------------------------------------
// InitNameIndexes
//----------------------------------------------------------------------
-void
-DWARFDebugPubnamesSet::InitNameIndexes() const
-{
- // Create the name index vector to be able to quickly search by name
- const size_t count = m_descriptors.size();
- for (uint32_t idx = 0; idx < count; ++idx)
- {
- const char* name = m_descriptors[idx].name.c_str();
- if (name && name[0])
- m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
- }
+void DWARFDebugPubnamesSet::InitNameIndexes() const {
+ // Create the name index vector to be able to quickly search by name
+ const size_t count = m_descriptors.size();
+ for (uint32_t idx = 0; idx < count; ++idx) {
+ const char *name = m_descriptors[idx].name.c_str();
+ if (name && name[0])
+ m_name_to_descriptor_index.insert(
+ cstr_to_index_mmap::value_type(name, idx));
+ }
}
-
-bool
-DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr)
-{
- if (data.ValidOffset(*offset_ptr))
- {
- m_descriptors.clear();
- m_offset = *offset_ptr;
- m_header.length = data.GetDWARFInitialLength(offset_ptr);
- m_header.version = data.GetU16(offset_ptr);
- m_header.die_offset = data.GetDWARFOffset(offset_ptr);
- m_header.die_length = data.GetDWARFOffset(offset_ptr);
-
- Descriptor pubnameDesc;
- while (data.ValidOffset(*offset_ptr))
- {
- pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
-
- if (pubnameDesc.offset)
- {
- const char* name = data.GetCStr(offset_ptr);
- if (name && name[0])
- {
- pubnameDesc.name = name;
- m_descriptors.push_back(pubnameDesc);
- }
- }
- else
- break; // We are done if we get a zero 4 byte offset
+bool DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ if (data.ValidOffset(*offset_ptr)) {
+ m_descriptors.clear();
+ m_offset = *offset_ptr;
+ m_header.length = data.GetDWARFInitialLength(offset_ptr);
+ m_header.version = data.GetU16(offset_ptr);
+ m_header.die_offset = data.GetDWARFOffset(offset_ptr);
+ m_header.die_length = data.GetDWARFOffset(offset_ptr);
+
+ Descriptor pubnameDesc;
+ while (data.ValidOffset(*offset_ptr)) {
+ pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
+
+ if (pubnameDesc.offset) {
+ const char *name = data.GetCStr(offset_ptr);
+ if (name && name[0]) {
+ pubnameDesc.name = name;
+ m_descriptors.push_back(pubnameDesc);
}
-
- return !m_descriptors.empty();
- }
- return false;
-}
-
-dw_offset_t
-DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
-{
- return m_offset + m_header.length + 4;
-}
-
-void
-DWARFDebugPubnamesSet::Dump(Log *log) const
-{
- log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
- m_header.length,
- m_header.version,
- m_header.die_offset,
- m_header.die_length);
-
- bool verbose = log->GetVerbose();
-
- DescriptorConstIter pos;
- DescriptorConstIter end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; ++pos)
- {
- if (verbose)
- log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str());
- else
- log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
+ } else
+ break; // We are done if we get a zero 4 byte offset
}
-}
-
-void
-DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
-{
- if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
- InitNameIndexes();
-
- std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
- for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
- die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
-}
-
-void
-DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
-{
- DescriptorConstIter pos;
- DescriptorConstIter end = m_descriptors.end();
- for (pos = m_descriptors.begin(); pos != end; ++pos)
- {
- if ( regex.Execute(pos->name.c_str()) )
- die_offset_coll.push_back(m_header.die_offset + pos->offset);
- }
+ return !m_descriptors.empty();
+ }
+ return false;
+}
+
+dw_offset_t DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const {
+ return m_offset + m_header.length + 4;
+}
+
+void DWARFDebugPubnamesSet::Dump(Log *log) const {
+ log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, "
+ "die_offset = 0x%8.8x, die_length = 0x%8.8x",
+ m_header.length, m_header.version, m_header.die_offset,
+ m_header.die_length);
+
+ bool verbose = log->GetVerbose();
+
+ DescriptorConstIter pos;
+ DescriptorConstIter end = m_descriptors.end();
+ for (pos = m_descriptors.begin(); pos != end; ++pos) {
+ if (verbose)
+ log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset,
+ m_header.die_offset, pos->offset + m_header.die_offset,
+ pos->name.c_str());
+ else
+ log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset,
+ pos->name.c_str());
+ }
+}
+
+void DWARFDebugPubnamesSet::Find(
+ const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offset_coll) const {
+ if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
+ InitNameIndexes();
+
+ std::pair<cstr_to_index_mmap::const_iterator,
+ cstr_to_index_mmap::const_iterator>
+ range(m_name_to_descriptor_index.equal_range(name));
+ for (cstr_to_index_mmap::const_iterator pos = range.first;
+ pos != range.second; ++pos)
+ die_offset_coll.push_back(m_header.die_offset +
+ m_descriptors[(*pos).second].offset);
+}
+
+void DWARFDebugPubnamesSet::Find(
+ const RegularExpression ®ex,
+ std::vector<dw_offset_t> &die_offset_coll) const {
+ DescriptorConstIter pos;
+ DescriptorConstIter end = m_descriptors.end();
+ for (pos = m_descriptors.begin(); pos != end; ++pos) {
+ if (regex.Execute(pos->name.c_str()))
+ die_offset_coll.push_back(m_header.die_offset + pos->offset);
+ }
}
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h Tue Sep 6 15:57:50 2016
@@ -19,81 +19,74 @@
#include <ext/hash_map>
#endif
-class DWARFDebugPubnamesSet
-{
+class DWARFDebugPubnamesSet {
public:
- struct Header
- {
- uint32_t length; // length of the set of entries for this compilation unit, not including the length field itself
- uint16_t version; // The DWARF version number
- uint32_t die_offset; // compile unit .debug_info offset
- uint32_t die_length; // compile unit .debug_info length
- Header() :
- length(10),
- version(2),
- die_offset(DW_INVALID_OFFSET),
- die_length(0)
- {
- }
- };
-
- struct Descriptor
- {
- Descriptor() :
- offset(),
- name()
- {
- }
-
- Descriptor(dw_offset_t the_offset, const char *the_name) :
- offset(the_offset),
- name(the_name ? the_name : "")
- {
- }
-
- dw_offset_t offset;
- std::string name;
- };
-
- DWARFDebugPubnamesSet();
- DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t die_length);
- dw_offset_t GetOffset() const { return m_offset; }
- void SetOffset(dw_offset_t offset) { m_offset = offset; }
- DWARFDebugPubnamesSet::Header& GetHeader() { return m_header; }
- const DWARFDebugPubnamesSet::Header& GetHeader() const { return m_header; }
- const DWARFDebugPubnamesSet::Descriptor* GetDescriptor(uint32_t i) const
- {
- if (i < m_descriptors.size())
- return &m_descriptors[i];
- return NULL;
- }
- uint32_t NumDescriptors() const { return m_descriptors.size(); }
- void AddDescriptor(dw_offset_t cu_rel_offset, const char* name);
- void Clear();
- bool Extract(const lldb_private::DWARFDataExtractor& debug_pubnames_data, lldb::offset_t *offset_ptr);
- void Dump(lldb_private::Log *s) const;
- void InitNameIndexes() const;
- void Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
- void Find(const lldb_private::RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const;
- dw_offset_t GetOffsetOfNextEntry() const;
-
-
+ struct Header {
+ uint32_t length; // length of the set of entries for this compilation unit,
+ // not including the length field itself
+ uint16_t version; // The DWARF version number
+ uint32_t die_offset; // compile unit .debug_info offset
+ uint32_t die_length; // compile unit .debug_info length
+ Header()
+ : length(10), version(2), die_offset(DW_INVALID_OFFSET), die_length(0) {
+ }
+ };
+
+ struct Descriptor {
+ Descriptor() : offset(), name() {}
+
+ Descriptor(dw_offset_t the_offset, const char *the_name)
+ : offset(the_offset), name(the_name ? the_name : "") {}
+
+ dw_offset_t offset;
+ std::string name;
+ };
+
+ DWARFDebugPubnamesSet();
+ DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
+ dw_offset_t cu_die_offset, dw_offset_t die_length);
+ dw_offset_t GetOffset() const { return m_offset; }
+ void SetOffset(dw_offset_t offset) { m_offset = offset; }
+ DWARFDebugPubnamesSet::Header &GetHeader() { return m_header; }
+ const DWARFDebugPubnamesSet::Header &GetHeader() const { return m_header; }
+ const DWARFDebugPubnamesSet::Descriptor *GetDescriptor(uint32_t i) const {
+ if (i < m_descriptors.size())
+ return &m_descriptors[i];
+ return NULL;
+ }
+ uint32_t NumDescriptors() const { return m_descriptors.size(); }
+ void AddDescriptor(dw_offset_t cu_rel_offset, const char *name);
+ void Clear();
+ bool Extract(const lldb_private::DWARFDataExtractor &debug_pubnames_data,
+ lldb::offset_t *offset_ptr);
+ void Dump(lldb_private::Log *s) const;
+ void InitNameIndexes() const;
+ void Find(const char *name, bool ignore_case,
+ std::vector<dw_offset_t> &die_offset_coll) const;
+ void Find(const lldb_private::RegularExpression ®ex,
+ std::vector<dw_offset_t> &die_offsets) const;
+ dw_offset_t GetOffsetOfNextEntry() const;
protected:
- typedef std::vector<Descriptor> DescriptorColl;
- typedef DescriptorColl::iterator DescriptorIter;
- typedef DescriptorColl::const_iterator DescriptorConstIter;
-
+ typedef std::vector<Descriptor> DescriptorColl;
+ typedef DescriptorColl::iterator DescriptorIter;
+ typedef DescriptorColl::const_iterator DescriptorConstIter;
- dw_offset_t m_offset;
- Header m_header;
+ dw_offset_t m_offset;
+ Header m_header;
#if __cplusplus >= 201103L || defined(_MSC_VER)
- typedef std::unordered_multimap<const char*, uint32_t, std::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap;
+ typedef std::unordered_multimap<const char *, uint32_t,
+ std::hash<const char *>,
+ CStringEqualBinaryPredicate>
+ cstr_to_index_mmap;
#else
- typedef __gnu_cxx::hash_multimap<const char*, uint32_t, __gnu_cxx::hash<const char*>, CStringEqualBinaryPredicate> cstr_to_index_mmap;
+ typedef __gnu_cxx::hash_multimap<const char *, uint32_t,
+ __gnu_cxx::hash<const char *>,
+ CStringEqualBinaryPredicate>
+ cstr_to_index_mmap;
#endif
- DescriptorColl m_descriptors;
- mutable cstr_to_index_mmap m_name_to_descriptor_index;
+ DescriptorColl m_descriptors;
+ mutable cstr_to_index_mmap m_name_to_descriptor_index;
};
-#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_
+#endif // SymbolFileDWARF_DWARFDebugPubnamesSet_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp Tue Sep 6 15:57:50 2016
@@ -15,135 +15,115 @@
using namespace lldb_private;
using namespace std;
-DWARFDebugRanges::DWARFDebugRanges() :
- m_range_map()
-{
-}
+DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
-DWARFDebugRanges::~DWARFDebugRanges()
-{
-}
+DWARFDebugRanges::~DWARFDebugRanges() {}
-void
-DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
-{
- DWARFRangeList range_list;
- lldb::offset_t offset = 0;
- dw_offset_t debug_ranges_offset = offset;
- while (Extract(dwarf2Data, &offset, range_list))
- {
- range_list.Sort();
- m_range_map[debug_ranges_offset] = range_list;
- debug_ranges_offset = offset;
+void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) {
+ DWARFRangeList range_list;
+ lldb::offset_t offset = 0;
+ dw_offset_t debug_ranges_offset = offset;
+ while (Extract(dwarf2Data, &offset, range_list)) {
+ range_list.Sort();
+ m_range_map[debug_ranges_offset] = range_list;
+ debug_ranges_offset = offset;
+ }
+}
+
+bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
+ lldb::offset_t *offset_ptr,
+ DWARFRangeList &range_list) {
+ range_list.Clear();
+
+ lldb::offset_t range_offset = *offset_ptr;
+ const DWARFDataExtractor &debug_ranges_data =
+ dwarf2Data->get_debug_ranges_data();
+ uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
+
+ while (
+ debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
+ dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ if (!begin && !end) {
+ // End of range list
+ break;
}
-}
-
-bool
-DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, DWARFRangeList &range_list)
-{
- range_list.Clear();
-
- lldb::offset_t range_offset = *offset_ptr;
- const DWARFDataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
- uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
-
- while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
- {
- dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- if (!begin && !end)
- {
- // End of range list
- break;
- }
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
- switch (addr_size)
- {
- case 2:
- if (begin == 0xFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
-
- case 4:
- if (begin == 0xFFFFFFFFull)
- begin = LLDB_INVALID_ADDRESS;
- break;
-
- case 8:
- break;
-
- default:
- assert(!"DWARFRangeList::Extract() unsupported address size.");
- break;
- }
-
- // Filter out empty ranges
- if (begin < end)
- range_list.Append(DWARFRangeList::Entry(begin, end - begin));
+ // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
+ // of ones
+ switch (addr_size) {
+ case 2:
+ if (begin == 0xFFFFull)
+ begin = LLDB_INVALID_ADDRESS;
+ break;
+
+ case 4:
+ if (begin == 0xFFFFFFFFull)
+ begin = LLDB_INVALID_ADDRESS;
+ break;
+
+ case 8:
+ break;
+
+ default:
+ assert(!"DWARFRangeList::Extract() unsupported address size.");
+ break;
}
- // Make sure we consumed at least something
- return range_offset != *offset_ptr;
-}
-
+ // Filter out empty ranges
+ if (begin < end)
+ range_list.Append(DWARFRangeList::Entry(begin, end - begin));
+ }
+
+ // Make sure we consumed at least something
+ return range_offset != *offset_ptr;
+}
+
+void DWARFDebugRanges::Dump(Stream &s,
+ const DWARFDataExtractor &debug_ranges_data,
+ lldb::offset_t *offset_ptr,
+ dw_addr_t cu_base_addr) {
+ uint32_t addr_size = s.GetAddressByteSize();
+ bool verbose = s.GetVerbose();
+
+ dw_addr_t base_addr = cu_base_addr;
+ while (
+ debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) {
+ dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
+ // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
+ // of ones
+ if (begin == 0xFFFFFFFFull && addr_size == 4)
+ begin = LLDB_INVALID_ADDRESS;
+
+ s.Indent();
+ if (verbose) {
+ s.AddressRange(begin, end, sizeof(dw_addr_t), " offsets = ");
+ }
-void
-DWARFDebugRanges::Dump(Stream &s, const DWARFDataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
-{
- uint32_t addr_size = s.GetAddressByteSize();
- bool verbose = s.GetVerbose();
-
- dw_addr_t base_addr = cu_base_addr;
- while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
- {
- dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
- // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
- // of ones
- if (begin == 0xFFFFFFFFull && addr_size == 4)
- begin = LLDB_INVALID_ADDRESS;
-
- s.Indent();
- if (verbose)
- {
- s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = ");
- }
-
-
- if (begin == 0 && end == 0)
- {
- s.PutCString(" End");
- break;
- }
- else if (begin == LLDB_INVALID_ADDRESS)
- {
- // A base address selection entry
- base_addr = end;
- s.Address(base_addr, sizeof (dw_addr_t), " Base address = ");
- }
- else
- {
- // Convert from offset to an address
- dw_addr_t begin_addr = begin + base_addr;
- dw_addr_t end_addr = end + base_addr;
+ if (begin == 0 && end == 0) {
+ s.PutCString(" End");
+ break;
+ } else if (begin == LLDB_INVALID_ADDRESS) {
+ // A base address selection entry
+ base_addr = end;
+ s.Address(base_addr, sizeof(dw_addr_t), " Base address = ");
+ } else {
+ // Convert from offset to an address
+ dw_addr_t begin_addr = begin + base_addr;
+ dw_addr_t end_addr = end + base_addr;
- s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL);
- }
+ s.AddressRange(begin_addr, end_addr, sizeof(dw_addr_t),
+ verbose ? " ==> addrs = " : NULL);
}
+ }
}
-bool
-DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, DWARFRangeList& range_list) const
-{
- range_map_const_iterator pos = m_range_map.find(debug_ranges_offset);
- if (pos != m_range_map.end())
- {
- range_list = pos->second;
- return true;
- }
- return false;
+bool DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const {
+ range_map_const_iterator pos = m_range_map.find(debug_ranges_offset);
+ if (pos != m_range_map.end()) {
+ range_list = pos->second;
+ return true;
+ }
+ return false;
}
-
-
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h Tue Sep 6 15:57:50 2016
@@ -10,33 +10,30 @@
#ifndef SymbolFileDWARF_DWARFDebugRanges_h_
#define SymbolFileDWARF_DWARFDebugRanges_h_
-#include "SymbolFileDWARF.h"
#include "DWARFDIE.h"
+#include "SymbolFileDWARF.h"
#include <map>
-class DWARFDebugRanges
-{
+class DWARFDebugRanges {
public:
-
- DWARFDebugRanges();
- ~DWARFDebugRanges();
- void Extract(SymbolFileDWARF* dwarf2Data);
- static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
- bool FindRanges(dw_offset_t debug_ranges_offset, DWARFRangeList& range_list) const;
+ DWARFDebugRanges();
+ ~DWARFDebugRanges();
+ void Extract(SymbolFileDWARF *dwarf2Data);
+ static void Dump(lldb_private::Stream &s,
+ const lldb_private::DWARFDataExtractor &debug_ranges_data,
+ lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
+ bool FindRanges(dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const;
protected:
+ bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr,
+ DWARFRangeList &range_list);
- bool
- Extract (SymbolFileDWARF* dwarf2Data,
- lldb::offset_t *offset_ptr,
- DWARFRangeList &range_list);
-
- typedef std::map<dw_offset_t, DWARFRangeList> range_map;
- typedef range_map::iterator range_map_iterator;
- typedef range_map::const_iterator range_map_const_iterator;
- range_map m_range_map;
+ typedef std::map<dw_offset_t, DWARFRangeList> range_map;
+ typedef range_map::iterator range_map_iterator;
+ typedef range_map::const_iterator range_map_const_iterator;
+ range_map m_range_map;
};
-
-#endif // SymbolFileDWARF_DWARFDebugRanges_h_
+#endif // SymbolFileDWARF_DWARFDebugRanges_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp Tue Sep 6 15:57:50 2016
@@ -9,96 +9,80 @@
#include "DWARFDeclContext.h"
-const char *
-DWARFDeclContext::GetQualifiedName () const
-{
- if (m_qualified_name.empty())
- {
- // The declaration context array for a class named "foo" in namespace
- // "a::b::c" will be something like:
- // [0] DW_TAG_class_type "foo"
- // [1] DW_TAG_namespace "c"
- // [2] DW_TAG_namespace "b"
- // [3] DW_TAG_namespace "a"
- if (!m_entries.empty())
- {
- if (m_entries.size() == 1)
- {
- if (m_entries[0].name)
- {
- m_qualified_name.append("::");
- m_qualified_name.append(m_entries[0].name);
- }
- }
+const char *DWARFDeclContext::GetQualifiedName() const {
+ if (m_qualified_name.empty()) {
+ // The declaration context array for a class named "foo" in namespace
+ // "a::b::c" will be something like:
+ // [0] DW_TAG_class_type "foo"
+ // [1] DW_TAG_namespace "c"
+ // [2] DW_TAG_namespace "b"
+ // [3] DW_TAG_namespace "a"
+ if (!m_entries.empty()) {
+ if (m_entries.size() == 1) {
+ if (m_entries[0].name) {
+ m_qualified_name.append("::");
+ m_qualified_name.append(m_entries[0].name);
+ }
+ } else {
+ collection::const_reverse_iterator pos;
+ collection::const_reverse_iterator begin = m_entries.rbegin();
+ collection::const_reverse_iterator end = m_entries.rend();
+ for (pos = begin; pos != end; ++pos) {
+ if (pos != begin)
+ m_qualified_name.append("::");
+ if (pos->name == NULL) {
+ if (pos->tag == DW_TAG_namespace)
+ m_qualified_name.append("(anonymous namespace)");
+ else if (pos->tag == DW_TAG_class_type)
+ m_qualified_name.append("(anonymous class)");
+ else if (pos->tag == DW_TAG_structure_type)
+ m_qualified_name.append("(anonymous struct)");
+ else if (pos->tag == DW_TAG_union_type)
+ m_qualified_name.append("(anonymous union)");
else
- {
- collection::const_reverse_iterator pos;
- collection::const_reverse_iterator begin = m_entries.rbegin();
- collection::const_reverse_iterator end = m_entries.rend();
- for (pos = begin; pos != end; ++pos)
- {
- if (pos != begin)
- m_qualified_name.append("::");
- if (pos->name == NULL)
- {
- if (pos->tag == DW_TAG_namespace)
- m_qualified_name.append ("(anonymous namespace)");
- else if (pos->tag == DW_TAG_class_type)
- m_qualified_name.append ("(anonymous class)");
- else if (pos->tag == DW_TAG_structure_type)
- m_qualified_name.append ("(anonymous struct)");
- else if (pos->tag == DW_TAG_union_type)
- m_qualified_name.append ("(anonymous union)");
- else
- m_qualified_name.append ("(anonymous)");
- }
- else
- m_qualified_name.append(pos->name);
- }
- }
+ m_qualified_name.append("(anonymous)");
+ } else
+ m_qualified_name.append(pos->name);
}
+ }
}
- if (m_qualified_name.empty())
- return NULL;
- return m_qualified_name.c_str();
+ }
+ if (m_qualified_name.empty())
+ return NULL;
+ return m_qualified_name.c_str();
}
-
-bool
-DWARFDeclContext::operator==(const DWARFDeclContext& rhs) const
-{
- if (m_entries.size() != rhs.m_entries.size())
- return false;
-
- collection::const_iterator pos;
- collection::const_iterator begin = m_entries.begin();
- collection::const_iterator end = m_entries.end();
-
- collection::const_iterator rhs_pos;
- collection::const_iterator rhs_begin = rhs.m_entries.begin();
- // The two entry arrays have the same size
-
- // First compare the tags before we do expensive name compares
- for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
- {
- if (pos->tag != rhs_pos->tag)
- {
- // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
- // used interchangeably in GCC
- if (pos->tag == DW_TAG_structure_type && rhs_pos->tag == DW_TAG_class_type)
- continue;
- if (pos->tag == DW_TAG_class_type && rhs_pos->tag == DW_TAG_structure_type)
- continue;
- return false;
- }
+bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
+ if (m_entries.size() != rhs.m_entries.size())
+ return false;
+
+ collection::const_iterator pos;
+ collection::const_iterator begin = m_entries.begin();
+ collection::const_iterator end = m_entries.end();
+
+ collection::const_iterator rhs_pos;
+ collection::const_iterator rhs_begin = rhs.m_entries.begin();
+ // The two entry arrays have the same size
+
+ // First compare the tags before we do expensive name compares
+ for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
+ if (pos->tag != rhs_pos->tag) {
+ // Check for DW_TAG_structure_type and DW_TAG_class_type as they are often
+ // used interchangeably in GCC
+ if (pos->tag == DW_TAG_structure_type &&
+ rhs_pos->tag == DW_TAG_class_type)
+ continue;
+ if (pos->tag == DW_TAG_class_type &&
+ rhs_pos->tag == DW_TAG_structure_type)
+ continue;
+ return false;
}
- // The tags all match, now compare the names
- for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
- {
- if (!pos->NameMatches (*rhs_pos))
- return false;
- }
- // All tags and names match
- return true;
+ }
+ // The tags all match, now compare the names
+ for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) {
+ if (!pos->NameMatches(*rhs_pos))
+ return false;
+ }
+ // All tags and names match
+ return true;
}
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h Tue Sep 6 15:57:50 2016
@@ -27,112 +27,69 @@
// in another DWARF file.
//----------------------------------------------------------------------
-class DWARFDeclContext
-{
+class DWARFDeclContext {
public:
- struct Entry
- {
- Entry () :
- tag(0),
- name(NULL)
- {
- }
- Entry (dw_tag_t t, const char *n) :
- tag(t),
- name(n)
- {
- }
-
- bool
- NameMatches (const Entry& rhs) const
- {
- if (name == rhs.name)
- return true;
- else if (name && rhs.name)
- return strcmp(name, rhs.name) == 0;
- return false;
- }
-
- // Test operator
- explicit operator bool() const
- {
- return tag != 0;
- }
-
- dw_tag_t tag;
- const char *name;
- };
-
- DWARFDeclContext () :
- m_entries(),
- m_language(lldb::eLanguageTypeUnknown)
- {
- }
+ struct Entry {
+ Entry() : tag(0), name(NULL) {}
+ Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
- void
- AppendDeclContext (dw_tag_t tag, const char *name)
- {
- m_entries.push_back(Entry(tag, name));
+ bool NameMatches(const Entry &rhs) const {
+ if (name == rhs.name)
+ return true;
+ else if (name && rhs.name)
+ return strcmp(name, rhs.name) == 0;
+ return false;
}
- bool
- operator ==(const DWARFDeclContext& rhs) const;
+ // Test operator
+ explicit operator bool() const { return tag != 0; }
- uint32_t
- GetSize() const
- {
- return m_entries.size();
- }
+ dw_tag_t tag;
+ const char *name;
+ };
- Entry &
- operator[] (uint32_t idx)
- {
- // "idx" must be valid
- return m_entries[idx];
- }
+ DWARFDeclContext() : m_entries(), m_language(lldb::eLanguageTypeUnknown) {}
- const Entry &
- operator[] (uint32_t idx) const
- {
- // "idx" must be valid
- return m_entries[idx];
- }
+ void AppendDeclContext(dw_tag_t tag, const char *name) {
+ m_entries.push_back(Entry(tag, name));
+ }
- const char *
- GetQualifiedName () const;
+ bool operator==(const DWARFDeclContext &rhs) const;
- // Same as GetQaulifiedName, but the life time of the returned string will
- // be that of the LLDB session.
- lldb_private::ConstString
- GetQualifiedNameAsConstString () const
- {
- return lldb_private::ConstString (GetQualifiedName ());
- }
+ uint32_t GetSize() const { return m_entries.size(); }
- void
- Clear()
- {
- m_entries.clear();
- m_qualified_name.clear();
- }
+ Entry &operator[](uint32_t idx) {
+ // "idx" must be valid
+ return m_entries[idx];
+ }
- lldb::LanguageType
- GetLanguage() const
- {
- return m_language;
- }
+ const Entry &operator[](uint32_t idx) const {
+ // "idx" must be valid
+ return m_entries[idx];
+ }
- void
- SetLanguage(lldb::LanguageType language)
- {
- m_language = language;
- }
+ const char *GetQualifiedName() const;
+
+ // Same as GetQaulifiedName, but the life time of the returned string will
+ // be that of the LLDB session.
+ lldb_private::ConstString GetQualifiedNameAsConstString() const {
+ return lldb_private::ConstString(GetQualifiedName());
+ }
+
+ void Clear() {
+ m_entries.clear();
+ m_qualified_name.clear();
+ }
+
+ lldb::LanguageType GetLanguage() const { return m_language; }
+
+ void SetLanguage(lldb::LanguageType language) { m_language = language; }
protected:
- typedef std::vector<Entry> collection;
- collection m_entries;
- mutable std::string m_qualified_name;
- lldb::LanguageType m_language;
+ typedef std::vector<Entry> collection;
+ collection m_entries;
+ mutable std::string m_qualified_name;
+ lldb::LanguageType m_language;
};
-#endif // SymbolFileDWARF_DWARFDeclContext_h_
+#endif // SymbolFileDWARF_DWARFDeclContext_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp Tue Sep 6 15:57:50 2016
@@ -8,490 +8,640 @@
//===----------------------------------------------------------------------===//
#include "DWARFDefines.h"
+#include "lldb/Core/ConstString.h"
#include <cstdio>
#include <cstring>
#include <string>
-#include "lldb/Core/ConstString.h"
namespace lldb_private {
-const char *
-DW_TAG_value_to_name (uint32_t val)
-{
+const char *DW_TAG_value_to_name(uint32_t val) {
static char invalid[100];
if (val == 0)
- return "NULL";
+ return "NULL";
- const char *llvmstr = llvm::dwarf::TagString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_TAG constant: 0x%x", val);
- return invalid;
+ const char *llvmstr = llvm::dwarf::TagString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_TAG constant: 0x%x", val);
+ return invalid;
}
return llvmstr;
-}
+}
-const char *
-DW_CHILDREN_value_to_name (uint8_t val)
-{
+const char *DW_CHILDREN_value_to_name(uint8_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::ChildrenString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_CHILDREN constant: 0x%x", val);
- return invalid;
+ const char *llvmstr = llvm::dwarf::ChildrenString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_CHILDREN constant: 0x%x",
+ val);
+ return invalid;
}
return llvmstr;
}
-const char *
-DW_AT_value_to_name (uint32_t val)
-{
+const char *DW_AT_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::AttributeString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_AT constant: 0x%x", val);
- return invalid;
+ const char *llvmstr = llvm::dwarf::AttributeString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_AT constant: 0x%x", val);
+ return invalid;
}
return llvmstr;
}
-const char *
-DW_FORM_value_to_name (uint32_t val)
-{
+const char *DW_FORM_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::FormEncodingString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_FORM constant: 0x%x", val);
- return invalid;
+ const char *llvmstr = llvm::dwarf::FormEncodingString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_FORM constant: 0x%x", val);
+ return invalid;
}
return llvmstr;
}
-const char *
-DW_OP_value_to_name (uint32_t val)
-{
+const char *DW_OP_value_to_name(uint32_t val) {
static char invalid[100];
- const char *llvmstr = llvm::dwarf::OperationEncodingString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_OP constant: 0x%x", val);
- return invalid;
+ const char *llvmstr = llvm::dwarf::OperationEncodingString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
+ return invalid;
}
return llvmstr;
}
-DRC_class
-DW_OP_value_to_class (uint32_t val)
-{
+DRC_class DW_OP_value_to_class(uint32_t val) {
switch (val) {
- case 0x03: return DRC_ONEOPERAND;
- case 0x06: return DRC_ZEROOPERANDS;
- case 0x08: return DRC_ONEOPERAND;
- case 0x09: return DRC_ONEOPERAND;
- case 0x0a: return DRC_ONEOPERAND;
- case 0x0b: return DRC_ONEOPERAND;
- case 0x0c: return DRC_ONEOPERAND;
- case 0x0d: return DRC_ONEOPERAND;
- case 0x0e: return DRC_ONEOPERAND;
- case 0x0f: return DRC_ONEOPERAND;
- case 0x10: return DRC_ONEOPERAND;
- case 0x11: return DRC_ONEOPERAND;
- case 0x12: return DRC_ZEROOPERANDS;
- case 0x13: return DRC_ZEROOPERANDS;
- case 0x14: return DRC_ZEROOPERANDS;
- case 0x15: return DRC_ONEOPERAND;
- case 0x16: return DRC_ZEROOPERANDS;
- case 0x17: return DRC_ZEROOPERANDS;
- case 0x18: return DRC_ZEROOPERANDS;
- case 0x19: return DRC_ZEROOPERANDS;
- case 0x1a: return DRC_ZEROOPERANDS;
- case 0x1b: return DRC_ZEROOPERANDS;
- case 0x1c: return DRC_ZEROOPERANDS;
- case 0x1d: return DRC_ZEROOPERANDS;
- case 0x1e: return DRC_ZEROOPERANDS;
- case 0x1f: return DRC_ZEROOPERANDS;
- case 0x20: return DRC_ZEROOPERANDS;
- case 0x21: return DRC_ZEROOPERANDS;
- case 0x22: return DRC_ZEROOPERANDS;
- case 0x23: return DRC_ONEOPERAND;
- case 0x24: return DRC_ZEROOPERANDS;
- case 0x25: return DRC_ZEROOPERANDS;
- case 0x26: return DRC_ZEROOPERANDS;
- case 0x27: return DRC_ZEROOPERANDS;
- case 0x2f: return DRC_ONEOPERAND;
- case 0x28: return DRC_ONEOPERAND;
- case 0x29: return DRC_ZEROOPERANDS;
- case 0x2a: return DRC_ZEROOPERANDS;
- case 0x2b: return DRC_ZEROOPERANDS;
- case 0x2c: return DRC_ZEROOPERANDS;
- case 0x2d: return DRC_ZEROOPERANDS;
- case 0x2e: return DRC_ZEROOPERANDS;
- case 0x30: return DRC_ZEROOPERANDS;
- case 0x31: return DRC_ZEROOPERANDS;
- case 0x32: return DRC_ZEROOPERANDS;
- case 0x33: return DRC_ZEROOPERANDS;
- case 0x34: return DRC_ZEROOPERANDS;
- case 0x35: return DRC_ZEROOPERANDS;
- case 0x36: return DRC_ZEROOPERANDS;
- case 0x37: return DRC_ZEROOPERANDS;
- case 0x38: return DRC_ZEROOPERANDS;
- case 0x39: return DRC_ZEROOPERANDS;
- case 0x3a: return DRC_ZEROOPERANDS;
- case 0x3b: return DRC_ZEROOPERANDS;
- case 0x3c: return DRC_ZEROOPERANDS;
- case 0x3d: return DRC_ZEROOPERANDS;
- case 0x3e: return DRC_ZEROOPERANDS;
- case 0x3f: return DRC_ZEROOPERANDS;
- case 0x40: return DRC_ZEROOPERANDS;
- case 0x41: return DRC_ZEROOPERANDS;
- case 0x42: return DRC_ZEROOPERANDS;
- case 0x43: return DRC_ZEROOPERANDS;
- case 0x44: return DRC_ZEROOPERANDS;
- case 0x45: return DRC_ZEROOPERANDS;
- case 0x46: return DRC_ZEROOPERANDS;
- case 0x47: return DRC_ZEROOPERANDS;
- case 0x48: return DRC_ZEROOPERANDS;
- case 0x49: return DRC_ZEROOPERANDS;
- case 0x4a: return DRC_ZEROOPERANDS;
- case 0x4b: return DRC_ZEROOPERANDS;
- case 0x4c: return DRC_ZEROOPERANDS;
- case 0x4d: return DRC_ZEROOPERANDS;
- case 0x4e: return DRC_ZEROOPERANDS;
- case 0x4f: return DRC_ZEROOPERANDS;
- case 0x50: return DRC_ZEROOPERANDS;
- case 0x51: return DRC_ZEROOPERANDS;
- case 0x52: return DRC_ZEROOPERANDS;
- case 0x53: return DRC_ZEROOPERANDS;
- case 0x54: return DRC_ZEROOPERANDS;
- case 0x55: return DRC_ZEROOPERANDS;
- case 0x56: return DRC_ZEROOPERANDS;
- case 0x57: return DRC_ZEROOPERANDS;
- case 0x58: return DRC_ZEROOPERANDS;
- case 0x59: return DRC_ZEROOPERANDS;
- case 0x5a: return DRC_ZEROOPERANDS;
- case 0x5b: return DRC_ZEROOPERANDS;
- case 0x5c: return DRC_ZEROOPERANDS;
- case 0x5d: return DRC_ZEROOPERANDS;
- case 0x5e: return DRC_ZEROOPERANDS;
- case 0x5f: return DRC_ZEROOPERANDS;
- case 0x60: return DRC_ZEROOPERANDS;
- case 0x61: return DRC_ZEROOPERANDS;
- case 0x62: return DRC_ZEROOPERANDS;
- case 0x63: return DRC_ZEROOPERANDS;
- case 0x64: return DRC_ZEROOPERANDS;
- case 0x65: return DRC_ZEROOPERANDS;
- case 0x66: return DRC_ZEROOPERANDS;
- case 0x67: return DRC_ZEROOPERANDS;
- case 0x68: return DRC_ZEROOPERANDS;
- case 0x69: return DRC_ZEROOPERANDS;
- case 0x6a: return DRC_ZEROOPERANDS;
- case 0x6b: return DRC_ZEROOPERANDS;
- case 0x6c: return DRC_ZEROOPERANDS;
- case 0x6d: return DRC_ZEROOPERANDS;
- case 0x6e: return DRC_ZEROOPERANDS;
- case 0x6f: return DRC_ZEROOPERANDS;
- case 0x70: return DRC_ONEOPERAND;
- case 0x71: return DRC_ONEOPERAND;
- case 0x72: return DRC_ONEOPERAND;
- case 0x73: return DRC_ONEOPERAND;
- case 0x74: return DRC_ONEOPERAND;
- case 0x75: return DRC_ONEOPERAND;
- case 0x76: return DRC_ONEOPERAND;
- case 0x77: return DRC_ONEOPERAND;
- case 0x78: return DRC_ONEOPERAND;
- case 0x79: return DRC_ONEOPERAND;
- case 0x7a: return DRC_ONEOPERAND;
- case 0x7b: return DRC_ONEOPERAND;
- case 0x7c: return DRC_ONEOPERAND;
- case 0x7d: return DRC_ONEOPERAND;
- case 0x7e: return DRC_ONEOPERAND;
- case 0x7f: return DRC_ONEOPERAND;
- case 0x80: return DRC_ONEOPERAND;
- case 0x81: return DRC_ONEOPERAND;
- case 0x82: return DRC_ONEOPERAND;
- case 0x83: return DRC_ONEOPERAND;
- case 0x84: return DRC_ONEOPERAND;
- case 0x85: return DRC_ONEOPERAND;
- case 0x86: return DRC_ONEOPERAND;
- case 0x87: return DRC_ONEOPERAND;
- case 0x88: return DRC_ONEOPERAND;
- case 0x89: return DRC_ONEOPERAND;
- case 0x8a: return DRC_ONEOPERAND;
- case 0x8b: return DRC_ONEOPERAND;
- case 0x8c: return DRC_ONEOPERAND;
- case 0x8d: return DRC_ONEOPERAND;
- case 0x8e: return DRC_ONEOPERAND;
- case 0x8f: return DRC_ONEOPERAND;
- case 0x90: return DRC_ONEOPERAND;
- case 0x91: return DRC_ONEOPERAND;
- case 0x92: return DRC_TWOOPERANDS;
- case 0x93: return DRC_ONEOPERAND;
- case 0x94: return DRC_ONEOPERAND;
- case 0x95: return DRC_ONEOPERAND;
- case 0x96: return DRC_ZEROOPERANDS;
- case 0x97: return DRC_DWARFv3 | DRC_ZEROOPERANDS;
- case 0x98: return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0x99: return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0x9a: return DRC_DWARFv3 | DRC_ONEOPERAND;
- case 0xf0: return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
- case 0xe0: return 0;
- case 0xff: return 0;
- default: return 0;
- }
-}
-
-const char *
-DW_ATE_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::AttributeEncodingString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ATE constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_ACCESS_value_to_name (uint32_t val)
-{
- static char invalid[100];
-
- const char *llvmstr = llvm::dwarf::AccessibilityString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ACCESS constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_VIS_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::VisibilityString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_VIS constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_VIRTUALITY_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::VirtualityString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_VIRTUALITY constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_LANG_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::LanguageString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_LANG constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_ID_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::CaseString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ID constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_CC_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::ConventionString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_CC constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_INL_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::InlineCodeString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_INL constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_ORD_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::ArrayOrderString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_ORD constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_DSC_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::DiscriminantString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_DSC constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_LNS_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::LNStandardString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_LNS constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_LNE_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::LNExtendedString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_LNE constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_MACINFO_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::MacinfoString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_MACINFO constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-const char *
-DW_CFA_value_to_name (uint32_t val)
-{
- static char invalid[100];
- const char *llvmstr = llvm::dwarf::CallFrameString (val);
- if (llvmstr == NULL)
- {
- snprintf (invalid, sizeof (invalid), "Unknown DW_CFA constant: 0x%x", val);
- return invalid;
- }
- return llvmstr;
-}
-
-DW_TAG_CategoryEnum
-get_tag_category (uint16_t tag)
-{
- switch (tag)
- {
- case DW_TAG_array_type : return TagCategoryType;
- case DW_TAG_class_type : return TagCategoryType;
- case DW_TAG_entry_point : return TagCategoryProgram;
- case DW_TAG_enumeration_type : return TagCategoryType;
- case DW_TAG_formal_parameter : return TagCategoryVariable;
- case DW_TAG_imported_declaration : return TagCategoryProgram;
- case DW_TAG_label : return TagCategoryProgram;
- case DW_TAG_lexical_block : return TagCategoryProgram;
- case DW_TAG_member : return TagCategoryType;
- case DW_TAG_pointer_type : return TagCategoryType;
- case DW_TAG_reference_type : return TagCategoryType;
- case DW_TAG_compile_unit : return TagCategoryProgram;
- case DW_TAG_string_type : return TagCategoryType;
- case DW_TAG_structure_type : return TagCategoryType;
- case DW_TAG_subroutine_type : return TagCategoryType;
- case DW_TAG_typedef : return TagCategoryType;
- case DW_TAG_union_type : return TagCategoryType;
- case DW_TAG_unspecified_parameters : return TagCategoryVariable;
- case DW_TAG_variant : return TagCategoryType;
- case DW_TAG_common_block : return TagCategoryProgram;
- case DW_TAG_common_inclusion : return TagCategoryProgram;
- case DW_TAG_inheritance : return TagCategoryType;
- case DW_TAG_inlined_subroutine : return TagCategoryProgram;
- case DW_TAG_module : return TagCategoryProgram;
- case DW_TAG_ptr_to_member_type : return TagCategoryType;
- case DW_TAG_set_type : return TagCategoryType;
- case DW_TAG_subrange_type : return TagCategoryType;
- case DW_TAG_with_stmt : return TagCategoryProgram;
- case DW_TAG_access_declaration : return TagCategoryProgram;
- case DW_TAG_base_type : return TagCategoryType;
- case DW_TAG_catch_block : return TagCategoryProgram;
- case DW_TAG_const_type : return TagCategoryType;
- case DW_TAG_constant : return TagCategoryVariable;
- case DW_TAG_enumerator : return TagCategoryType;
- case DW_TAG_file_type : return TagCategoryType;
- case DW_TAG_friend : return TagCategoryType;
- case DW_TAG_namelist : return TagCategoryVariable;
- case DW_TAG_namelist_item : return TagCategoryVariable;
- case DW_TAG_packed_type : return TagCategoryType;
- case DW_TAG_subprogram : return TagCategoryProgram;
- case DW_TAG_template_type_parameter : return TagCategoryType;
- case DW_TAG_template_value_parameter : return TagCategoryType;
- case DW_TAG_thrown_type : return TagCategoryType;
- case DW_TAG_try_block : return TagCategoryProgram;
- case DW_TAG_variant_part : return TagCategoryType;
- case DW_TAG_variable : return TagCategoryVariable;
- case DW_TAG_volatile_type : return TagCategoryType;
- case DW_TAG_dwarf_procedure : return TagCategoryProgram;
- case DW_TAG_restrict_type : return TagCategoryType;
- case DW_TAG_interface_type : return TagCategoryType;
- case DW_TAG_namespace : return TagCategoryProgram;
- case DW_TAG_imported_module : return TagCategoryProgram;
- case DW_TAG_unspecified_type : return TagCategoryType;
- case DW_TAG_partial_unit : return TagCategoryProgram;
- case DW_TAG_imported_unit : return TagCategoryProgram;
- case DW_TAG_shared_type : return TagCategoryType;
- default: break;
- }
+ case 0x03:
+ return DRC_ONEOPERAND;
+ case 0x06:
+ return DRC_ZEROOPERANDS;
+ case 0x08:
+ return DRC_ONEOPERAND;
+ case 0x09:
+ return DRC_ONEOPERAND;
+ case 0x0a:
+ return DRC_ONEOPERAND;
+ case 0x0b:
+ return DRC_ONEOPERAND;
+ case 0x0c:
+ return DRC_ONEOPERAND;
+ case 0x0d:
+ return DRC_ONEOPERAND;
+ case 0x0e:
+ return DRC_ONEOPERAND;
+ case 0x0f:
+ return DRC_ONEOPERAND;
+ case 0x10:
+ return DRC_ONEOPERAND;
+ case 0x11:
+ return DRC_ONEOPERAND;
+ case 0x12:
+ return DRC_ZEROOPERANDS;
+ case 0x13:
+ return DRC_ZEROOPERANDS;
+ case 0x14:
+ return DRC_ZEROOPERANDS;
+ case 0x15:
+ return DRC_ONEOPERAND;
+ case 0x16:
+ return DRC_ZEROOPERANDS;
+ case 0x17:
+ return DRC_ZEROOPERANDS;
+ case 0x18:
+ return DRC_ZEROOPERANDS;
+ case 0x19:
+ return DRC_ZEROOPERANDS;
+ case 0x1a:
+ return DRC_ZEROOPERANDS;
+ case 0x1b:
+ return DRC_ZEROOPERANDS;
+ case 0x1c:
+ return DRC_ZEROOPERANDS;
+ case 0x1d:
+ return DRC_ZEROOPERANDS;
+ case 0x1e:
+ return DRC_ZEROOPERANDS;
+ case 0x1f:
+ return DRC_ZEROOPERANDS;
+ case 0x20:
+ return DRC_ZEROOPERANDS;
+ case 0x21:
+ return DRC_ZEROOPERANDS;
+ case 0x22:
+ return DRC_ZEROOPERANDS;
+ case 0x23:
+ return DRC_ONEOPERAND;
+ case 0x24:
+ return DRC_ZEROOPERANDS;
+ case 0x25:
+ return DRC_ZEROOPERANDS;
+ case 0x26:
+ return DRC_ZEROOPERANDS;
+ case 0x27:
+ return DRC_ZEROOPERANDS;
+ case 0x2f:
+ return DRC_ONEOPERAND;
+ case 0x28:
+ return DRC_ONEOPERAND;
+ case 0x29:
+ return DRC_ZEROOPERANDS;
+ case 0x2a:
+ return DRC_ZEROOPERANDS;
+ case 0x2b:
+ return DRC_ZEROOPERANDS;
+ case 0x2c:
+ return DRC_ZEROOPERANDS;
+ case 0x2d:
+ return DRC_ZEROOPERANDS;
+ case 0x2e:
+ return DRC_ZEROOPERANDS;
+ case 0x30:
+ return DRC_ZEROOPERANDS;
+ case 0x31:
+ return DRC_ZEROOPERANDS;
+ case 0x32:
+ return DRC_ZEROOPERANDS;
+ case 0x33:
+ return DRC_ZEROOPERANDS;
+ case 0x34:
+ return DRC_ZEROOPERANDS;
+ case 0x35:
+ return DRC_ZEROOPERANDS;
+ case 0x36:
+ return DRC_ZEROOPERANDS;
+ case 0x37:
+ return DRC_ZEROOPERANDS;
+ case 0x38:
+ return DRC_ZEROOPERANDS;
+ case 0x39:
+ return DRC_ZEROOPERANDS;
+ case 0x3a:
+ return DRC_ZEROOPERANDS;
+ case 0x3b:
+ return DRC_ZEROOPERANDS;
+ case 0x3c:
+ return DRC_ZEROOPERANDS;
+ case 0x3d:
+ return DRC_ZEROOPERANDS;
+ case 0x3e:
+ return DRC_ZEROOPERANDS;
+ case 0x3f:
+ return DRC_ZEROOPERANDS;
+ case 0x40:
+ return DRC_ZEROOPERANDS;
+ case 0x41:
+ return DRC_ZEROOPERANDS;
+ case 0x42:
+ return DRC_ZEROOPERANDS;
+ case 0x43:
+ return DRC_ZEROOPERANDS;
+ case 0x44:
+ return DRC_ZEROOPERANDS;
+ case 0x45:
+ return DRC_ZEROOPERANDS;
+ case 0x46:
+ return DRC_ZEROOPERANDS;
+ case 0x47:
+ return DRC_ZEROOPERANDS;
+ case 0x48:
+ return DRC_ZEROOPERANDS;
+ case 0x49:
+ return DRC_ZEROOPERANDS;
+ case 0x4a:
+ return DRC_ZEROOPERANDS;
+ case 0x4b:
+ return DRC_ZEROOPERANDS;
+ case 0x4c:
+ return DRC_ZEROOPERANDS;
+ case 0x4d:
+ return DRC_ZEROOPERANDS;
+ case 0x4e:
+ return DRC_ZEROOPERANDS;
+ case 0x4f:
+ return DRC_ZEROOPERANDS;
+ case 0x50:
+ return DRC_ZEROOPERANDS;
+ case 0x51:
+ return DRC_ZEROOPERANDS;
+ case 0x52:
+ return DRC_ZEROOPERANDS;
+ case 0x53:
+ return DRC_ZEROOPERANDS;
+ case 0x54:
+ return DRC_ZEROOPERANDS;
+ case 0x55:
+ return DRC_ZEROOPERANDS;
+ case 0x56:
+ return DRC_ZEROOPERANDS;
+ case 0x57:
+ return DRC_ZEROOPERANDS;
+ case 0x58:
+ return DRC_ZEROOPERANDS;
+ case 0x59:
+ return DRC_ZEROOPERANDS;
+ case 0x5a:
+ return DRC_ZEROOPERANDS;
+ case 0x5b:
+ return DRC_ZEROOPERANDS;
+ case 0x5c:
+ return DRC_ZEROOPERANDS;
+ case 0x5d:
+ return DRC_ZEROOPERANDS;
+ case 0x5e:
+ return DRC_ZEROOPERANDS;
+ case 0x5f:
+ return DRC_ZEROOPERANDS;
+ case 0x60:
+ return DRC_ZEROOPERANDS;
+ case 0x61:
+ return DRC_ZEROOPERANDS;
+ case 0x62:
+ return DRC_ZEROOPERANDS;
+ case 0x63:
+ return DRC_ZEROOPERANDS;
+ case 0x64:
+ return DRC_ZEROOPERANDS;
+ case 0x65:
+ return DRC_ZEROOPERANDS;
+ case 0x66:
+ return DRC_ZEROOPERANDS;
+ case 0x67:
+ return DRC_ZEROOPERANDS;
+ case 0x68:
+ return DRC_ZEROOPERANDS;
+ case 0x69:
+ return DRC_ZEROOPERANDS;
+ case 0x6a:
+ return DRC_ZEROOPERANDS;
+ case 0x6b:
+ return DRC_ZEROOPERANDS;
+ case 0x6c:
+ return DRC_ZEROOPERANDS;
+ case 0x6d:
+ return DRC_ZEROOPERANDS;
+ case 0x6e:
+ return DRC_ZEROOPERANDS;
+ case 0x6f:
+ return DRC_ZEROOPERANDS;
+ case 0x70:
+ return DRC_ONEOPERAND;
+ case 0x71:
+ return DRC_ONEOPERAND;
+ case 0x72:
+ return DRC_ONEOPERAND;
+ case 0x73:
+ return DRC_ONEOPERAND;
+ case 0x74:
+ return DRC_ONEOPERAND;
+ case 0x75:
+ return DRC_ONEOPERAND;
+ case 0x76:
+ return DRC_ONEOPERAND;
+ case 0x77:
+ return DRC_ONEOPERAND;
+ case 0x78:
+ return DRC_ONEOPERAND;
+ case 0x79:
+ return DRC_ONEOPERAND;
+ case 0x7a:
+ return DRC_ONEOPERAND;
+ case 0x7b:
+ return DRC_ONEOPERAND;
+ case 0x7c:
+ return DRC_ONEOPERAND;
+ case 0x7d:
+ return DRC_ONEOPERAND;
+ case 0x7e:
+ return DRC_ONEOPERAND;
+ case 0x7f:
+ return DRC_ONEOPERAND;
+ case 0x80:
+ return DRC_ONEOPERAND;
+ case 0x81:
+ return DRC_ONEOPERAND;
+ case 0x82:
+ return DRC_ONEOPERAND;
+ case 0x83:
+ return DRC_ONEOPERAND;
+ case 0x84:
+ return DRC_ONEOPERAND;
+ case 0x85:
+ return DRC_ONEOPERAND;
+ case 0x86:
+ return DRC_ONEOPERAND;
+ case 0x87:
+ return DRC_ONEOPERAND;
+ case 0x88:
+ return DRC_ONEOPERAND;
+ case 0x89:
+ return DRC_ONEOPERAND;
+ case 0x8a:
+ return DRC_ONEOPERAND;
+ case 0x8b:
+ return DRC_ONEOPERAND;
+ case 0x8c:
+ return DRC_ONEOPERAND;
+ case 0x8d:
+ return DRC_ONEOPERAND;
+ case 0x8e:
+ return DRC_ONEOPERAND;
+ case 0x8f:
+ return DRC_ONEOPERAND;
+ case 0x90:
+ return DRC_ONEOPERAND;
+ case 0x91:
+ return DRC_ONEOPERAND;
+ case 0x92:
+ return DRC_TWOOPERANDS;
+ case 0x93:
+ return DRC_ONEOPERAND;
+ case 0x94:
+ return DRC_ONEOPERAND;
+ case 0x95:
+ return DRC_ONEOPERAND;
+ case 0x96:
+ return DRC_ZEROOPERANDS;
+ case 0x97:
+ return DRC_DWARFv3 | DRC_ZEROOPERANDS;
+ case 0x98:
+ return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0x99:
+ return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0x9a:
+ return DRC_DWARFv3 | DRC_ONEOPERAND;
+ case 0xf0:
+ return DRC_ZEROOPERANDS; /* DW_OP_APPLE_uninit */
+ case 0xe0:
+ return 0;
+ case 0xff:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+const char *DW_ATE_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::AttributeEncodingString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ATE constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_ACCESS_value_to_name(uint32_t val) {
+ static char invalid[100];
+
+ const char *llvmstr = llvm::dwarf::AccessibilityString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ACCESS constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_VIS_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::VisibilityString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_VIS constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_VIRTUALITY_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::VirtualityString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_VIRTUALITY constant: 0x%x",
+ val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_LANG_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::LanguageString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_LANG constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_ID_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::CaseString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ID constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_CC_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::ConventionString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_CC constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_INL_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::InlineCodeString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_INL constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_ORD_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::ArrayOrderString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_ORD constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_DSC_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::DiscriminantString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_DSC constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_LNS_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::LNStandardString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_LNS constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_LNE_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::LNExtendedString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_LNE constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_MACINFO_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::MacinfoString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_MACINFO constant: 0x%x",
+ val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+const char *DW_CFA_value_to_name(uint32_t val) {
+ static char invalid[100];
+ const char *llvmstr = llvm::dwarf::CallFrameString(val);
+ if (llvmstr == NULL) {
+ snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val);
+ return invalid;
+ }
+ return llvmstr;
+}
+
+DW_TAG_CategoryEnum get_tag_category(uint16_t tag) {
+ switch (tag) {
+ case DW_TAG_array_type:
+ return TagCategoryType;
+ case DW_TAG_class_type:
+ return TagCategoryType;
+ case DW_TAG_entry_point:
+ return TagCategoryProgram;
+ case DW_TAG_enumeration_type:
+ return TagCategoryType;
+ case DW_TAG_formal_parameter:
+ return TagCategoryVariable;
+ case DW_TAG_imported_declaration:
+ return TagCategoryProgram;
+ case DW_TAG_label:
+ return TagCategoryProgram;
+ case DW_TAG_lexical_block:
+ return TagCategoryProgram;
+ case DW_TAG_member:
+ return TagCategoryType;
+ case DW_TAG_pointer_type:
+ return TagCategoryType;
+ case DW_TAG_reference_type:
+ return TagCategoryType;
+ case DW_TAG_compile_unit:
+ return TagCategoryProgram;
+ case DW_TAG_string_type:
+ return TagCategoryType;
+ case DW_TAG_structure_type:
+ return TagCategoryType;
+ case DW_TAG_subroutine_type:
+ return TagCategoryType;
+ case DW_TAG_typedef:
+ return TagCategoryType;
+ case DW_TAG_union_type:
+ return TagCategoryType;
+ case DW_TAG_unspecified_parameters:
+ return TagCategoryVariable;
+ case DW_TAG_variant:
+ return TagCategoryType;
+ case DW_TAG_common_block:
+ return TagCategoryProgram;
+ case DW_TAG_common_inclusion:
+ return TagCategoryProgram;
+ case DW_TAG_inheritance:
+ return TagCategoryType;
+ case DW_TAG_inlined_subroutine:
+ return TagCategoryProgram;
+ case DW_TAG_module:
+ return TagCategoryProgram;
+ case DW_TAG_ptr_to_member_type:
+ return TagCategoryType;
+ case DW_TAG_set_type:
+ return TagCategoryType;
+ case DW_TAG_subrange_type:
+ return TagCategoryType;
+ case DW_TAG_with_stmt:
return TagCategoryProgram;
+ case DW_TAG_access_declaration:
+ return TagCategoryProgram;
+ case DW_TAG_base_type:
+ return TagCategoryType;
+ case DW_TAG_catch_block:
+ return TagCategoryProgram;
+ case DW_TAG_const_type:
+ return TagCategoryType;
+ case DW_TAG_constant:
+ return TagCategoryVariable;
+ case DW_TAG_enumerator:
+ return TagCategoryType;
+ case DW_TAG_file_type:
+ return TagCategoryType;
+ case DW_TAG_friend:
+ return TagCategoryType;
+ case DW_TAG_namelist:
+ return TagCategoryVariable;
+ case DW_TAG_namelist_item:
+ return TagCategoryVariable;
+ case DW_TAG_packed_type:
+ return TagCategoryType;
+ case DW_TAG_subprogram:
+ return TagCategoryProgram;
+ case DW_TAG_template_type_parameter:
+ return TagCategoryType;
+ case DW_TAG_template_value_parameter:
+ return TagCategoryType;
+ case DW_TAG_thrown_type:
+ return TagCategoryType;
+ case DW_TAG_try_block:
+ return TagCategoryProgram;
+ case DW_TAG_variant_part:
+ return TagCategoryType;
+ case DW_TAG_variable:
+ return TagCategoryVariable;
+ case DW_TAG_volatile_type:
+ return TagCategoryType;
+ case DW_TAG_dwarf_procedure:
+ return TagCategoryProgram;
+ case DW_TAG_restrict_type:
+ return TagCategoryType;
+ case DW_TAG_interface_type:
+ return TagCategoryType;
+ case DW_TAG_namespace:
+ return TagCategoryProgram;
+ case DW_TAG_imported_module:
+ return TagCategoryProgram;
+ case DW_TAG_unspecified_type:
+ return TagCategoryType;
+ case DW_TAG_partial_unit:
+ return TagCategoryProgram;
+ case DW_TAG_imported_unit:
+ return TagCategoryProgram;
+ case DW_TAG_shared_type:
+ return TagCategoryType;
+ default:
+ break;
+ }
+ return TagCategoryProgram;
}
} // namespace lldb_private
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h Tue Sep 6 15:57:50 2016
@@ -10,106 +10,104 @@
#ifndef SymbolFileDWARF_DWARFDefines_h_
#define SymbolFileDWARF_DWARFDefines_h_
-#include <stdint.h>
#include "lldb/Core/dwarf.h"
+#include <stdint.h>
namespace lldb_private {
-typedef uint32_t DRC_class; // Holds DRC_* class bitfields
+typedef uint32_t DRC_class; // Holds DRC_* class bitfields
-enum DW_TAG_Category
-{
- TagCategoryVariable,
- TagCategoryType,
- TagCategoryProgram,
- kNumTagCategories
+enum DW_TAG_Category {
+ TagCategoryVariable,
+ TagCategoryType,
+ TagCategoryProgram,
+ kNumTagCategories
};
typedef enum DW_TAG_Category DW_TAG_CategoryEnum;
-const char *DW_TAG_value_to_name (uint32_t val);
+const char *DW_TAG_value_to_name(uint32_t val);
-DW_TAG_CategoryEnum get_tag_category (uint16_t tag);
+DW_TAG_CategoryEnum get_tag_category(uint16_t tag);
-const char *DW_CHILDREN_value_to_name (uint8_t val);
+const char *DW_CHILDREN_value_to_name(uint8_t val);
-const char *DW_AT_value_to_name (uint32_t val);
+const char *DW_AT_value_to_name(uint32_t val);
-const char *DW_FORM_value_to_name (uint32_t val);
+const char *DW_FORM_value_to_name(uint32_t val);
-const char *DW_OP_value_to_name (uint32_t val);
+const char *DW_OP_value_to_name(uint32_t val);
-DRC_class DW_OP_value_to_class (uint32_t val);
+DRC_class DW_OP_value_to_class(uint32_t val);
-const char *DW_ATE_value_to_name (uint32_t val);
+const char *DW_ATE_value_to_name(uint32_t val);
-const char *DW_ACCESS_value_to_name (uint32_t val);
+const char *DW_ACCESS_value_to_name(uint32_t val);
-const char *DW_VIS_value_to_name (uint32_t val);
+const char *DW_VIS_value_to_name(uint32_t val);
-const char *DW_VIRTUALITY_value_to_name (uint32_t val);
+const char *DW_VIRTUALITY_value_to_name(uint32_t val);
-const char *DW_LANG_value_to_name (uint32_t val);
+const char *DW_LANG_value_to_name(uint32_t val);
-const char *DW_ID_value_to_name (uint32_t val);
+const char *DW_ID_value_to_name(uint32_t val);
-const char *DW_CC_value_to_name (uint32_t val);
+const char *DW_CC_value_to_name(uint32_t val);
-const char *DW_INL_value_to_name (uint32_t val);
+const char *DW_INL_value_to_name(uint32_t val);
-const char *DW_ORD_value_to_name (uint32_t val);
+const char *DW_ORD_value_to_name(uint32_t val);
-const char *DW_DSC_value_to_name (uint32_t val);
+const char *DW_DSC_value_to_name(uint32_t val);
-const char *DW_LNS_value_to_name (uint32_t val);
+const char *DW_LNS_value_to_name(uint32_t val);
-const char *DW_LNE_value_to_name (uint32_t val);
+const char *DW_LNE_value_to_name(uint32_t val);
-const char *DW_MACINFO_value_to_name (uint32_t val);
+const char *DW_MACINFO_value_to_name(uint32_t val);
-const char *DW_CFA_value_to_name (uint32_t val);
+const char *DW_CFA_value_to_name(uint32_t val);
-const char *DW_GNU_EH_PE_value_to_name (uint32_t val);
+const char *DW_GNU_EH_PE_value_to_name(uint32_t val);
/* These DRC are entirely our own construction,
although they are derived from various comments in the DWARF standard.
Most of these are not useful to the parser, but the DW_AT and DW_FORM
classes should prove to be usable in some fashion. */
-#define DRC_0x65 0x1
-#define DRC_ADDRESS 0x2
-#define DRC_BLOCK 0x4
-#define DRC_CONSTANT 0x8
-#define DRC_DWARFv3 0x10
-#define DRC_FLAG 0x20
-#define DRC_INDIRECT_SPECIAL 0x40
-#define DRC_LINEPTR 0x80
-#define DRC_LOCEXPR 0x100
-#define DRC_LOCLISTPTR 0x200
-#define DRC_MACPTR 0x400
-#define DRC_ONEOPERAND 0x800
-#define DRC_OPERANDONE_1BYTE_DELTA 0x1000
-#define DRC_OPERANDONE_2BYTE_DELTA 0x2000
-#define DRC_OPERANDONE_4BYTE_DELTA 0x4000
-#define DRC_OPERANDONE_ADDRESS 0x8000
-#define DRC_OPERANDONE_BLOCK 0x10000
-#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000
-#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000
-#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000
-#define DRC_OPERANDTWO_BLOCK 0x100000
-#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000
-#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000
-#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000
-#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000
-#define DRC_RANGELISTPTR 0x2000000
-#define DRC_REFERENCE 0x4000000
-#define DRC_STRING 0x8000000
-#define DRC_TWOOPERANDS 0x10000000
-#define DRC_VENDOR_GNU 0x20000000
-#define DRC_VENDOR_MIPS 0x40000000
-#define DRC_ZEROOPERANDS 0x80000000
+#define DRC_0x65 0x1
+#define DRC_ADDRESS 0x2
+#define DRC_BLOCK 0x4
+#define DRC_CONSTANT 0x8
+#define DRC_DWARFv3 0x10
+#define DRC_FLAG 0x20
+#define DRC_INDIRECT_SPECIAL 0x40
+#define DRC_LINEPTR 0x80
+#define DRC_LOCEXPR 0x100
+#define DRC_LOCLISTPTR 0x200
+#define DRC_MACPTR 0x400
+#define DRC_ONEOPERAND 0x800
+#define DRC_OPERANDONE_1BYTE_DELTA 0x1000
+#define DRC_OPERANDONE_2BYTE_DELTA 0x2000
+#define DRC_OPERANDONE_4BYTE_DELTA 0x4000
+#define DRC_OPERANDONE_ADDRESS 0x8000
+#define DRC_OPERANDONE_BLOCK 0x10000
+#define DRC_OPERANDONE_SLEB128_OFFSET 0x20000
+#define DRC_OPERANDONE_ULEB128_OFFSET 0x40000
+#define DRC_OPERANDONE_ULEB128_REGISTER 0x80000
+#define DRC_OPERANDTWO_BLOCK 0x100000
+#define DRC_OPERANDTWO_SLEB128_OFFSET 0x200000
+#define DRC_OPERANDTWO_ULEB128_OFFSET 0x400000
+#define DRC_OPERANDTWO_ULEB128_REGISTER 0x800000
+#define DRC_OPERNADONE_ULEB128_REGISTER 0x1000000
+#define DRC_RANGELISTPTR 0x2000000
+#define DRC_REFERENCE 0x4000000
+#define DRC_STRING 0x8000000
+#define DRC_TWOOPERANDS 0x10000000
+#define DRC_VENDOR_GNU 0x20000000
+#define DRC_VENDOR_MIPS 0x40000000
+#define DRC_ZEROOPERANDS 0x80000000
} // namespace lldb_private
-
-#endif // SymbolFileDWARF_DWARFDefines_h_
+#endif // SymbolFileDWARF_DWARFDefines_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp Tue Sep 6 15:57:50 2016
@@ -9,19 +9,17 @@
#include <assert.h>
-#include "lldb/Core/dwarf.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Core/dwarf.h"
-#include "DWARFFormValue.h"
#include "DWARFCompileUnit.h"
+#include "DWARFFormValue.h"
class DWARFCompileUnit;
using namespace lldb_private;
-
-static uint8_t g_form_sizes_addr4[] =
-{
+static uint8_t g_form_sizes_addr4[] = {
0, // 0x00 unused
4, // 0x01 DW_FORM_addr
0, // 0x02 unused
@@ -38,7 +36,8 @@ static uint8_t g_form_sizes_addr4[] =
0, // 0x0d DW_FORM_sdata
4, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -58,9 +57,7 @@ static uint8_t g_form_sizes_addr4[] =
};
-static uint8_t
-g_form_sizes_addr8[] =
-{
+static uint8_t g_form_sizes_addr8[] = {
0, // 0x00 unused
8, // 0x01 DW_FORM_addr
0, // 0x02 unused
@@ -77,7 +74,8 @@ g_form_sizes_addr8[] =
0, // 0x0d DW_FORM_sdata
4, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -98,9 +96,7 @@ g_form_sizes_addr8[] =
// Difference with g_form_sizes_addr8:
// DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4
-static uint8_t
-g_form_sizes_addr8_dwarf64[] =
-{
+static uint8_t g_form_sizes_addr8_dwarf64[] = {
0, // 0x00 unused
8, // 0x01 DW_FORM_addr
0, // 0x02 unused
@@ -117,7 +113,8 @@ g_form_sizes_addr8_dwarf64[] =
0, // 0x0d DW_FORM_sdata
8, // 0x0e DW_FORM_strp
0, // 0x0f DW_FORM_udata
- 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+ 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
+ // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
1, // 0x11 DW_FORM_ref1
2, // 0x12 DW_FORM_ref2
4, // 0x13 DW_FORM_ref4
@@ -137,553 +134,612 @@ g_form_sizes_addr8_dwarf64[] =
};
DWARFFormValue::FixedFormSizes
-DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64)
-{
- if (!is_dwarf64) {
- switch (addr_size)
- {
- case 4: return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
- case 8: return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
- }
- } else {
- if (addr_size == 8)
- return FixedFormSizes(g_form_sizes_addr8_dwarf64, sizeof(g_form_sizes_addr8_dwarf64));
- // is_dwarf64 && addr_size == 4 : no provider does this.
- }
- return FixedFormSizes();
-}
-
-DWARFFormValue::DWARFFormValue() :
- m_cu (NULL),
- m_form(0),
- m_value()
-{
-}
-
-DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) :
- m_cu (cu),
- m_form(form),
- m_value()
-{
-}
-
-void
-DWARFFormValue::Clear()
-{
- m_cu = nullptr;
- m_form = 0;
- memset(&m_value, 0, sizeof(m_value));
-}
-
-bool
-DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr)
-{
- bool indirect = false;
- bool is_block = false;
- m_value.data = NULL;
- uint8_t ref_addr_size;
- // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
- do
- {
- indirect = false;
- switch (m_form)
- {
- case DW_FORM_addr: assert(m_cu);
- m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu)); break;
- case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break;
- case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break;
- case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break;
- case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break;
- case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break;
- case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); break;
- case DW_FORM_exprloc:
- case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break;
- case DW_FORM_block1: m_value.value.uval = data.GetU8(offset_ptr); is_block = true; break;
- case DW_FORM_data1: m_value.value.uval = data.GetU8(offset_ptr); break;
- case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break;
- case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break;
- case DW_FORM_strp: assert(m_cu);
- m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4); break;
- // case DW_FORM_APPLE_db_str:
- case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break;
- case DW_FORM_ref_addr: assert(m_cu);
- ref_addr_size = 4;
- if (m_cu->GetVersion() <= 2)
- ref_addr_size = m_cu->GetAddressByteSize();
- else
- ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
- m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break;
- case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break;
- case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break;
- case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break;
- case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break;
- case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break;
- case DW_FORM_indirect:
- m_form = data.GetULEB128(offset_ptr);
- indirect = true;
- break;
-
- case DW_FORM_sec_offset: assert(m_cu);
- m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4); break;
- case DW_FORM_flag_present: m_value.value.uval = 1; break;
- case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break;
- case DW_FORM_GNU_str_index: m_value.value.uval = data.GetULEB128(offset_ptr); break;
- case DW_FORM_GNU_addr_index: m_value.value.uval = data.GetULEB128(offset_ptr); break;
- default:
- return false;
- break;
- }
- } while (indirect);
-
- if (is_block)
- {
- m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
- if (m_value.data != NULL)
- {
- *offset_ptr += m_value.value.uval;
- }
- }
-
- return true;
-}
-
-bool
-DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const
-{
- return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
-}
-
-bool
-DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu)
-{
- uint8_t ref_addr_size;
- switch (form)
- {
- // Blocks if inlined data that have a length field and the data bytes
- // inlined in the .debug_info
- case DW_FORM_exprloc:
- case DW_FORM_block: { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true;
- case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true;
- case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true;
- case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true;
-
- // Inlined NULL terminated C-strings
- case DW_FORM_string:
- debug_info_data.GetCStr(offset_ptr);
- return true;
-
- // Compile unit address sized values
+DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
+ bool is_dwarf64) {
+ if (!is_dwarf64) {
+ switch (addr_size) {
+ case 4:
+ return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4));
+ case 8:
+ return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8));
+ }
+ } else {
+ if (addr_size == 8)
+ return FixedFormSizes(g_form_sizes_addr8_dwarf64,
+ sizeof(g_form_sizes_addr8_dwarf64));
+ // is_dwarf64 && addr_size == 4 : no provider does this.
+ }
+ return FixedFormSizes();
+}
+
+DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
+
+DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form)
+ : m_cu(cu), m_form(form), m_value() {}
+
+void DWARFFormValue::Clear() {
+ m_cu = nullptr;
+ m_form = 0;
+ memset(&m_value, 0, sizeof(m_value));
+}
+
+bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr) {
+ bool indirect = false;
+ bool is_block = false;
+ m_value.data = NULL;
+ uint8_t ref_addr_size;
+ // Read the value for the form into value and follow and DW_FORM_indirect
+ // instances we run into
+ do {
+ indirect = false;
+ switch (m_form) {
case DW_FORM_addr:
- *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
- return true;
-
- case DW_FORM_ref_addr:
- ref_addr_size = 4;
- assert (cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong
- if (cu->GetVersion() <= 2)
- ref_addr_size = cu->GetAddressByteSize();
- else
- ref_addr_size = cu->IsDWARF64() ? 8 : 4;
- *offset_ptr += ref_addr_size;
- return true;
-
- // 0 bytes values (implied from DW_FORM)
- case DW_FORM_flag_present:
- return true;
-
- // 1 byte values
+ assert(m_cu);
+ m_value.value.uval = data.GetMaxU64(
+ offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu));
+ break;
+ case DW_FORM_block2:
+ m_value.value.uval = data.GetU16(offset_ptr);
+ is_block = true;
+ break;
+ case DW_FORM_block4:
+ m_value.value.uval = data.GetU32(offset_ptr);
+ is_block = true;
+ break;
+ case DW_FORM_data2:
+ m_value.value.uval = data.GetU16(offset_ptr);
+ break;
+ case DW_FORM_data4:
+ m_value.value.uval = data.GetU32(offset_ptr);
+ break;
+ case DW_FORM_data8:
+ m_value.value.uval = data.GetU64(offset_ptr);
+ break;
+ case DW_FORM_string:
+ m_value.value.cstr = data.GetCStr(offset_ptr);
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ is_block = true;
+ break;
+ case DW_FORM_block1:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ is_block = true;
+ break;
case DW_FORM_data1:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ break;
case DW_FORM_flag:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ break;
+ case DW_FORM_sdata:
+ m_value.value.sval = data.GetSLEB128(offset_ptr);
+ break;
+ case DW_FORM_strp:
+ assert(m_cu);
+ m_value.value.uval =
+ data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4);
+ break;
+ // case DW_FORM_APPLE_db_str:
+ case DW_FORM_udata:
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ break;
+ case DW_FORM_ref_addr:
+ assert(m_cu);
+ ref_addr_size = 4;
+ if (m_cu->GetVersion() <= 2)
+ ref_addr_size = m_cu->GetAddressByteSize();
+ else
+ ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
+ m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
+ break;
case DW_FORM_ref1:
- *offset_ptr += 1;
- return true;
-
- // 2 byte values
- case DW_FORM_data2:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ break;
case DW_FORM_ref2:
- *offset_ptr += 2;
- return true;
-
- // 32 bit for DWARF 32, 64 for DWARF 64
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- assert(cu);
- *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
- return true;
-
- // 4 byte values
- case DW_FORM_data4:
+ m_value.value.uval = data.GetU16(offset_ptr);
+ break;
case DW_FORM_ref4:
- *offset_ptr += 4;
- return true;
-
- // 8 byte values
- case DW_FORM_data8:
+ m_value.value.uval = data.GetU32(offset_ptr);
+ break;
case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- *offset_ptr += 8;
- return true;
-
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata:
- case DW_FORM_udata:
+ m_value.value.uval = data.GetU64(offset_ptr);
+ break;
case DW_FORM_ref_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- debug_info_data.Skip_LEB128(offset_ptr);
- return true;
-
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ break;
case DW_FORM_indirect:
- {
- dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
- return DWARFFormValue::SkipValue (indirect_form,
- debug_info_data,
- offset_ptr,
- cu);
- }
-
- default:
- break;
- }
- return false;
-}
+ m_form = data.GetULEB128(offset_ptr);
+ indirect = true;
+ break;
-
-void
-DWARFFormValue::Dump(Stream &s) const
-{
- uint64_t uvalue = Unsigned();
- bool cu_relative_offset = false;
-
- bool verbose = s.GetVerbose();
-
- switch (m_form)
- {
- case DW_FORM_addr: s.Address(uvalue, sizeof (uint64_t)); break;
- case DW_FORM_flag:
- case DW_FORM_data1: s.PutHex8(uvalue); break;
- case DW_FORM_data2: s.PutHex16(uvalue); break;
case DW_FORM_sec_offset:
- case DW_FORM_data4: s.PutHex32(uvalue); break;
+ assert(m_cu);
+ m_value.value.uval =
+ data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(m_cu) ? 8 : 4);
+ break;
+ case DW_FORM_flag_present:
+ m_value.value.uval = 1;
+ break;
case DW_FORM_ref_sig8:
- case DW_FORM_data8: s.PutHex64(uvalue); break;
- case DW_FORM_string: s.QuotedCString(AsCString()); break;
- case DW_FORM_exprloc:
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- if (uvalue > 0)
- {
- switch (m_form)
- {
- case DW_FORM_exprloc:
- case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break;
- case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break;
- case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break;
- case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break;
- default: break;
- }
-
- const uint8_t* data_ptr = m_value.data;
- if (data_ptr)
- {
- const uint8_t* end_data_ptr = data_ptr + uvalue; // uvalue contains size of block
- while (data_ptr < end_data_ptr)
- {
- s.Printf("%2.2x ", *data_ptr);
- ++data_ptr;
- }
- }
- else
- s.PutCString("NULL");
- }
- break;
-
- case DW_FORM_sdata: s.PutSLEB128(uvalue); break;
- case DW_FORM_udata: s.PutULEB128(uvalue); break;
- case DW_FORM_strp:
- {
- const char* dbg_str = AsCString();
- if (dbg_str)
- {
- if (verbose)
- s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
- s.QuotedCString(dbg_str);
- }
- else
- {
- s.PutHex32(uvalue);
- }
- }
- break;
-
- case DW_FORM_ref_addr:
- {
- assert (m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong
- if (m_cu->GetVersion() <= 2)
- s.Address(uvalue, sizeof (uint64_t) * 2);
- else
- s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
- break;
- }
- case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
- case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
- case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
- case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
- case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;
-
- // All DW_FORM_indirect attributes should be resolved prior to calling this function
- case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break;
- case DW_FORM_flag_present: break;
+ m_value.value.uval = data.GetU64(offset_ptr);
+ break;
+ case DW_FORM_GNU_str_index:
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ break;
+ case DW_FORM_GNU_addr_index:
+ m_value.value.uval = data.GetULEB128(offset_ptr);
+ break;
default:
- s.Printf("DW_FORM(0x%4.4x)", m_form);
- break;
+ return false;
+ break;
}
+ } while (indirect);
- if (cu_relative_offset)
- {
- assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong
- if (verbose)
- s.PutCString(" => ");
+ if (is_block) {
+ m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
+ if (m_value.data != NULL) {
+ *offset_ptr += m_value.value.uval;
+ }
+ }
+
+ return true;
+}
+
+bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr) const {
+ return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu);
+}
+
+bool DWARFFormValue::SkipValue(dw_form_t form,
+ const DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr,
+ const DWARFCompileUnit *cu) {
+ uint8_t ref_addr_size;
+ switch (form) {
+ // Blocks if inlined data that have a length field and the data bytes
+ // inlined in the .debug_info
+ case DW_FORM_exprloc:
+ case DW_FORM_block: {
+ dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
+ case DW_FORM_block1: {
+ dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
+ case DW_FORM_block2: {
+ dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
+ case DW_FORM_block4: {
+ dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);
+ *offset_ptr += size;
+ }
+ return true;
- s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
- }
-}
+ // Inlined NULL terminated C-strings
+ case DW_FORM_string:
+ debug_info_data.GetCStr(offset_ptr);
+ return true;
-const char*
-DWARFFormValue::AsCString() const
-{
- SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF();
-
- if (m_form == DW_FORM_string)
- {
- return m_value.value.cstr;
- }
- else if (m_form == DW_FORM_strp)
- {
- if (!symbol_file)
- return nullptr;
+ // Compile unit address sized values
+ case DW_FORM_addr:
+ *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
+ return true;
- return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
- }
- else if (m_form == DW_FORM_GNU_str_index)
- {
- if (!symbol_file)
- return nullptr;
-
- uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
- lldb::offset_t offset = m_value.value.uval * index_size;
- dw_offset_t str_offset = symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, index_size);
- return symbol_file->get_debug_str_data().PeekCStr(str_offset);
- }
- return nullptr;
-}
+ case DW_FORM_ref_addr:
+ ref_addr_size = 4;
+ assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get
+ // this wrong
+ if (cu->GetVersion() <= 2)
+ ref_addr_size = cu->GetAddressByteSize();
+ else
+ ref_addr_size = cu->IsDWARF64() ? 8 : 4;
+ *offset_ptr += ref_addr_size;
+ return true;
-dw_addr_t
-DWARFFormValue::Address() const
-{
- SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF();
+ // 0 bytes values (implied from DW_FORM)
+ case DW_FORM_flag_present:
+ return true;
- if (m_form == DW_FORM_addr)
- return Unsigned();
+ // 1 byte values
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ *offset_ptr += 1;
+ return true;
- assert(m_cu);
- assert(m_form == DW_FORM_GNU_addr_index);
+ // 2 byte values
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ *offset_ptr += 2;
+ return true;
- if (!symbol_file)
- return 0;
+ // 32 bit for DWARF 32, 64 for DWARF 64
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ assert(cu);
+ *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
+ return true;
- uint32_t index_size = m_cu->GetAddressByteSize();
- dw_offset_t addr_base = m_cu->GetAddrBase();
- lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
- return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
-}
+ // 4 byte values
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ *offset_ptr += 4;
+ return true;
-uint64_t
-DWARFFormValue::Reference() const
-{
- uint64_t die_offset = m_value.value.uval;
- switch (m_form)
- {
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong
- die_offset += m_cu->GetOffset();
- break;
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ *offset_ptr += 8;
+ return true;
- default:
- break;
- }
+ // signed or unsigned LEB 128 values
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ debug_info_data.Skip_LEB128(offset_ptr);
+ return true;
- return die_offset;
-}
+ case DW_FORM_indirect: {
+ dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
+ return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr,
+ cu);
+ }
+
+ default:
+ break;
+ }
+ return false;
+}
+
+void DWARFFormValue::Dump(Stream &s) const {
+ uint64_t uvalue = Unsigned();
+ bool cu_relative_offset = false;
+
+ bool verbose = s.GetVerbose();
+
+ switch (m_form) {
+ case DW_FORM_addr:
+ s.Address(uvalue, sizeof(uint64_t));
+ break;
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ s.PutHex8(uvalue);
+ break;
+ case DW_FORM_data2:
+ s.PutHex16(uvalue);
+ break;
+ case DW_FORM_sec_offset:
+ case DW_FORM_data4:
+ s.PutHex32(uvalue);
+ break;
+ case DW_FORM_ref_sig8:
+ case DW_FORM_data8:
+ s.PutHex64(uvalue);
+ break;
+ case DW_FORM_string:
+ s.QuotedCString(AsCString());
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ if (uvalue > 0) {
+ switch (m_form) {
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ s.Printf("<0x%" PRIx64 "> ", uvalue);
+ break;
+ case DW_FORM_block1:
+ s.Printf("<0x%2.2x> ", (uint8_t)uvalue);
+ break;
+ case DW_FORM_block2:
+ s.Printf("<0x%4.4x> ", (uint16_t)uvalue);
+ break;
+ case DW_FORM_block4:
+ s.Printf("<0x%8.8x> ", (uint32_t)uvalue);
+ break;
+ default:
+ break;
+ }
-uint64_t
-DWARFFormValue::Reference (dw_offset_t base_offset) const
-{
- uint64_t die_offset = m_value.value.uval;
- switch (m_form)
- {
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- die_offset += base_offset;
- break;
-
- default:
- break;
+ const uint8_t *data_ptr = m_value.data;
+ if (data_ptr) {
+ const uint8_t *end_data_ptr =
+ data_ptr + uvalue; // uvalue contains size of block
+ while (data_ptr < end_data_ptr) {
+ s.Printf("%2.2x ", *data_ptr);
+ ++data_ptr;
+ }
+ } else
+ s.PutCString("NULL");
+ }
+ break;
+
+ case DW_FORM_sdata:
+ s.PutSLEB128(uvalue);
+ break;
+ case DW_FORM_udata:
+ s.PutULEB128(uvalue);
+ break;
+ case DW_FORM_strp: {
+ const char *dbg_str = AsCString();
+ if (dbg_str) {
+ if (verbose)
+ s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
+ s.QuotedCString(dbg_str);
+ } else {
+ s.PutHex32(uvalue);
}
-
- return die_offset;
-}
-
+ } break;
-const uint8_t*
-DWARFFormValue::BlockData() const
-{
- return m_value.data;
-}
+ case DW_FORM_ref_addr: {
+ assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will
+ // get this wrong
+ if (m_cu->GetVersion() <= 2)
+ s.Address(uvalue, sizeof(uint64_t) * 2);
+ else
+ s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't
+ // support DWARF64 yet
+ break;
+ }
+ case DW_FORM_ref1:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%2.2x", (uint8_t)uvalue);
+ break;
+ case DW_FORM_ref2:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%4.4x", (uint16_t)uvalue);
+ break;
+ case DW_FORM_ref4:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%4.4x", (uint32_t)uvalue);
+ break;
+ case DW_FORM_ref8:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%8.8" PRIx64, uvalue);
+ break;
+ case DW_FORM_ref_udata:
+ cu_relative_offset = true;
+ if (verbose)
+ s.Printf("cu + 0x%" PRIx64, uvalue);
+ break;
+
+ // All DW_FORM_indirect attributes should be resolved prior to calling this
+ // function
+ case DW_FORM_indirect:
+ s.PutCString("DW_FORM_indirect");
+ break;
+ case DW_FORM_flag_present:
+ break;
+ default:
+ s.Printf("DW_FORM(0x%4.4x)", m_form);
+ break;
+ }
+
+ if (cu_relative_offset) {
+ assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
+ // unit relative or we will get this wrong
+ if (verbose)
+ s.PutCString(" => ");
+
+ s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset());
+ }
+}
+
+const char *DWARFFormValue::AsCString() const {
+ SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
+
+ if (m_form == DW_FORM_string) {
+ return m_value.value.cstr;
+ } else if (m_form == DW_FORM_strp) {
+ if (!symbol_file)
+ return nullptr;
+ return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval);
+ } else if (m_form == DW_FORM_GNU_str_index) {
+ if (!symbol_file)
+ return nullptr;
-bool
-DWARFFormValue::IsBlockForm(const dw_form_t form)
-{
- switch (form)
- {
- case DW_FORM_exprloc:
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- return true;
- }
- return false;
+ uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4;
+ lldb::offset_t offset = m_value.value.uval * index_size;
+ dw_offset_t str_offset =
+ symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset,
+ index_size);
+ return symbol_file->get_debug_str_data().PeekCStr(str_offset);
+ }
+ return nullptr;
+}
+
+dw_addr_t DWARFFormValue::Address() const {
+ SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF();
+
+ if (m_form == DW_FORM_addr)
+ return Unsigned();
+
+ assert(m_cu);
+ assert(m_form == DW_FORM_GNU_addr_index);
+
+ if (!symbol_file)
+ return 0;
+
+ uint32_t index_size = m_cu->GetAddressByteSize();
+ dw_offset_t addr_base = m_cu->GetAddrBase();
+ lldb::offset_t offset = addr_base + m_value.value.uval * index_size;
+ return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size);
+}
+
+uint64_t DWARFFormValue::Reference() const {
+ uint64_t die_offset = m_value.value.uval;
+ switch (m_form) {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
+ // unit relative or we will get this wrong
+ die_offset += m_cu->GetOffset();
+ break;
+
+ default:
+ break;
+ }
+
+ return die_offset;
+}
+
+uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
+ uint64_t die_offset = m_value.value.uval;
+ switch (m_form) {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ die_offset += base_offset;
+ break;
+
+ default:
+ break;
+ }
+
+ return die_offset;
+}
+
+const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
+
+bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
+ switch (form) {
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ return true;
+ }
+ return false;
}
-bool
-DWARFFormValue::IsDataForm(const dw_form_t form)
-{
- switch (form)
- {
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- return true;
- }
- return false;
+bool DWARFFormValue::IsDataForm(const dw_form_t form) {
+ switch (form) {
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ return true;
+ }
+ return false;
}
-int
-DWARFFormValue::Compare (const DWARFFormValue& a_value,
- const DWARFFormValue& b_value)
-{
- dw_form_t a_form = a_value.Form();
- dw_form_t b_form = b_value.Form();
- if (a_form < b_form)
- return -1;
- if (a_form > b_form)
- return 1;
- switch (a_form)
- {
- case DW_FORM_addr:
- case DW_FORM_flag:
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- case DW_FORM_udata:
- case DW_FORM_ref_addr:
- case DW_FORM_sec_offset:
- case DW_FORM_flag_present:
- case DW_FORM_ref_sig8:
- case DW_FORM_GNU_addr_index:
- {
- uint64_t a = a_value.Unsigned();
- uint64_t b = b_value.Unsigned();
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
-
- case DW_FORM_sdata:
- {
- int64_t a = a_value.Signed();
- int64_t b = b_value.Signed();
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
-
- case DW_FORM_string:
- case DW_FORM_strp:
- case DW_FORM_GNU_str_index:
- {
- const char *a_string = a_value.AsCString();
- const char *b_string = b_value.AsCString();
- if (a_string == b_string)
- return 0;
- else if (a_string && b_string)
- return strcmp(a_string, b_string);
- else if (a_string == NULL)
- return -1; // A string is NULL, and B is valid
- else
- return 1; // A string valid, and B is NULL
- }
-
-
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- case DW_FORM_exprloc:
- {
- uint64_t a_len = a_value.Unsigned();
- uint64_t b_len = b_value.Unsigned();
- if (a_len < b_len)
- return -1;
- if (a_len > b_len)
- return 1;
- // The block lengths are the same
- return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
- }
- break;
-
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- {
- uint64_t a = a_value.Reference();
- uint64_t b = b_value.Reference();
- if (a < b)
- return -1;
- if (a > b)
- return 1;
- return 0;
- }
-
- case DW_FORM_indirect:
- assert(!"This shouldn't happen after the form has been extracted...");
- break;
-
- default:
- assert(!"Unhandled DW_FORM");
- break;
- }
+int DWARFFormValue::Compare(const DWARFFormValue &a_value,
+ const DWARFFormValue &b_value) {
+ dw_form_t a_form = a_value.Form();
+ dw_form_t b_form = b_value.Form();
+ if (a_form < b_form)
return -1;
+ if (a_form > b_form)
+ return 1;
+ switch (a_form) {
+ case DW_FORM_addr:
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_udata:
+ case DW_FORM_ref_addr:
+ case DW_FORM_sec_offset:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_GNU_addr_index: {
+ uint64_t a = a_value.Unsigned();
+ uint64_t b = b_value.Unsigned();
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ case DW_FORM_sdata: {
+ int64_t a = a_value.Signed();
+ int64_t b = b_value.Signed();
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_str_index: {
+ const char *a_string = a_value.AsCString();
+ const char *b_string = b_value.AsCString();
+ if (a_string == b_string)
+ return 0;
+ else if (a_string && b_string)
+ return strcmp(a_string, b_string);
+ else if (a_string == NULL)
+ return -1; // A string is NULL, and B is valid
+ else
+ return 1; // A string valid, and B is NULL
+ }
+
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_exprloc: {
+ uint64_t a_len = a_value.Unsigned();
+ uint64_t b_len = b_value.Unsigned();
+ if (a_len < b_len)
+ return -1;
+ if (a_len > b_len)
+ return 1;
+ // The block lengths are the same
+ return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
+ } break;
+
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata: {
+ uint64_t a = a_value.Reference();
+ uint64_t b = b_value.Reference();
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ case DW_FORM_indirect:
+ assert(!"This shouldn't happen after the form has been extracted...");
+ break;
+
+ default:
+ assert(!"Unhandled DW_FORM");
+ break;
+ }
+ return -1;
}
-
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h Tue Sep 6 15:57:50 2016
@@ -10,103 +10,87 @@
#ifndef SymbolFileDWARF_DWARFFormValue_h_
#define SymbolFileDWARF_DWARFFormValue_h_
-#include <stddef.h> // for NULL
#include "DWARFDataExtractor.h"
+#include <stddef.h> // for NULL
class DWARFCompileUnit;
-class DWARFFormValue
-{
+class DWARFFormValue {
public:
- typedef struct ValueTypeTag
- {
- ValueTypeTag() :
- value(),
- data(NULL)
- {
- value.uval = 0;
- }
-
- union
- {
- uint64_t uval;
- int64_t sval;
- const char* cstr;
- } value;
- const uint8_t* data;
- } ValueType;
-
- class FixedFormSizes
- {
- public:
- FixedFormSizes() :
- m_fix_sizes(nullptr), m_size(0)
- {}
-
- FixedFormSizes(const uint8_t* fix_sizes, size_t size) :
- m_fix_sizes(fix_sizes), m_size(size)
- {}
-
- uint8_t
- GetSize(uint32_t index) const
- {
- return index < m_size ? m_fix_sizes[index] : 0;
- }
-
- bool
- Empty() const
- {
- return m_size == 0;
- }
-
- private:
- const uint8_t* m_fix_sizes;
- size_t m_size;
- };
-
- enum
- {
- eValueTypeInvalid = 0,
- eValueTypeUnsigned,
- eValueTypeSigned,
- eValueTypeCStr,
- eValueTypeBlock
- };
-
- DWARFFormValue();
- DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form);
- const DWARFCompileUnit* GetCompileUnit () const { return m_cu; }
- void SetCompileUnit (const DWARFCompileUnit* cu) { m_cu = cu; }
- dw_form_t Form() const { return m_form; }
- void SetForm(dw_form_t form) { m_form = form; }
- const ValueType& Value() const { return m_value; }
- void Dump(lldb_private::Stream &s) const;
- bool ExtractValue(const lldb_private::DWARFDataExtractor& data,
- lldb::offset_t* offset_ptr);
- const uint8_t* BlockData() const;
- uint64_t Reference() const;
- uint64_t Reference (dw_offset_t offset) const;
- bool Boolean() const { return m_value.value.uval != 0; }
- uint64_t Unsigned() const { return m_value.value.uval; }
- void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
- int64_t Signed() const { return m_value.value.sval; }
- void SetSigned(int64_t sval) { m_value.value.sval = sval; }
- const char* AsCString() const;
- dw_addr_t Address() const;
- bool IsValid() const { return m_form != 0; }
- bool SkipValue(const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const;
- static bool SkipValue(const dw_form_t form, const lldb_private::DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu);
- static bool IsBlockForm(const dw_form_t form);
- static bool IsDataForm(const dw_form_t form);
- static FixedFormSizes GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64);
- static int Compare (const DWARFFormValue& a,
- const DWARFFormValue& b);
- void Clear();
+ typedef struct ValueTypeTag {
+ ValueTypeTag() : value(), data(NULL) { value.uval = 0; }
+
+ union {
+ uint64_t uval;
+ int64_t sval;
+ const char *cstr;
+ } value;
+ const uint8_t *data;
+ } ValueType;
+
+ class FixedFormSizes {
+ public:
+ FixedFormSizes() : m_fix_sizes(nullptr), m_size(0) {}
+
+ FixedFormSizes(const uint8_t *fix_sizes, size_t size)
+ : m_fix_sizes(fix_sizes), m_size(size) {}
+
+ uint8_t GetSize(uint32_t index) const {
+ return index < m_size ? m_fix_sizes[index] : 0;
+ }
+
+ bool Empty() const { return m_size == 0; }
+
+ private:
+ const uint8_t *m_fix_sizes;
+ size_t m_size;
+ };
+
+ enum {
+ eValueTypeInvalid = 0,
+ eValueTypeUnsigned,
+ eValueTypeSigned,
+ eValueTypeCStr,
+ eValueTypeBlock
+ };
+
+ DWARFFormValue();
+ DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form);
+ const DWARFCompileUnit *GetCompileUnit() const { return m_cu; }
+ void SetCompileUnit(const DWARFCompileUnit *cu) { m_cu = cu; }
+ dw_form_t Form() const { return m_form; }
+ void SetForm(dw_form_t form) { m_form = form; }
+ const ValueType &Value() const { return m_value; }
+ void Dump(lldb_private::Stream &s) const;
+ bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr);
+ const uint8_t *BlockData() const;
+ uint64_t Reference() const;
+ uint64_t Reference(dw_offset_t offset) const;
+ bool Boolean() const { return m_value.value.uval != 0; }
+ uint64_t Unsigned() const { return m_value.value.uval; }
+ void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
+ int64_t Signed() const { return m_value.value.sval; }
+ void SetSigned(int64_t sval) { m_value.value.sval = sval; }
+ const char *AsCString() const;
+ dw_addr_t Address() const;
+ bool IsValid() const { return m_form != 0; }
+ bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr) const;
+ static bool SkipValue(const dw_form_t form,
+ const lldb_private::DWARFDataExtractor &debug_info_data,
+ lldb::offset_t *offset_ptr, const DWARFCompileUnit *cu);
+ static bool IsBlockForm(const dw_form_t form);
+ static bool IsDataForm(const dw_form_t form);
+ static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size,
+ bool is_dwarf64);
+ static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
+ void Clear();
+
protected:
- const DWARFCompileUnit* m_cu; // Compile unit for this form
- dw_form_t m_form; // Form for this value
- ValueType m_value; // Contains all data for the form
+ const DWARFCompileUnit *m_cu; // Compile unit for this form
+ dw_form_t m_form; // Form for this value
+ ValueType m_value; // Contains all data for the form
};
-
-#endif // SymbolFileDWARF_DWARFFormValue_h_
+#endif // SymbolFileDWARF_DWARFFormValue_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp Tue Sep 6 15:57:50 2016
@@ -9,746 +9,635 @@
#include "HashedNameToDIE.h"
-void
-DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets)
-{
- const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
-}
-
-void
-DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- DIEArray &die_offsets)
-{
- if (tag == 0)
- {
- ExtractDIEArray (die_info_array, die_offsets);
- }
- else
- {
- const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches)
- {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
-}
-
-void
-DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets)
-{
- if (tag == 0)
- {
- ExtractDIEArray (die_info_array, die_offsets);
- }
- else
- {
- const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- if (qualified_name_hash != die_info_array[i].qualified_name_hash)
- continue;
- const dw_tag_t die_tag = die_info_array[i].tag;
- bool tag_matches = die_tag == 0 || tag == die_tag;
- if (!tag_matches)
- {
- if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
- }
- if (tag_matches)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
+void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
+ DIEArray &die_offsets) {
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
}
-void
-DWARFMappedHash::ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available,
- DIEArray &die_offsets)
-{
+void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ DIEArray &die_offsets) {
+ if (tag == 0) {
+ ExtractDIEArray(die_info_array, die_offsets);
+ } else {
const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- const dw_tag_t die_tag = die_info_array[i].tag;
- if (die_tag == 0 || die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
- {
- if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation)
- {
- if (return_implementation_only_if_available)
- {
- // We found the one true definition for this class, so
- // only return that
- die_offsets.clear();
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- return;
- }
- else
- {
- // Put the one true definition as the first entry so it
- // matches first
- die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
- else
- {
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
- }
- }
-}
-
-void
-DWARFMappedHash::ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
- uint32_t type_flag_mask,
- uint32_t type_flag_value,
- DIEArray &die_offsets)
-{
+ for (size_t i = 0; i < count; ++i) {
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches) {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches =
+ tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+ }
+}
+
+void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets) {
+ if (tag == 0) {
+ ExtractDIEArray(die_info_array, die_offsets);
+ } else {
const size_t count = die_info_array.size();
- for (size_t i=0; i<count; ++i)
- {
- if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
- die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
- }
-}
-
-const char *
-DWARFMappedHash::GetAtomTypeName (uint16_t atom)
-{
- switch (atom)
- {
- case eAtomTypeNULL: return "NULL";
- case eAtomTypeDIEOffset: return "die-offset";
- case eAtomTypeCUOffset: return "cu-offset";
- case eAtomTypeTag: return "die-tag";
- case eAtomTypeNameFlags: return "name-flags";
- case eAtomTypeTypeFlags: return "type-flags";
- case eAtomTypeQualNameHash: return "qualified-name-hash";
- }
- return "<invalid>";
-}
-
-DWARFMappedHash::DIEInfo::DIEInfo () :
- cu_offset (DW_INVALID_OFFSET),
- offset (DW_INVALID_OFFSET),
- tag (0),
- type_flags (0),
- qualified_name_hash (0)
-{
-}
-
-DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t c,
- dw_offset_t o,
- dw_tag_t t,
- uint32_t f,
- uint32_t h) :
- cu_offset (c),
- offset (o),
- tag (t),
- type_flags (f),
- qualified_name_hash (h)
-{
-}
-
-DWARFMappedHash::Prologue::Prologue (dw_offset_t _die_base_offset) :
- die_base_offset (_die_base_offset),
- atoms(),
- atom_mask (0),
- min_hash_data_byte_size(0),
- hash_data_has_fixed_byte_size(true)
-{
- // Define an array of DIE offsets by first defining an array,
- // and then define the atom type for the array, in this case
- // we have an array of DIE offsets
- AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
-}
-
-void
-DWARFMappedHash::Prologue::ClearAtoms ()
-{
- hash_data_has_fixed_byte_size = true;
- min_hash_data_byte_size = 0;
- atom_mask = 0;
- atoms.clear();
-}
-
-bool
-DWARFMappedHash::Prologue::ContainsAtom (AtomType atom_type) const
-{
- return (atom_mask & (1u << atom_type)) != 0;
-}
-
-void
-DWARFMappedHash::Prologue::Clear ()
-{
- die_base_offset = 0;
- ClearAtoms ();
-}
-
-void
-DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form)
-{
- atoms.push_back ({type, form});
- atom_mask |= 1u << type;
- switch (form)
- {
- case DW_FORM_indirect:
- case DW_FORM_exprloc:
- case DW_FORM_flag_present:
- case DW_FORM_ref_sig8:
- assert (!"Unhandled atom form");
- break;
-
- case DW_FORM_string:
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- hash_data_has_fixed_byte_size = false;
- LLVM_FALLTHROUGH;
- case DW_FORM_flag:
- case DW_FORM_data1:
- case DW_FORM_ref1:
- case DW_FORM_sec_offset:
- min_hash_data_byte_size += 1;
- break;
-
- case DW_FORM_block2:
- hash_data_has_fixed_byte_size = false;
- LLVM_FALLTHROUGH;
- case DW_FORM_data2:
- case DW_FORM_ref2:
- min_hash_data_byte_size += 2;
- break;
-
- case DW_FORM_block4:
- hash_data_has_fixed_byte_size = false;
- LLVM_FALLTHROUGH;
- case DW_FORM_data4:
- case DW_FORM_ref4:
- case DW_FORM_addr:
- case DW_FORM_ref_addr:
- case DW_FORM_strp:
- min_hash_data_byte_size += 4;
- break;
-
- case DW_FORM_data8:
- case DW_FORM_ref8:
- min_hash_data_byte_size += 8;
- break;
-
- }
-}
-
-lldb::offset_t
-DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data,
- lldb::offset_t offset)
-{
- ClearAtoms ();
-
- die_base_offset = data.GetU32 (&offset);
-
- const uint32_t atom_count = data.GetU32 (&offset);
- if (atom_count == 0x00060003u)
- {
- // Old format, deal with contents of old pre-release format
- while (data.GetU32(&offset))
- /* do nothing */;
-
- // Hardcode to the only known value for now.
- AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4);
- }
- else
- {
- for (uint32_t i=0; i<atom_count; ++i)
- {
- AtomType type = (AtomType)data.GetU16 (&offset);
- dw_form_t form = (dw_form_t)data.GetU16 (&offset);
- AppendAtom (type, form);
- }
- }
- return offset;
-}
-
-size_t
-DWARFMappedHash::Prologue::GetByteSize () const
-{
- // Add an extra count to the atoms size for the zero termination Atom that gets
- // written to disk
- return sizeof(die_base_offset) + sizeof(uint32_t) + atoms.size() * sizeof(Atom);
-}
-
-size_t
-DWARFMappedHash::Prologue::GetMinimumHashDataByteSize () const
-{
- return min_hash_data_byte_size;
-}
-
-bool
-DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const
-{
- return hash_data_has_fixed_byte_size;
-}
-
-size_t
-DWARFMappedHash::Header::GetByteSize (const HeaderData &header_data)
-{
- return header_data.GetByteSize();
+ for (size_t i = 0; i < count; ++i) {
+ if (qualified_name_hash != die_info_array[i].qualified_name_hash)
+ continue;
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches) {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches =
+ tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+ }
+}
+
+void DWARFMappedHash::ExtractClassOrStructDIEArray(
+ const DIEInfoArray &die_info_array,
+ bool return_implementation_only_if_available, DIEArray &die_offsets) {
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i) {
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ if (die_tag == 0 || die_tag == DW_TAG_class_type ||
+ die_tag == DW_TAG_structure_type) {
+ if (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) {
+ if (return_implementation_only_if_available) {
+ // We found the one true definition for this class, so
+ // only return that
+ die_offsets.clear();
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ return;
+ } else {
+ // Put the one true definition as the first entry so it
+ // matches first
+ die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+ } else {
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+ }
+ }
+}
+
+void DWARFMappedHash::ExtractTypesFromDIEArray(
+ const DIEInfoArray &die_info_array, uint32_t type_flag_mask,
+ uint32_t type_flag_value, DIEArray &die_offsets) {
+ const size_t count = die_info_array.size();
+ for (size_t i = 0; i < count; ++i) {
+ if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
+ die_offsets.emplace_back(die_info_array[i].cu_offset,
+ die_info_array[i].offset);
+ }
+}
+
+const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) {
+ switch (atom) {
+ case eAtomTypeNULL:
+ return "NULL";
+ case eAtomTypeDIEOffset:
+ return "die-offset";
+ case eAtomTypeCUOffset:
+ return "cu-offset";
+ case eAtomTypeTag:
+ return "die-tag";
+ case eAtomTypeNameFlags:
+ return "name-flags";
+ case eAtomTypeTypeFlags:
+ return "type-flags";
+ case eAtomTypeQualNameHash:
+ return "qualified-name-hash";
+ }
+ return "<invalid>";
+}
+
+DWARFMappedHash::DIEInfo::DIEInfo()
+ : cu_offset(DW_INVALID_OFFSET), offset(DW_INVALID_OFFSET), tag(0),
+ type_flags(0), qualified_name_hash(0) {}
+
+DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t,
+ uint32_t f, uint32_t h)
+ : cu_offset(c), offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
+
+DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
+ : die_base_offset(_die_base_offset), atoms(), atom_mask(0),
+ min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
+ // Define an array of DIE offsets by first defining an array,
+ // and then define the atom type for the array, in this case
+ // we have an array of DIE offsets
+ AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
+}
+
+void DWARFMappedHash::Prologue::ClearAtoms() {
+ hash_data_has_fixed_byte_size = true;
+ min_hash_data_byte_size = 0;
+ atom_mask = 0;
+ atoms.clear();
+}
+
+bool DWARFMappedHash::Prologue::ContainsAtom(AtomType atom_type) const {
+ return (atom_mask & (1u << atom_type)) != 0;
+}
+
+void DWARFMappedHash::Prologue::Clear() {
+ die_base_offset = 0;
+ ClearAtoms();
+}
+
+void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) {
+ atoms.push_back({type, form});
+ atom_mask |= 1u << type;
+ switch (form) {
+ case DW_FORM_indirect:
+ case DW_FORM_exprloc:
+ case DW_FORM_flag_present:
+ case DW_FORM_ref_sig8:
+ assert(!"Unhandled atom form");
+ break;
+
+ case DW_FORM_string:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ hash_data_has_fixed_byte_size = false;
+ LLVM_FALLTHROUGH;
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_sec_offset:
+ min_hash_data_byte_size += 1;
+ break;
+
+ case DW_FORM_block2:
+ hash_data_has_fixed_byte_size = false;
+ LLVM_FALLTHROUGH;
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ min_hash_data_byte_size += 2;
+ break;
+
+ case DW_FORM_block4:
+ hash_data_has_fixed_byte_size = false;
+ LLVM_FALLTHROUGH;
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ case DW_FORM_strp:
+ min_hash_data_byte_size += 4;
+ break;
+
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ min_hash_data_byte_size += 8;
+ break;
+ }
}
lldb::offset_t
-DWARFMappedHash::Header::Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
-{
- offset = MappedHash::Header<Prologue>::Read (data, offset);
- if (offset != UINT32_MAX)
- {
- offset = header_data.Read (data, offset);
- }
- return offset;
-}
-
-bool
-DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr,
- DIEInfo &hash_data) const
-{
- const size_t num_atoms = header_data.atoms.size();
- if (num_atoms == 0)
- return false;
-
- for (size_t i=0; i<num_atoms; ++i)
- {
- DWARFFormValue form_value (NULL, header_data.atoms[i].form);
-
- if (!form_value.ExtractValue(data, offset_ptr))
- return false;
-
- switch (header_data.atoms[i].type)
- {
- case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- hash_data.offset = (dw_offset_t)form_value.Reference (header_data.die_base_offset);
- break;
-
- case eAtomTypeTag: // DW_TAG value for the DIE
- hash_data.tag = (dw_tag_t)form_value.Unsigned ();
- break;
-
- case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- hash_data.type_flags = (uint32_t)form_value.Unsigned ();
- break;
-
- case eAtomTypeQualNameHash: // Flags from enum TypeFlags
- hash_data.qualified_name_hash = form_value.Unsigned ();
- break;
-
- default:
- // We can always skip atoms we don't know about
- break;
- }
- }
- return true;
-}
-
-void
-DWARFMappedHash::Header::Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const
-{
- const size_t num_atoms = header_data.atoms.size();
- for (size_t i=0; i<num_atoms; ++i)
- {
- if (i > 0)
- strm.PutCString (", ");
-
- DWARFFormValue form_value (NULL, header_data.atoms[i].form);
- switch (header_data.atoms[i].type)
- {
- case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- strm.Printf ("{0x%8.8x}", hash_data.offset);
- break;
-
- case eAtomTypeTag: // DW_TAG value for the DIE
- {
- const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag);
- if (tag_cstr)
- strm.PutCString (tag_cstr);
- else
- strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag);
- }
- break;
-
- case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- strm.Printf ("0x%2.2x", hash_data.type_flags);
- if (hash_data.type_flags)
- {
- strm.PutCString (" (");
- if (hash_data.type_flags & eTypeFlagClassIsImplementation)
- strm.PutCString (" implementation");
- strm.PutCString (" )");
- }
- break;
-
- case eAtomTypeQualNameHash: // Flags from enum TypeFlags
- strm.Printf ("0x%8.8x", hash_data.qualified_name_hash);
- break;
-
- default:
- strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
- break;
- }
- }
-}
-
-DWARFMappedHash::MemoryTable::MemoryTable (lldb_private::DWARFDataExtractor &table_data,
- const lldb_private::DWARFDataExtractor &string_table,
- const char *name) :
- MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray> (table_data),
- m_data (table_data),
- m_string_table (string_table),
- m_name (name)
-{
-}
+DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data,
+ lldb::offset_t offset) {
+ ClearAtoms();
+
+ die_base_offset = data.GetU32(&offset);
+
+ const uint32_t atom_count = data.GetU32(&offset);
+ if (atom_count == 0x00060003u) {
+ // Old format, deal with contents of old pre-release format
+ while (data.GetU32(&offset))
+ /* do nothing */;
+
+ // Hardcode to the only known value for now.
+ AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
+ } else {
+ for (uint32_t i = 0; i < atom_count; ++i) {
+ AtomType type = (AtomType)data.GetU16(&offset);
+ dw_form_t form = (dw_form_t)data.GetU16(&offset);
+ AppendAtom(type, form);
+ }
+ }
+ return offset;
+}
+
+size_t DWARFMappedHash::Prologue::GetByteSize() const {
+ // Add an extra count to the atoms size for the zero termination Atom that
+ // gets
+ // written to disk
+ return sizeof(die_base_offset) + sizeof(uint32_t) +
+ atoms.size() * sizeof(Atom);
+}
+
+size_t DWARFMappedHash::Prologue::GetMinimumHashDataByteSize() const {
+ return min_hash_data_byte_size;
+}
+
+bool DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const {
+ return hash_data_has_fixed_byte_size;
+}
+
+size_t DWARFMappedHash::Header::GetByteSize(const HeaderData &header_data) {
+ return header_data.GetByteSize();
+}
+
+lldb::offset_t DWARFMappedHash::Header::Read(lldb_private::DataExtractor &data,
+ lldb::offset_t offset) {
+ offset = MappedHash::Header<Prologue>::Read(data, offset);
+ if (offset != UINT32_MAX) {
+ offset = header_data.Read(data, offset);
+ }
+ return offset;
+}
+
+bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr,
+ DIEInfo &hash_data) const {
+ const size_t num_atoms = header_data.atoms.size();
+ if (num_atoms == 0)
+ return false;
+
+ for (size_t i = 0; i < num_atoms; ++i) {
+ DWARFFormValue form_value(NULL, header_data.atoms[i].form);
+
+ if (!form_value.ExtractValue(data, offset_ptr))
+ return false;
+
+ switch (header_data.atoms[i].type) {
+ case eAtomTypeDIEOffset: // DIE offset, check form for encoding
+ hash_data.offset =
+ (dw_offset_t)form_value.Reference(header_data.die_base_offset);
+ break;
+
+ case eAtomTypeTag: // DW_TAG value for the DIE
+ hash_data.tag = (dw_tag_t)form_value.Unsigned();
+ break;
+
+ case eAtomTypeTypeFlags: // Flags from enum TypeFlags
+ hash_data.type_flags = (uint32_t)form_value.Unsigned();
+ break;
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ hash_data.qualified_name_hash = form_value.Unsigned();
+ break;
+
+ default:
+ // We can always skip atoms we don't know about
+ break;
+ }
+ }
+ return true;
+}
+
+void DWARFMappedHash::Header::Dump(lldb_private::Stream &strm,
+ const DIEInfo &hash_data) const {
+ const size_t num_atoms = header_data.atoms.size();
+ for (size_t i = 0; i < num_atoms; ++i) {
+ if (i > 0)
+ strm.PutCString(", ");
+
+ DWARFFormValue form_value(NULL, header_data.atoms[i].form);
+ switch (header_data.atoms[i].type) {
+ case eAtomTypeDIEOffset: // DIE offset, check form for encoding
+ strm.Printf("{0x%8.8x}", hash_data.offset);
+ break;
+
+ case eAtomTypeTag: // DW_TAG value for the DIE
+ {
+ const char *tag_cstr = lldb_private::DW_TAG_value_to_name(hash_data.tag);
+ if (tag_cstr)
+ strm.PutCString(tag_cstr);
+ else
+ strm.Printf("DW_TAG_(0x%4.4x)", hash_data.tag);
+ } break;
+
+ case eAtomTypeTypeFlags: // Flags from enum TypeFlags
+ strm.Printf("0x%2.2x", hash_data.type_flags);
+ if (hash_data.type_flags) {
+ strm.PutCString(" (");
+ if (hash_data.type_flags & eTypeFlagClassIsImplementation)
+ strm.PutCString(" implementation");
+ strm.PutCString(" )");
+ }
+ break;
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ strm.Printf("0x%8.8x", hash_data.qualified_name_hash);
+ break;
+
+ default:
+ strm.Printf("AtomType(0x%x)", header_data.atoms[i].type);
+ break;
+ }
+ }
+}
+
+DWARFMappedHash::MemoryTable::MemoryTable(
+ lldb_private::DWARFDataExtractor &table_data,
+ const lldb_private::DWARFDataExtractor &string_table, const char *name)
+ : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data),
+ m_data(table_data), m_string_table(string_table), m_name(name) {}
const char *
-DWARFMappedHash::MemoryTable::GetStringForKeyType (KeyType key) const
-{
- // The key in the DWARF table is the .debug_str offset for the string
- return m_string_table.PeekCStr (key);
+DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const {
+ // The key in the DWARF table is the .debug_str offset for the string
+ return m_string_table.PeekCStr(key);
}
-bool
-DWARFMappedHash::MemoryTable::ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const
-{
- lldb::offset_t offset = hash_data_offset;
- offset += 4; // Skip string table offset that contains offset of hash name in .debug_str
- const uint32_t count = m_data.GetU32 (&offset);
- if (count > 0)
- {
- hash_data.resize(count);
- for (uint32_t i=0; i<count; ++i)
- {
- if (!m_header.Read(m_data, &offset, hash_data[i]))
- return false;
- }
+bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset,
+ HashData &hash_data) const {
+ lldb::offset_t offset = hash_data_offset;
+ offset += 4; // Skip string table offset that contains offset of hash name in
+ // .debug_str
+ const uint32_t count = m_data.GetU32(&offset);
+ if (count > 0) {
+ hash_data.resize(count);
+ for (uint32_t i = 0; i < count; ++i) {
+ if (!m_header.Read(m_data, &offset, hash_data[i]))
+ return false;
}
- else
- hash_data.clear();
- return true;
+ } else
+ hash_data.clear();
+ return true;
}
DWARFMappedHash::MemoryTable::Result
-DWARFMappedHash::MemoryTable::GetHashDataForName (const char *name,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const
-{
- pair.key = m_data.GetU32 (hash_data_offset_ptr);
- pair.value.clear();
-
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
- if (pair.key == 0)
- return eResultEndOfHashData;
-
- // There definitely should be a string for this string offset, if
- // there isn't, there is something wrong, return and error
- const char *strp_cstr = m_string_table.PeekCStr (pair.key);
- if (strp_cstr == NULL)
- {
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
-
- const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
- {
- // We have at least one HashData entry, and we have enough
- // data to parse at least "count" HashData entries.
-
- // First make sure the entire C string matches...
- const bool match = strcmp (name, strp_cstr) == 0;
-
- if (!match && m_header.header_data.HashDataHasFixedByteSize())
- {
- // If the string doesn't match and we have fixed size data,
- // we can just add the total byte size of all HashData objects
- // to the hash data offset and be done...
- *hash_data_offset_ptr += min_total_hash_data_size;
- }
- else
- {
- // If the string does match, or we don't have fixed size data
- // then we need to read the hash data as a stream. If the
- // string matches we also append all HashData objects to the
- // value array.
- for (uint32_t i=0; i<count; ++i)
- {
- DIEInfo die_info;
- if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
- {
- // Only happened if the HashData of the string matched...
- if (match)
- pair.value.push_back (die_info);
- }
- else
- {
- // Something went wrong while reading the data
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
- }
- }
- // Return the correct response depending on if the string matched
- // or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will get called
- // again for the next key/value or the key terminator
- // which in our case is a zero .debug_str offset.
- }
+DWARFMappedHash::MemoryTable::GetHashDataForName(
+ const char *name, lldb::offset_t *hash_data_offset_ptr, Pair &pair) const {
+ pair.key = m_data.GetU32(hash_data_offset_ptr);
+ pair.value.clear();
+
+ // If the key is zero, this terminates our chain of HashData objects
+ // for this hash value.
+ if (pair.key == 0)
+ return eResultEndOfHashData;
+
+ // There definitely should be a string for this string offset, if
+ // there isn't, there is something wrong, return and error
+ const char *strp_cstr = m_string_table.PeekCStr(pair.key);
+ if (strp_cstr == NULL) {
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
+
+ const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
+ const size_t min_total_hash_data_size =
+ count * m_header.header_data.GetMinimumHashDataByteSize();
+ if (count > 0 &&
+ m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
+ // We have at least one HashData entry, and we have enough
+ // data to parse at least "count" HashData entries.
+
+ // First make sure the entire C string matches...
+ const bool match = strcmp(name, strp_cstr) == 0;
+
+ if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
+ // If the string doesn't match and we have fixed size data,
+ // we can just add the total byte size of all HashData objects
+ // to the hash data offset and be done...
+ *hash_data_offset_ptr += min_total_hash_data_size;
+ } else {
+ // If the string does match, or we don't have fixed size data
+ // then we need to read the hash data as a stream. If the
+ // string matches we also append all HashData objects to the
+ // value array.
+ for (uint32_t i = 0; i < count; ++i) {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
+ // Only happened if the HashData of the string matched...
+ if (match)
+ pair.value.push_back(die_info);
+ } else {
+ // Something went wrong while reading the data
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
+ }
+ }
+ // Return the correct response depending on if the string matched
+ // or not...
+ if (match)
+ return eResultKeyMatch; // The key (cstring) matches and we have lookup
+ // results!
else
- {
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
+ return eResultKeyMismatch; // The key doesn't match, this function will
+ // get called
+ // again for the next key/value or the key terminator
+ // which in our case is a zero .debug_str offset.
+ } else {
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
}
DWARFMappedHash::MemoryTable::Result
-DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression (
- const lldb_private::RegularExpression& regex,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const
-{
- pair.key = m_data.GetU32 (hash_data_offset_ptr);
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
- if (pair.key == 0)
- return eResultEndOfHashData;
-
- // There definitely should be a string for this string offset, if
- // there isn't, there is something wrong, return and error
- const char *strp_cstr = m_string_table.PeekCStr (pair.key);
- if (strp_cstr == NULL)
- return eResultError;
-
- const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const size_t min_total_hash_data_size = count * m_header.header_data.GetMinimumHashDataByteSize();
- if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
- {
- const bool match = regex.Execute(strp_cstr);
-
- if (!match && m_header.header_data.HashDataHasFixedByteSize())
- {
- // If the regex doesn't match and we have fixed size data,
- // we can just add the total byte size of all HashData objects
- // to the hash data offset and be done...
- *hash_data_offset_ptr += min_total_hash_data_size;
- }
- else
- {
- // If the string does match, or we don't have fixed size data
- // then we need to read the hash data as a stream. If the
- // string matches we also append all HashData objects to the
- // value array.
- for (uint32_t i=0; i<count; ++i)
- {
- DIEInfo die_info;
- if (m_header.Read(m_data, hash_data_offset_ptr, die_info))
- {
- // Only happened if the HashData of the string matched...
- if (match)
- pair.value.push_back (die_info);
- }
- else
- {
- // Something went wrong while reading the data
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
- }
- }
- // Return the correct response depending on if the string matched
- // or not...
- if (match)
- return eResultKeyMatch; // The key (cstring) matches and we have lookup results!
- else
- return eResultKeyMismatch; // The key doesn't match, this function will get called
- // again for the next key/value or the key terminator
- // which in our case is a zero .debug_str offset.
- }
+DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression(
+ const lldb_private::RegularExpression ®ex,
+ lldb::offset_t *hash_data_offset_ptr, Pair &pair) const {
+ pair.key = m_data.GetU32(hash_data_offset_ptr);
+ // If the key is zero, this terminates our chain of HashData objects
+ // for this hash value.
+ if (pair.key == 0)
+ return eResultEndOfHashData;
+
+ // There definitely should be a string for this string offset, if
+ // there isn't, there is something wrong, return and error
+ const char *strp_cstr = m_string_table.PeekCStr(pair.key);
+ if (strp_cstr == NULL)
+ return eResultError;
+
+ const uint32_t count = m_data.GetU32(hash_data_offset_ptr);
+ const size_t min_total_hash_data_size =
+ count * m_header.header_data.GetMinimumHashDataByteSize();
+ if (count > 0 &&
+ m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr,
+ min_total_hash_data_size)) {
+ const bool match = regex.Execute(strp_cstr);
+
+ if (!match && m_header.header_data.HashDataHasFixedByteSize()) {
+ // If the regex doesn't match and we have fixed size data,
+ // we can just add the total byte size of all HashData objects
+ // to the hash data offset and be done...
+ *hash_data_offset_ptr += min_total_hash_data_size;
+ } else {
+ // If the string does match, or we don't have fixed size data
+ // then we need to read the hash data as a stream. If the
+ // string matches we also append all HashData objects to the
+ // value array.
+ for (uint32_t i = 0; i < count; ++i) {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) {
+ // Only happened if the HashData of the string matched...
+ if (match)
+ pair.value.push_back(die_info);
+ } else {
+ // Something went wrong while reading the data
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
+ }
+ }
+ // Return the correct response depending on if the string matched
+ // or not...
+ if (match)
+ return eResultKeyMatch; // The key (cstring) matches and we have lookup
+ // results!
else
- {
- *hash_data_offset_ptr = UINT32_MAX;
- return eResultError;
- }
-}
-
-size_t
-DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex (
- const lldb_private::RegularExpression& regex,
- DIEInfoArray &die_info_array) const
-{
- const uint32_t hash_count = m_header.hashes_count;
- Pair pair;
- for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
- {
- lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
- while (hash_data_offset != UINT32_MAX)
- {
- const lldb::offset_t prev_hash_data_offset = hash_data_offset;
- Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
- if (prev_hash_data_offset == hash_data_offset)
- break;
-
- // Check the result of getting our hash data
- switch (hash_result)
- {
- case eResultKeyMatch:
- case eResultKeyMismatch:
- // Whether we matches or not, it doesn't matter, we
- // keep looking.
- break;
-
- case eResultEndOfHashData:
- case eResultError:
- hash_data_offset = UINT32_MAX;
- break;
- }
- }
- }
- die_info_array.swap (pair.value);
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::AppendAllDIEsInRange (const uint32_t die_offset_start,
- const uint32_t die_offset_end,
- DIEInfoArray &die_info_array) const
-{
- const uint32_t hash_count = m_header.hashes_count;
- for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
- {
- bool done = false;
- lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
- while (!done && hash_data_offset != UINT32_MAX)
- {
- KeyType key = m_data.GetU32 (&hash_data_offset);
- // If the key is zero, this terminates our chain of HashData objects
- // for this hash value.
- if (key == 0)
- break;
-
- const uint32_t count = m_data.GetU32 (&hash_data_offset);
- for (uint32_t i=0; i<count; ++i)
- {
- DIEInfo die_info;
- if (m_header.Read(m_data, &hash_data_offset, die_info))
- {
- if (die_info.offset == 0)
- done = true;
- if (die_offset_start <= die_info.offset && die_info.offset < die_offset_end)
- die_info_array.push_back(die_info);
- }
- }
- }
- }
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEArray &die_offsets)
-{
- if (!name || !name[0])
- return 0;
-
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray (die_info_array, die_offsets);
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::FindByNameAndTag (const char *name,
- const dw_tag_t tag,
- DIEArray &die_offsets)
-{
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray (die_info_array, tag, die_offsets);
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash (const char *name,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets)
-{
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets);
- return die_info_array.size();
-}
-
-size_t
-DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName (const char *name,
- DIEArray &die_offsets,
- bool must_be_implementation)
-{
- DIEInfoArray die_info_array;
- if (FindByName(name, die_info_array))
- {
- if (must_be_implementation && GetHeader().header_data.ContainsAtom (eAtomTypeTypeFlags))
- {
- // If we have two atoms, then we have the DIE offset and
- // the type flags so we can find the objective C class
- // efficiently.
- DWARFMappedHash::ExtractTypesFromDIEArray (die_info_array,
- UINT32_MAX,
- eTypeFlagClassIsImplementation,
- die_offsets);
- }
- else
- {
- // We don't only want the one true definition, so try and see
- // what we can find, and only return class or struct DIEs.
- // If we do have the full implementation, then return it alone,
- // else return all possible matches.
- const bool return_implementation_only_if_available = true;
- DWARFMappedHash::ExtractClassOrStructDIEArray (die_info_array,
- return_implementation_only_if_available,
- die_offsets);
- }
- }
- return die_offsets.size();
-}
+ return eResultKeyMismatch; // The key doesn't match, this function will
+ // get called
+ // again for the next key/value or the key terminator
+ // which in our case is a zero .debug_str offset.
+ } else {
+ *hash_data_offset_ptr = UINT32_MAX;
+ return eResultError;
+ }
+}
+
+size_t DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex(
+ const lldb_private::RegularExpression ®ex,
+ DIEInfoArray &die_info_array) const {
+ const uint32_t hash_count = m_header.hashes_count;
+ Pair pair;
+ for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) {
+ lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx);
+ while (hash_data_offset != UINT32_MAX) {
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
+ Result hash_result =
+ AppendHashDataForRegularExpression(regex, &hash_data_offset, pair);
+ if (prev_hash_data_offset == hash_data_offset)
+ break;
+
+ // Check the result of getting our hash data
+ switch (hash_result) {
+ case eResultKeyMatch:
+ case eResultKeyMismatch:
+ // Whether we matches or not, it doesn't matter, we
+ // keep looking.
+ break;
+
+ case eResultEndOfHashData:
+ case eResultError:
+ hash_data_offset = UINT32_MAX;
+ break;
+ }
+ }
+ }
+ die_info_array.swap(pair.value);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::AppendAllDIEsInRange(
+ const uint32_t die_offset_start, const uint32_t die_offset_end,
+ DIEInfoArray &die_info_array) const {
+ const uint32_t hash_count = m_header.hashes_count;
+ for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) {
+ bool done = false;
+ lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx);
+ while (!done && hash_data_offset != UINT32_MAX) {
+ KeyType key = m_data.GetU32(&hash_data_offset);
+ // If the key is zero, this terminates our chain of HashData objects
+ // for this hash value.
+ if (key == 0)
+ break;
+
+ const uint32_t count = m_data.GetU32(&hash_data_offset);
+ for (uint32_t i = 0; i < count; ++i) {
+ DIEInfo die_info;
+ if (m_header.Read(m_data, &hash_data_offset, die_info)) {
+ if (die_info.offset == 0)
+ done = true;
+ if (die_offset_start <= die_info.offset &&
+ die_info.offset < die_offset_end)
+ die_info_array.push_back(die_info);
+ }
+ }
+ }
+ }
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
+ DIEArray &die_offsets) {
+ if (!name || !name[0])
+ return 0;
-size_t
-DWARFMappedHash::MemoryTable::FindByName (const char *name, DIEInfoArray &die_info_array)
-{
- if (!name || !name[0])
- return 0;
-
- Pair kv_pair;
- size_t old_size = die_info_array.size();
- if (Find (name, kv_pair))
- {
- die_info_array.swap(kv_pair.value);
- return die_info_array.size() - old_size;
- }
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray(die_info_array, die_offsets);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindByNameAndTag(const char *name,
+ const dw_tag_t tag,
+ DIEArray &die_offsets) {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray(die_info_array, tag, die_offsets);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash(
+ const char *name, const dw_tag_t tag, const uint32_t qualified_name_hash,
+ DIEArray &die_offsets) {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash,
+ die_offsets);
+ return die_info_array.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName(
+ const char *name, DIEArray &die_offsets, bool must_be_implementation) {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array)) {
+ if (must_be_implementation &&
+ GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) {
+ // If we have two atoms, then we have the DIE offset and
+ // the type flags so we can find the objective C class
+ // efficiently.
+ DWARFMappedHash::ExtractTypesFromDIEArray(die_info_array, UINT32_MAX,
+ eTypeFlagClassIsImplementation,
+ die_offsets);
+ } else {
+ // We don't only want the one true definition, so try and see
+ // what we can find, and only return class or struct DIEs.
+ // If we do have the full implementation, then return it alone,
+ // else return all possible matches.
+ const bool return_implementation_only_if_available = true;
+ DWARFMappedHash::ExtractClassOrStructDIEArray(
+ die_info_array, return_implementation_only_if_available, die_offsets);
+ }
+ }
+ return die_offsets.size();
+}
+
+size_t DWARFMappedHash::MemoryTable::FindByName(const char *name,
+ DIEInfoArray &die_info_array) {
+ if (!name || !name[0])
return 0;
+
+ Pair kv_pair;
+ size_t old_size = die_info_array.size();
+ if (Find(name, kv_pair)) {
+ die_info_array.swap(kv_pair.value);
+ return die_info_array.size() - old_size;
+ }
+ return 0;
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h Tue Sep 6 15:57:50 2016
@@ -12,10 +12,10 @@
#include <vector>
-#include "lldb/lldb-defines.h"
-#include "lldb/Core/dwarf.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/MappedHash.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/dwarf.h"
+#include "lldb/lldb-defines.h"
#include "DWARFDefines.h"
#include "DWARFFormValue.h"
@@ -25,195 +25,169 @@ class SymbolFileDWARF;
class DWARFCompileUnit;
class DWARFDebugInfoEntry;
-class DWARFMappedHash
-{
+class DWARFMappedHash {
public:
- enum AtomType : uint16_t
- {
- eAtomTypeNULL = 0u,
- eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
- eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question
- eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
- eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
- eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name (since all hash entries are basename only)
- // For example a type like "std::vector<int>::iterator" would have a name of "iterator"
- // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not have to pull
- // in debug info for a type when we know the fully qualified name.
- };
-
- // Bit definitions for the eAtomTypeTypeFlags flags
- enum TypeFlags
- {
- // Always set for C++, only set for ObjC if this is the
- // @implementation for class
- eTypeFlagClassIsImplementation = ( 1u << 1 )
- };
-
- struct DIEInfo
- {
- dw_offset_t cu_offset;
- dw_offset_t offset; // The DIE offset
- dw_tag_t tag;
- uint32_t type_flags; // Any flags for this DIEInfo
- uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
-
- DIEInfo ();
- DIEInfo (dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
- };
-
- struct Atom
- {
- AtomType type;
- dw_form_t form;
- };
-
- typedef std::vector<DIEInfo> DIEInfoArray;
- typedef std::vector<Atom> AtomArray;
-
- class Prologue
- {
- public:
- Prologue (dw_offset_t _die_base_offset = 0);
-
- void
- ClearAtoms ();
-
- bool
- ContainsAtom (AtomType atom_type) const;
-
- void
- Clear ();
-
- void
- AppendAtom (AtomType type, dw_form_t form);
-
- lldb::offset_t
- Read (const lldb_private::DataExtractor &data, lldb::offset_t offset);
-
- size_t
- GetByteSize () const;
-
- size_t
- GetMinimumHashDataByteSize () const;
-
- bool
- HashDataHasFixedByteSize() const;
-
- // DIE offset base so die offsets in hash_data can be CU relative
- dw_offset_t die_base_offset;
- AtomArray atoms;
- uint32_t atom_mask;
- size_t min_hash_data_byte_size;
- bool hash_data_has_fixed_byte_size;
- };
-
- class Header : public MappedHash::Header<Prologue>
- {
- public:
- size_t
- GetByteSize (const HeaderData &header_data) override;
-
- lldb::offset_t
- Read (lldb_private::DataExtractor &data, lldb::offset_t offset) override;
-
- bool
- Read (const lldb_private::DWARFDataExtractor &data,
- lldb::offset_t *offset_ptr,
- DIEInfo &hash_data) const;
-
- void
- Dump (lldb_private::Stream& strm, const DIEInfo &hash_data) const;
- };
-
- // A class for reading and using a saved hash table from a block of data
- // in memory
- class MemoryTable : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, DIEInfoArray>
- {
- public:
- MemoryTable (lldb_private::DWARFDataExtractor &table_data,
- const lldb_private::DWARFDataExtractor &string_table,
- const char *name);
-
- const char *
- GetStringForKeyType (KeyType key) const override;
-
- bool
- ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const override;
-
- size_t
- AppendAllDIEsThatMatchingRegex (const lldb_private::RegularExpression& regex,
- DIEInfoArray &die_info_array) const;
-
- size_t
- AppendAllDIEsInRange (const uint32_t die_offset_start,
- const uint32_t die_offset_end,
- DIEInfoArray &die_info_array) const;
-
- size_t
- FindByName (const char *name, DIEArray &die_offsets);
-
- size_t
- FindByNameAndTag (const char *name, const dw_tag_t tag, DIEArray &die_offsets);
-
- size_t
- FindByNameAndTagAndQualifiedNameHash (const char *name,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets);
-
- size_t
- FindCompleteObjCClassByName (const char *name,
- DIEArray &die_offsets,
- bool must_be_implementation);
-
- protected:
- Result
- AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const;
-
- size_t
- FindByName (const char *name, DIEInfoArray &die_info_array);
-
- Result
- GetHashDataForName (const char *name,
- lldb::offset_t* hash_data_offset_ptr,
- Pair &pair) const override;
-
- const lldb_private::DWARFDataExtractor &m_data;
- const lldb_private::DWARFDataExtractor &m_string_table;
- std::string m_name;
- };
+ enum AtomType : uint16_t {
+ eAtomTypeNULL = 0u,
+ eAtomTypeDIEOffset = 1u, // DIE offset, check form for encoding
+ eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that
+ // contains the item in question
+ eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1
+ // (if no tags exceed 255) or DW_FORM_data2
+ eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
+ eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
+ eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name
+ // (since all hash entries are basename only)
+ // For example a type like "std::vector<int>::iterator" would have a name of
+ // "iterator"
+ // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not
+ // have to pull
+ // in debug info for a type when we know the fully qualified name.
+ };
+
+ // Bit definitions for the eAtomTypeTypeFlags flags
+ enum TypeFlags {
+ // Always set for C++, only set for ObjC if this is the
+ // @implementation for class
+ eTypeFlagClassIsImplementation = (1u << 1)
+ };
+
+ struct DIEInfo {
+ dw_offset_t cu_offset;
+ dw_offset_t offset; // The DIE offset
+ dw_tag_t tag;
+ uint32_t type_flags; // Any flags for this DIEInfo
+ uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
+
+ DIEInfo();
+ DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
+ };
+
+ struct Atom {
+ AtomType type;
+ dw_form_t form;
+ };
+
+ typedef std::vector<DIEInfo> DIEInfoArray;
+ typedef std::vector<Atom> AtomArray;
+
+ class Prologue {
+ public:
+ Prologue(dw_offset_t _die_base_offset = 0);
+
+ void ClearAtoms();
+
+ bool ContainsAtom(AtomType atom_type) const;
+
+ void Clear();
+
+ void AppendAtom(AtomType type, dw_form_t form);
+
+ lldb::offset_t Read(const lldb_private::DataExtractor &data,
+ lldb::offset_t offset);
+
+ size_t GetByteSize() const;
+
+ size_t GetMinimumHashDataByteSize() const;
+
+ bool HashDataHasFixedByteSize() const;
+
+ // DIE offset base so die offsets in hash_data can be CU relative
+ dw_offset_t die_base_offset;
+ AtomArray atoms;
+ uint32_t atom_mask;
+ size_t min_hash_data_byte_size;
+ bool hash_data_has_fixed_byte_size;
+ };
+
+ class Header : public MappedHash::Header<Prologue> {
+ public:
+ size_t GetByteSize(const HeaderData &header_data) override;
+
+ lldb::offset_t Read(lldb_private::DataExtractor &data,
+ lldb::offset_t offset) override;
+
+ bool Read(const lldb_private::DWARFDataExtractor &data,
+ lldb::offset_t *offset_ptr, DIEInfo &hash_data) const;
+
+ void Dump(lldb_private::Stream &strm, const DIEInfo &hash_data) const;
+ };
+
+ // A class for reading and using a saved hash table from a block of data
+ // in memory
+ class MemoryTable
+ : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header,
+ DIEInfoArray> {
+ public:
+ MemoryTable(lldb_private::DWARFDataExtractor &table_data,
+ const lldb_private::DWARFDataExtractor &string_table,
+ const char *name);
+
+ const char *GetStringForKeyType(KeyType key) const override;
+
+ bool ReadHashData(uint32_t hash_data_offset,
+ HashData &hash_data) const override;
+
+ size_t
+ AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex,
+ DIEInfoArray &die_info_array) const;
+
+ size_t AppendAllDIEsInRange(const uint32_t die_offset_start,
+ const uint32_t die_offset_end,
+ DIEInfoArray &die_info_array) const;
+
+ size_t FindByName(const char *name, DIEArray &die_offsets);
+
+ size_t FindByNameAndTag(const char *name, const dw_tag_t tag,
+ DIEArray &die_offsets);
+
+ size_t
+ FindByNameAndTagAndQualifiedNameHash(const char *name, const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets);
+
+ size_t FindCompleteObjCClassByName(const char *name, DIEArray &die_offsets,
+ bool must_be_implementation);
+
+ protected:
+ Result AppendHashDataForRegularExpression(
+ const lldb_private::RegularExpression ®ex,
+ lldb::offset_t *hash_data_offset_ptr, Pair &pair) const;
+
+ size_t FindByName(const char *name, DIEInfoArray &die_info_array);
+
+ Result GetHashDataForName(const char *name,
+ lldb::offset_t *hash_data_offset_ptr,
+ Pair &pair) const override;
+
+ const lldb_private::DWARFDataExtractor &m_data;
+ const lldb_private::DWARFDataExtractor &m_string_table;
+ std::string m_name;
+ };
- static void
- ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets);
+ static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+ DIEArray &die_offsets);
protected:
- static void
- ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- DIEArray &die_offsets);
-
- static void
- ExtractDIEArray (const DIEInfoArray &die_info_array,
- const dw_tag_t tag,
- const uint32_t qualified_name_hash,
- DIEArray &die_offsets);
-
- static void
- ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
- bool return_implementation_only_if_available,
- DIEArray &die_offsets);
-
- static void
- ExtractTypesFromDIEArray (const DIEInfoArray &die_info_array,
- uint32_t type_flag_mask,
- uint32_t type_flag_value,
+ static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag, DIEArray &die_offsets);
+
+ static void ExtractDIEArray(const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
DIEArray &die_offsets);
- static const char *
- GetAtomTypeName (uint16_t atom);
+ static void
+ ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array,
+ bool return_implementation_only_if_available,
+ DIEArray &die_offsets);
+
+ static void ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array,
+ uint32_t type_flag_mask,
+ uint32_t type_flag_value,
+ DIEArray &die_offsets);
+
+ static const char *GetAtomTypeName(uint16_t atom);
};
-#endif // SymbolFileDWARF_HashedNameToDIE_h_
+#endif // SymbolFileDWARF_HashedNameToDIE_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Tue Sep 6 15:57:50 2016
@@ -9,227 +9,195 @@
#include "LogChannelDWARF.h"
-#include "lldb/Interpreter/Args.h"
+#include "SymbolFileDWARF.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
-#include "SymbolFileDWARF.h"
+#include "lldb/Interpreter/Args.h"
using namespace lldb;
using namespace lldb_private;
-
// when the one and only logging channel is enabled, then this will be non NULL.
-static LogChannelDWARF* g_log_channel = NULL;
-
-LogChannelDWARF::LogChannelDWARF () :
- LogChannel ()
-{
-}
-
-LogChannelDWARF::~LogChannelDWARF ()
-{
-}
+static LogChannelDWARF *g_log_channel = NULL;
+LogChannelDWARF::LogChannelDWARF() : LogChannel() {}
-void
-LogChannelDWARF::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- LogChannelDWARF::CreateInstance);
-}
-
-void
-LogChannelDWARF::Terminate()
-{
- PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
-}
+LogChannelDWARF::~LogChannelDWARF() {}
-LogChannel*
-LogChannelDWARF::CreateInstance ()
-{
- return new LogChannelDWARF ();
+void LogChannelDWARF::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ LogChannelDWARF::CreateInstance);
}
-lldb_private::ConstString
-LogChannelDWARF::GetPluginNameStatic()
-{
- return SymbolFileDWARF::GetPluginNameStatic();
+void LogChannelDWARF::Terminate() {
+ PluginManager::UnregisterPlugin(LogChannelDWARF::CreateInstance);
}
-const char *
-LogChannelDWARF::GetPluginDescriptionStatic()
-{
- return "DWARF log channel for debugging plug-in issues.";
-}
+LogChannel *LogChannelDWARF::CreateInstance() { return new LogChannelDWARF(); }
-lldb_private::ConstString
-LogChannelDWARF::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString LogChannelDWARF::GetPluginNameStatic() {
+ return SymbolFileDWARF::GetPluginNameStatic();
}
-uint32_t
-LogChannelDWARF::GetPluginVersion()
-{
- return 1;
+const char *LogChannelDWARF::GetPluginDescriptionStatic() {
+ return "DWARF log channel for debugging plug-in issues.";
}
-
-void
-LogChannelDWARF::Delete ()
-{
- g_log_channel = NULL;
+lldb_private::ConstString LogChannelDWARF::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t LogChannelDWARF::GetPluginVersion() { return 1; }
-void
-LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm)
-{
- if (m_log_ap.get() == NULL)
- return;
-
- uint32_t flag_bits = m_log_ap->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0) flag_bits &= ~DWARF_LOG_ALL;
- else if (::strcasecmp (arg, "info") == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO;
- else if (::strcasecmp (arg, "line") == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE;
- else if (::strcasecmp (arg, "pubnames") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
- else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
- else if (::strcasecmp (arg, "aranges") == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
- else if (::strcasecmp (arg, "lookups") == 0) flag_bits &= ~DWARF_LOG_LOOKUPS;
- else if (::strcasecmp (arg, "map") == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP;
- else if (::strcasecmp (arg, "default") == 0) flag_bits &= ~DWARF_LOG_DEFAULT;
- else if (::strcasecmp (arg, "verbose") == 0) flag_bits &= ~DWARF_LOG_VERBOSE;
- else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListCategories (feedback_strm);
- }
- }
-
- if (flag_bits == 0)
- Delete ();
- else
- m_log_ap->GetMask().Reset (flag_bits);
+void LogChannelDWARF::Delete() { g_log_channel = NULL; }
+void LogChannelDWARF::Disable(const char **categories, Stream *feedback_strm) {
+ if (m_log_ap.get() == NULL)
return;
-}
-bool
-LogChannelDWARF::Enable
-(
- StreamSP &log_stream_sp,
- uint32_t log_options,
- Stream *feedback_strm, // Feedback stream for argument errors etc
- const char **categories // The categories to enable within this logging stream, if empty, enable default set
-)
-{
- Delete ();
-
- if (m_log_ap)
- m_log_ap->SetStream(log_stream_sp);
- else
- m_log_ap.reset(new Log (log_stream_sp));
-
- g_log_channel = this;
- uint32_t flag_bits = 0;
- bool got_unknown_category = false;
- for (size_t i = 0; categories[i] != NULL; ++i)
- {
- const char *arg = categories[i];
-
- if (::strcasecmp (arg, "all") == 0) flag_bits |= DWARF_LOG_ALL;
- else if (::strcasecmp (arg, "info") == 0) flag_bits |= DWARF_LOG_DEBUG_INFO;
- else if (::strcasecmp (arg, "line") == 0) flag_bits |= DWARF_LOG_DEBUG_LINE;
- else if (::strcasecmp (arg, "pubnames") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
- else if (::strcasecmp (arg, "pubtypes") == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
- else if (::strcasecmp (arg, "aranges") == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES;
- else if (::strcasecmp (arg, "lookups") == 0) flag_bits |= DWARF_LOG_LOOKUPS;
- else if (::strcasecmp (arg, "map") == 0) flag_bits |= DWARF_LOG_DEBUG_MAP;
- else if (::strcasecmp (arg, "default") == 0) flag_bits |= DWARF_LOG_DEFAULT;
- else if (::strcasecmp (arg, "verbose") == 0) flag_bits |= DWARF_LOG_VERBOSE;
- else if (::strncasecmp(arg, "comp", 4) == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false)
- {
- got_unknown_category = true;
- ListCategories (feedback_strm);
- }
- }
+ uint32_t flag_bits = m_log_ap->GetMask().Get();
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits &= ~DWARF_LOG_ALL;
+ else if (::strcasecmp(arg, "info") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_INFO;
+ else if (::strcasecmp(arg, "line") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_LINE;
+ else if (::strcasecmp(arg, "pubnames") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
+ else if (::strcasecmp(arg, "pubtypes") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
+ else if (::strcasecmp(arg, "aranges") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
+ else if (::strcasecmp(arg, "lookups") == 0)
+ flag_bits &= ~DWARF_LOG_LOOKUPS;
+ else if (::strcasecmp(arg, "map") == 0)
+ flag_bits &= ~DWARF_LOG_DEBUG_MAP;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits &= ~DWARF_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits &= ~DWARF_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "comp", 4) == 0)
+ flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListCategories(feedback_strm);
}
- if (flag_bits == 0)
- flag_bits = DWARF_LOG_DEFAULT;
+ }
+
+ if (flag_bits == 0)
+ Delete();
+ else
m_log_ap->GetMask().Reset(flag_bits);
- m_log_ap->GetOptions().Reset(log_options);
- return m_log_ap.get() != NULL;
-}
-void
-LogChannelDWARF::ListCategories (Stream *strm)
-{
- strm->Printf ("Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " info - log the parsing of .debug_info\n"
- " line - log the parsing of .debug_line\n"
- " pubnames - log the parsing of .debug_pubnames\n"
- " pubtypes - log the parsing of .debug_pubtypes\n"
- " aranges - log the parsing of .debug_aranges\n"
- " lookups - log any lookups that happen by name, regex, or address\n"
- " completion - log struct/unions/class type completions\n"
- " map - log insertions of object files into DWARF debug maps\n",
- SymbolFileDWARF::GetPluginNameStatic().GetCString());
-}
-
-Log *
-LogChannelDWARF::GetLog ()
-{
- if (g_log_channel)
- return g_log_channel->m_log_ap.get();
-
- return NULL;
-}
-
-Log *
-LogChannelDWARF::GetLogIfAll (uint32_t mask)
-{
- if (g_log_channel && g_log_channel->m_log_ap.get())
- {
- if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
- return g_log_channel->m_log_ap.get();
- }
- return NULL;
+ return;
}
-Log *
-LogChannelDWARF::GetLogIfAny (uint32_t mask)
-{
- if (g_log_channel && g_log_channel->m_log_ap.get())
- {
- if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
- return g_log_channel->m_log_ap.get();
+bool LogChannelDWARF::Enable(
+ StreamSP &log_stream_sp, uint32_t log_options,
+ Stream *feedback_strm, // Feedback stream for argument errors etc
+ const char **categories // The categories to enable within this logging
+ // stream, if empty, enable default set
+ ) {
+ Delete();
+
+ if (m_log_ap)
+ m_log_ap->SetStream(log_stream_sp);
+ else
+ m_log_ap.reset(new Log(log_stream_sp));
+
+ g_log_channel = this;
+ uint32_t flag_bits = 0;
+ bool got_unknown_category = false;
+ for (size_t i = 0; categories[i] != NULL; ++i) {
+ const char *arg = categories[i];
+
+ if (::strcasecmp(arg, "all") == 0)
+ flag_bits |= DWARF_LOG_ALL;
+ else if (::strcasecmp(arg, "info") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_INFO;
+ else if (::strcasecmp(arg, "line") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_LINE;
+ else if (::strcasecmp(arg, "pubnames") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
+ else if (::strcasecmp(arg, "pubtypes") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
+ else if (::strcasecmp(arg, "aranges") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_ARANGES;
+ else if (::strcasecmp(arg, "lookups") == 0)
+ flag_bits |= DWARF_LOG_LOOKUPS;
+ else if (::strcasecmp(arg, "map") == 0)
+ flag_bits |= DWARF_LOG_DEBUG_MAP;
+ else if (::strcasecmp(arg, "default") == 0)
+ flag_bits |= DWARF_LOG_DEFAULT;
+ else if (::strcasecmp(arg, "verbose") == 0)
+ flag_bits |= DWARF_LOG_VERBOSE;
+ else if (::strncasecmp(arg, "comp", 4) == 0)
+ flag_bits |= DWARF_LOG_TYPE_COMPLETION;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false) {
+ got_unknown_category = true;
+ ListCategories(feedback_strm);
+ }
}
- return NULL;
-}
-
-void
-LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
-{
- if (g_log_channel)
- {
- Log *log = g_log_channel->m_log_ap.get();
- if (log && log->GetMask().AnySet(mask))
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+ }
+ if (flag_bits == 0)
+ flag_bits = DWARF_LOG_DEFAULT;
+ m_log_ap->GetMask().Reset(flag_bits);
+ m_log_ap->GetOptions().Reset(log_options);
+ return m_log_ap.get() != NULL;
+}
+
+void LogChannelDWARF::ListCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for '%s':\n"
+ " all - turn on all available logging categories\n"
+ " info - log the parsing of .debug_info\n"
+ " line - log the parsing of .debug_line\n"
+ " pubnames - log the parsing of .debug_pubnames\n"
+ " pubtypes - log the parsing of .debug_pubtypes\n"
+ " aranges - log the parsing of .debug_aranges\n"
+ " lookups - log any lookups that happen by name, regex, or address\n"
+ " completion - log struct/unions/class type completions\n"
+ " map - log insertions of object files into DWARF debug maps\n",
+ SymbolFileDWARF::GetPluginNameStatic().GetCString());
+}
+
+Log *LogChannelDWARF::GetLog() {
+ if (g_log_channel)
+ return g_log_channel->m_log_ap.get();
+
+ return NULL;
+}
+
+Log *LogChannelDWARF::GetLogIfAll(uint32_t mask) {
+ if (g_log_channel && g_log_channel->m_log_ap.get()) {
+ if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
+ return g_log_channel->m_log_ap.get();
+ }
+ return NULL;
+}
+
+Log *LogChannelDWARF::GetLogIfAny(uint32_t mask) {
+ if (g_log_channel && g_log_channel->m_log_ap.get()) {
+ if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
+ return g_log_channel->m_log_ap.get();
+ }
+ return NULL;
+}
+
+void LogChannelDWARF::LogIf(uint32_t mask, const char *format, ...) {
+ if (g_log_channel) {
+ Log *log = g_log_channel->m_log_ap.get();
+ if (log && log->GetMask().AnySet(mask)) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
}
+ }
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h Tue Sep 6 15:57:50 2016
@@ -16,72 +16,59 @@
// Project includes
#include "lldb/Core/Log.h"
-#define DWARF_LOG_VERBOSE (1u << 0)
-#define DWARF_LOG_DEBUG_INFO (1u << 1)
-#define DWARF_LOG_DEBUG_LINE (1u << 2)
-#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3)
-#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4)
-#define DWARF_LOG_DEBUG_ARANGES (1u << 5)
-#define DWARF_LOG_LOOKUPS (1u << 6)
-#define DWARF_LOG_TYPE_COMPLETION (1u << 7)
-#define DWARF_LOG_DEBUG_MAP (1u << 8)
-#define DWARF_LOG_ALL (UINT32_MAX)
-#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
+#define DWARF_LOG_VERBOSE (1u << 0)
+#define DWARF_LOG_DEBUG_INFO (1u << 1)
+#define DWARF_LOG_DEBUG_LINE (1u << 2)
+#define DWARF_LOG_DEBUG_PUBNAMES (1u << 3)
+#define DWARF_LOG_DEBUG_PUBTYPES (1u << 4)
+#define DWARF_LOG_DEBUG_ARANGES (1u << 5)
+#define DWARF_LOG_LOOKUPS (1u << 6)
+#define DWARF_LOG_TYPE_COMPLETION (1u << 7)
+#define DWARF_LOG_DEBUG_MAP (1u << 8)
+#define DWARF_LOG_ALL (UINT32_MAX)
+#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
-class LogChannelDWARF : public lldb_private::LogChannel
-{
+class LogChannelDWARF : public lldb_private::LogChannel {
public:
- LogChannelDWARF ();
+ LogChannelDWARF();
- ~LogChannelDWARF() override;
+ ~LogChannelDWARF() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::LogChannel *
- CreateInstance ();
+ static lldb_private::LogChannel *CreateInstance();
- lldb_private::ConstString
- GetPluginName() override;
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
- void
- Disable(const char** categories, lldb_private::Stream *feedback_strm) override;
+ void Disable(const char **categories,
+ lldb_private::Stream *feedback_strm) override;
- void
- Delete ();
+ void Delete();
- bool
- Enable(lldb::StreamSP &log_stream_sp,
- uint32_t log_options,
- lldb_private::Stream *feedback_strm, // Feedback stream for argument errors etc
- const char **categories) override; // The categories to enable within this logging stream, if empty, enable default set
+ bool Enable(lldb::StreamSP &log_stream_sp, uint32_t log_options,
+ lldb_private::Stream
+ *feedback_strm, // Feedback stream for argument errors etc
+ const char **categories) override; // The categories to enable
+ // within this logging stream,
+ // if empty, enable default set
- void
- ListCategories(lldb_private::Stream *strm) override;
+ void ListCategories(lldb_private::Stream *strm) override;
- static lldb_private::Log *
- GetLog ();
+ static lldb_private::Log *GetLog();
- static lldb_private::Log *
- GetLogIfAll (uint32_t mask);
-
- static lldb_private::Log *
- GetLogIfAny (uint32_t mask);
-
- static void
- LogIf (uint32_t mask, const char *format, ...);
+ static lldb_private::Log *GetLogIfAll(uint32_t mask);
+
+ static lldb_private::Log *GetLogIfAny(uint32_t mask);
+
+ static void LogIf(uint32_t mask, const char *format, ...);
};
#endif // SymbolFileDWARF_LogChannelDWARF_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp Tue Sep 6 15:57:50 2016
@@ -9,9 +9,9 @@
#include "NameToDIE.h"
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "DWARFCompileUnit.h"
@@ -22,75 +22,61 @@
using namespace lldb;
using namespace lldb_private;
-void
-NameToDIE::Finalize()
-{
- m_map.Sort ();
- m_map.SizeToFit ();
-}
-
-void
-NameToDIE::Insert (const ConstString& name, const DIERef& die_ref)
-{
- m_map.Append(name.GetCString(), die_ref);
-}
-
-size_t
-NameToDIE::Find (const ConstString &name, DIEArray &info_array) const
-{
- return m_map.GetValues (name.GetCString(), info_array);
-}
-
-size_t
-NameToDIE::Find (const RegularExpression& regex, DIEArray &info_array) const
-{
- return m_map.GetValues (regex, info_array);
-}
-
-size_t
-NameToDIE::FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const
-{
- const size_t initial_size = info_array.size();
- const uint32_t size = m_map.GetSize();
- for (uint32_t i=0; i<size; ++i)
- {
- const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i);
- if (cu_offset == die_ref.cu_offset)
- info_array.push_back (die_ref);
- }
- return info_array.size() - initial_size;
-}
-
-void
-NameToDIE::Dump (Stream *s)
-{
- const uint32_t size = m_map.GetSize();
- for (uint32_t i=0; i<size; ++i)
- {
- const char *cstr = m_map.GetCStringAtIndex(i);
- const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i);
- s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void*) cstr, die_ref.cu_offset, die_ref.die_offset, cstr);
- }
-}
-
-void
-NameToDIE::ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const
-{
- const uint32_t size = m_map.GetSize();
- for (uint32_t i=0; i<size; ++i)
- {
- if (!callback(m_map.GetCStringAtIndexUnchecked(i), m_map.GetValueAtIndexUnchecked (i)))
- break;
- }
-}
-
-void
-NameToDIE::Append (const NameToDIE& other)
-{
- const uint32_t size = other.m_map.GetSize();
- for (uint32_t i = 0; i < size; ++i)
- {
- m_map.Append(other.m_map.GetCStringAtIndexUnchecked (i),
- other.m_map.GetValueAtIndexUnchecked (i));
- }
+void NameToDIE::Finalize() {
+ m_map.Sort();
+ m_map.SizeToFit();
+}
+
+void NameToDIE::Insert(const ConstString &name, const DIERef &die_ref) {
+ m_map.Append(name.GetCString(), die_ref);
+}
+
+size_t NameToDIE::Find(const ConstString &name, DIEArray &info_array) const {
+ return m_map.GetValues(name.GetCString(), info_array);
+}
+
+size_t NameToDIE::Find(const RegularExpression ®ex,
+ DIEArray &info_array) const {
+ return m_map.GetValues(regex, info_array);
+}
+
+size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
+ DIEArray &info_array) const {
+ const size_t initial_size = info_array.size();
+ const uint32_t size = m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
+ if (cu_offset == die_ref.cu_offset)
+ info_array.push_back(die_ref);
+ }
+ return info_array.size() - initial_size;
+}
+
+void NameToDIE::Dump(Stream *s) {
+ const uint32_t size = m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ const char *cstr = m_map.GetCStringAtIndex(i);
+ const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
+ s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr,
+ die_ref.cu_offset, die_ref.die_offset, cstr);
+ }
+}
+
+void NameToDIE::ForEach(
+ std::function<bool(const char *name, const DIERef &die_ref)> const
+ &callback) const {
+ const uint32_t size = m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ if (!callback(m_map.GetCStringAtIndexUnchecked(i),
+ m_map.GetValueAtIndexUnchecked(i)))
+ break;
+ }
+}
+
+void NameToDIE::Append(const NameToDIE &other) {
+ const uint32_t size = other.m_map.GetSize();
+ for (uint32_t i = 0; i < size; ++i) {
+ m_map.Append(other.m_map.GetCStringAtIndexUnchecked(i),
+ other.m_map.GetValueAtIndexUnchecked(i));
+ }
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/NameToDIE.h Tue Sep 6 15:57:50 2016
@@ -12,51 +12,42 @@
#include <functional>
-#include "lldb/Core/dwarf.h"
+#include "DIERef.h"
#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Core/dwarf.h"
#include "lldb/lldb-defines.h"
-#include "DIERef.h"
class SymbolFileDWARF;
-class NameToDIE
-{
+class NameToDIE {
public:
- NameToDIE () :
- m_map()
- {
- }
-
- ~NameToDIE ()
- {
- }
-
- void
- Dump (lldb_private::Stream *s);
-
- void
- Insert (const lldb_private::ConstString& name, const DIERef& die_ref);
-
- void
- Append (const NameToDIE& other);
-
- void
- Finalize();
-
- size_t
- Find (const lldb_private::ConstString &name, DIEArray &info_array) const;
-
- size_t
- Find (const lldb_private::RegularExpression& regex, DIEArray &info_array) const;
+ NameToDIE() : m_map() {}
+
+ ~NameToDIE() {}
+
+ void Dump(lldb_private::Stream *s);
+
+ void Insert(const lldb_private::ConstString &name, const DIERef &die_ref);
+
+ void Append(const NameToDIE &other);
+
+ void Finalize();
+
+ size_t Find(const lldb_private::ConstString &name,
+ DIEArray &info_array) const;
+
+ size_t Find(const lldb_private::RegularExpression ®ex,
+ DIEArray &info_array) const;
- size_t
- FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const;
+ size_t FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
+ DIEArray &info_array) const;
- void
- ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const;
+ void
+ ForEach(std::function<bool(const char *name, const DIERef &die_ref)> const
+ &callback) const;
protected:
- lldb_private::UniqueCStringMap<DIERef> m_map;
+ lldb_private::UniqueCStringMap<DIERef> m_map;
};
-#endif // SymbolFileDWARF_NameToDIE_h_
+#endif // SymbolFileDWARF_NameToDIE_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Sep 6 15:57:50 2016
@@ -88,8 +88,8 @@
using namespace lldb;
using namespace lldb_private;
-//static inline bool
-//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
+// static inline bool
+// child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
//{
// switch (tag)
// {
@@ -108,4713 +108,4169 @@ using namespace lldb_private;
namespace {
- PropertyDefinition
- g_properties[] =
- {
- { "comp-dir-symlink-paths" , OptionValue::eTypeFileSpecList, true, 0 , nullptr, nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time." },
- { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
- };
-
- enum
- {
- ePropertySymLinkPaths
- };
+PropertyDefinition g_properties[] = {
+ {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
+ nullptr, "If the DW_AT_comp_dir matches any of these paths the symbolic "
+ "links will be resolved at DWARF parse time."},
+ {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+
+enum { ePropertySymLinkPaths };
+
+class PluginProperties : public Properties {
+public:
+ static ConstString GetSettingName() {
+ return SymbolFileDWARF::GetPluginNameStatic();
+ }
+
+ PluginProperties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ FileSpecList &GetSymLinkPaths() {
+ OptionValueFileSpecList *option_value =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
+ nullptr, true, ePropertySymLinkPaths);
+ assert(option_value);
+ return option_value->GetCurrentValue();
+ }
+};
+typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
- class PluginProperties : public Properties
- {
- public:
- static ConstString
- GetSettingName()
- {
- return SymbolFileDWARF::GetPluginNameStatic();
- }
-
- PluginProperties()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- FileSpecList&
- GetSymLinkPaths()
- {
- OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, true, ePropertySymLinkPaths);
- assert(option_value);
- return option_value->GetCurrentValue();
- }
+static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() {
+ static const auto g_settings_sp(std::make_shared<PluginProperties>());
+ return g_settings_sp;
+}
- };
+} // anonymous namespace end
- typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP;
+static const char *removeHostnameFromPathname(const char *path_from_dwarf) {
+ if (!path_from_dwarf || !path_from_dwarf[0]) {
+ return path_from_dwarf;
+ }
- static const SymbolFileDWARFPropertiesSP&
- GetGlobalPluginProperties()
- {
- static const auto g_settings_sp(std::make_shared<PluginProperties>());
- return g_settings_sp;
- }
+ const char *colon_pos = strchr(path_from_dwarf, ':');
+ if (nullptr == colon_pos) {
+ return path_from_dwarf;
+ }
-} // anonymous namespace end
+ const char *slash_pos = strchr(path_from_dwarf, '/');
+ if (slash_pos && (slash_pos < colon_pos)) {
+ return path_from_dwarf;
+ }
+ // check whether we have a windows path, and so the first character
+ // is a drive-letter not a hostname.
+ if (colon_pos == path_from_dwarf + 1 && isalpha(*path_from_dwarf) &&
+ strlen(path_from_dwarf) > 2 && '\\' == path_from_dwarf[2]) {
+ return path_from_dwarf;
+ }
-static const char*
-removeHostnameFromPathname(const char* path_from_dwarf)
-{
- if (!path_from_dwarf || !path_from_dwarf[0])
- {
- return path_from_dwarf;
- }
-
- const char *colon_pos = strchr(path_from_dwarf, ':');
- if (nullptr == colon_pos)
- {
- return path_from_dwarf;
- }
-
- const char *slash_pos = strchr(path_from_dwarf, '/');
- if (slash_pos && (slash_pos < colon_pos))
- {
- return path_from_dwarf;
- }
-
- // check whether we have a windows path, and so the first character
- // is a drive-letter not a hostname.
- if (
- colon_pos == path_from_dwarf + 1 &&
- isalpha(*path_from_dwarf) &&
- strlen(path_from_dwarf) > 2 &&
- '\\' == path_from_dwarf[2])
- {
- return path_from_dwarf;
- }
-
- return colon_pos + 1;
+ return colon_pos + 1;
}
-static const char*
-resolveCompDir(const char* path_from_dwarf)
-{
- if (!path_from_dwarf)
- return nullptr;
-
- // DWARF2/3 suggests the form hostname:pathname for compilation directory.
- // Remove the host part if present.
- const char* local_path = removeHostnameFromPathname(path_from_dwarf);
- if (!local_path)
- return nullptr;
-
- bool is_symlink = false;
- FileSpec local_path_spec(local_path, false);
- const auto& file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
- for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
- is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), local_path_spec, true);
-
- if (!is_symlink)
- return local_path;
-
- if (!local_path_spec.IsSymbolicLink())
- return local_path;
-
- FileSpec resolved_local_path_spec;
- const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
- if (error.Success())
- return resolved_local_path_spec.GetCString();
-
+static const char *resolveCompDir(const char *path_from_dwarf) {
+ if (!path_from_dwarf)
return nullptr;
-}
+ // DWARF2/3 suggests the form hostname:pathname for compilation directory.
+ // Remove the host part if present.
+ const char *local_path = removeHostnameFromPathname(path_from_dwarf);
+ if (!local_path)
+ return nullptr;
-void
-SymbolFileDWARF::Initialize()
-{
- LogChannelDWARF::Initialize();
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
-}
-
-void
-SymbolFileDWARF::DebuggerInitialize(Debugger &debugger)
-{
- if (!PluginManager::GetSettingForSymbolFilePlugin(debugger, PluginProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForSymbolFilePlugin(debugger,
- GetGlobalPluginProperties()->GetValueProperties(),
- ConstString ("Properties for the dwarf symbol-file plug-in."),
- is_global_setting);
+ bool is_symlink = false;
+ FileSpec local_path_spec(local_path, false);
+ const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
+ for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
+ is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i),
+ local_path_spec, true);
+
+ if (!is_symlink)
+ return local_path;
+
+ if (!local_path_spec.IsSymbolicLink())
+ return local_path;
+
+ FileSpec resolved_local_path_spec;
+ const auto error =
+ FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
+ if (error.Success())
+ return resolved_local_path_spec.GetCString();
+
+ return nullptr;
+}
+
+void SymbolFileDWARF::Initialize() {
+ LogChannelDWARF::Initialize();
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+}
+
+void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForSymbolFilePlugin(
+ debugger, PluginProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForSymbolFilePlugin(
+ debugger, GetGlobalPluginProperties()->GetValueProperties(),
+ ConstString("Properties for the dwarf symbol-file plug-in."),
+ is_global_setting);
+ }
+}
+
+void SymbolFileDWARF::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+ LogChannelDWARF::Initialize();
+}
+
+lldb_private::ConstString SymbolFileDWARF::GetPluginNameStatic() {
+ static ConstString g_name("dwarf");
+ return g_name;
+}
+
+const char *SymbolFileDWARF::GetPluginDescriptionStatic() {
+ return "DWARF and DWARF3 debug symbol file reader.";
+}
+
+SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileDWARF(obj_file);
+}
+
+TypeList *SymbolFileDWARF::GetTypeList() {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetTypeList();
+ else
+ return m_obj_file->GetModule()->GetTypeList();
+}
+void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
+ dw_offset_t max_die_offset, uint32_t type_mask,
+ TypeSet &type_set) {
+ if (die) {
+ const dw_offset_t die_offset = die.GetOffset();
+
+ if (die_offset >= max_die_offset)
+ return;
+
+ if (die_offset >= min_die_offset) {
+ const dw_tag_t tag = die.Tag();
+
+ bool add_type = false;
+
+ switch (tag) {
+ case DW_TAG_array_type:
+ add_type = (type_mask & eTypeClassArray) != 0;
+ break;
+ case DW_TAG_unspecified_type:
+ case DW_TAG_base_type:
+ add_type = (type_mask & eTypeClassBuiltin) != 0;
+ break;
+ case DW_TAG_class_type:
+ add_type = (type_mask & eTypeClassClass) != 0;
+ break;
+ case DW_TAG_structure_type:
+ add_type = (type_mask & eTypeClassStruct) != 0;
+ break;
+ case DW_TAG_union_type:
+ add_type = (type_mask & eTypeClassUnion) != 0;
+ break;
+ case DW_TAG_enumeration_type:
+ add_type = (type_mask & eTypeClassEnumeration) != 0;
+ break;
+ case DW_TAG_subroutine_type:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ add_type = (type_mask & eTypeClassFunction) != 0;
+ break;
+ case DW_TAG_pointer_type:
+ add_type = (type_mask & eTypeClassPointer) != 0;
+ break;
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_reference_type:
+ add_type = (type_mask & eTypeClassReference) != 0;
+ break;
+ case DW_TAG_typedef:
+ add_type = (type_mask & eTypeClassTypedef) != 0;
+ break;
+ case DW_TAG_ptr_to_member_type:
+ add_type = (type_mask & eTypeClassMemberPointer) != 0;
+ break;
+ }
+
+ if (add_type) {
+ const bool assert_not_being_parsed = true;
+ Type *type = ResolveTypeUID(die, assert_not_being_parsed);
+ if (type) {
+ if (type_set.find(type) == type_set.end())
+ type_set.insert(type);
+ }
+ }
+ }
+
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
+ child_die = child_die.GetSibling()) {
+ GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
+ }
+ }
+}
+
+size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
+ uint32_t type_mask, TypeList &type_list)
+
+{
+ TypeSet type_set;
+
+ CompileUnit *comp_unit = NULL;
+ DWARFCompileUnit *dwarf_cu = NULL;
+ if (sc_scope)
+ comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
+
+ if (comp_unit) {
+ dwarf_cu = GetDWARFCompileUnit(comp_unit);
+ if (dwarf_cu == 0)
+ return 0;
+ GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
+ dwarf_cu->GetNextCompileUnitOffset(), type_mask, type_set);
+ } else {
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ const size_t num_cus = info->GetNumCompileUnits();
+ for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
+ dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu) {
+ GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set);
+ }
+ }
+ }
+ }
+
+ std::set<CompilerType> compiler_type_set;
+ size_t num_types_added = 0;
+ for (Type *type : type_set) {
+ CompilerType compiler_type = type->GetForwardCompilerType();
+ if (compiler_type_set.find(compiler_type) == compiler_type_set.end()) {
+ compiler_type_set.insert(compiler_type);
+ type_list.Insert(type->shared_from_this());
+ ++num_types_added;
}
+ }
+ return num_types_added;
}
-void
-SymbolFileDWARF::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
- LogChannelDWARF::Initialize();
-}
+//----------------------------------------------------------------------
+// Gets the first parent that is a lexical block, function or inlined
+// subroutine, or compile unit.
+//----------------------------------------------------------------------
+DWARFDIE
+SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
+ DWARFDIE die;
+ for (die = child_die.GetParent(); die; die = die.GetParent()) {
+ dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ return die;
+ }
+ }
+ return DWARFDIE();
+}
+
+SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile)
+ : SymbolFile(objfile), UserID(0), // Used by SymbolFileDWARFDebugMap to when
+ // this class parses .o files to contain
+ // the .o file index/ID
+ m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
+ m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
+ m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
+ m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(),
+ m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(),
+ m_line(), m_apple_names_ap(), m_apple_types_ap(), m_apple_namespaces_ap(),
+ m_apple_objc_ap(), m_function_basename_index(),
+ m_function_fullname_index(), m_function_method_index(),
+ m_function_selector_index(), m_objc_class_selectors_index(),
+ m_global_index(), m_type_index(), m_namespace_index(), m_indexed(false),
+ m_using_apple_tables(false), m_fetched_external_modules(false),
+ m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
+ m_unique_ast_type_map() {}
+
+SymbolFileDWARF::~SymbolFileDWARF() {}
+
+static const ConstString &GetDWARFMachOSegmentName() {
+ static ConstString g_dwarf_section_name("__DWARF");
+ return g_dwarf_section_name;
+}
+
+UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ return debug_map_symfile->GetUniqueDWARFASTTypeMap();
+ else
+ return m_unique_ast_type_map;
+}
+
+TypeSystem *SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ TypeSystem *type_system;
+ if (debug_map_symfile) {
+ type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
+ } else {
+ type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ }
+ return type_system;
+}
+
+void SymbolFileDWARF::InitializeObject() {
+ ModuleSP module_sp(m_obj_file->GetModule());
+ if (module_sp) {
+ const SectionList *section_list = module_sp->GetSectionList();
+ const Section *section =
+ section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
+
+ // Memory map the DWARF mach-o segment so we have everything mmap'ed
+ // to keep our heap memory usage down.
+ if (section)
+ m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
+ }
+
+ get_apple_names_data();
+ if (m_data_apple_names.m_data.GetByteSize() > 0) {
+ m_apple_names_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_names.m_data, get_debug_str_data(), ".apple_names"));
+ if (m_apple_names_ap->IsValid())
+ m_using_apple_tables = true;
+ else
+ m_apple_names_ap.reset();
+ }
+ get_apple_types_data();
+ if (m_data_apple_types.m_data.GetByteSize() > 0) {
+ m_apple_types_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_types.m_data, get_debug_str_data(), ".apple_types"));
+ if (m_apple_types_ap->IsValid())
+ m_using_apple_tables = true;
+ else
+ m_apple_types_ap.reset();
+ }
+ get_apple_namespaces_data();
+ if (m_data_apple_namespaces.m_data.GetByteSize() > 0) {
+ m_apple_namespaces_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_namespaces.m_data, get_debug_str_data(),
+ ".apple_namespaces"));
+ if (m_apple_namespaces_ap->IsValid())
+ m_using_apple_tables = true;
+ else
+ m_apple_namespaces_ap.reset();
+ }
-lldb_private::ConstString
-SymbolFileDWARF::GetPluginNameStatic()
-{
- static ConstString g_name("dwarf");
- return g_name;
+ get_apple_objc_data();
+ if (m_data_apple_objc.m_data.GetByteSize() > 0) {
+ m_apple_objc_ap.reset(new DWARFMappedHash::MemoryTable(
+ m_data_apple_objc.m_data, get_debug_str_data(), ".apple_objc"));
+ if (m_apple_objc_ap->IsValid())
+ m_using_apple_tables = true;
+ else
+ m_apple_objc_ap.reset();
+ }
}
-const char *
-SymbolFileDWARF::GetPluginDescriptionStatic()
-{
- return "DWARF and DWARF3 debug symbol file reader.";
+bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
+ return version == 2 || version == 3 || version == 4;
}
+uint32_t SymbolFileDWARF::CalculateAbilities() {
+ uint32_t abilities = 0;
+ if (m_obj_file != NULL) {
+ const Section *section = NULL;
+ const SectionList *section_list = m_obj_file->GetSectionList();
+ if (section_list == NULL)
+ return 0;
-SymbolFile*
-SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
-{
- return new SymbolFileDWARF(obj_file);
-}
+ uint64_t debug_abbrev_file_size = 0;
+ uint64_t debug_info_file_size = 0;
+ uint64_t debug_line_file_size = 0;
-TypeList *
-SymbolFileDWARF::GetTypeList ()
-{
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- return debug_map_symfile->GetTypeList();
- else
- return m_obj_file->GetModule()->GetTypeList();
+ section = section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
-}
-void
-SymbolFileDWARF::GetTypes (const DWARFDIE &die,
- dw_offset_t min_die_offset,
- dw_offset_t max_die_offset,
- uint32_t type_mask,
- TypeSet &type_set)
-{
- if (die)
- {
- const dw_offset_t die_offset = die.GetOffset();
-
- if (die_offset >= max_die_offset)
- return;
-
- if (die_offset >= min_die_offset)
- {
- const dw_tag_t tag = die.Tag();
-
- bool add_type = false;
-
- switch (tag)
- {
- case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
- case DW_TAG_unspecified_type:
- case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
- case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
- case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
- case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
- case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
- case DW_TAG_subroutine_type:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
- case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
- case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
- case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
- }
+ if (section)
+ section_list = §ion->GetChildren();
- if (add_type)
- {
- const bool assert_not_being_parsed = true;
- Type *type = ResolveTypeUID (die, assert_not_being_parsed);
- if (type)
- {
- if (type_set.find(type) == type_set.end())
- type_set.insert(type);
- }
- }
- }
-
- for (DWARFDIE child_die = die.GetFirstChild();
- child_die.IsValid();
- child_die = child_die.GetSibling())
- {
- GetTypes (child_die, min_die_offset, max_die_offset, type_mask, type_set);
- }
- }
-}
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true).get();
+ if (section != NULL) {
+ debug_info_file_size = section->GetFileSize();
-size_t
-SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
- uint32_t type_mask,
- TypeList &type_list)
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugAbbrev, true)
+ .get();
+ if (section)
+ debug_abbrev_file_size = section->GetFileSize();
-{
- TypeSet type_set;
-
- CompileUnit *comp_unit = NULL;
- DWARFCompileUnit* dwarf_cu = NULL;
- if (sc_scope)
- comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
-
- if (comp_unit)
- {
- dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (dwarf_cu == 0)
- return 0;
- GetTypes (dwarf_cu->DIE(),
- dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(),
- type_mask,
- type_set);
- }
- else
- {
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- const size_t num_cus = info->GetNumCompileUnits();
- for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
- {
- dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- {
- GetTypes (dwarf_cu->DIE(),
- 0,
- UINT32_MAX,
- type_mask,
- type_set);
- }
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)
+ .get();
+ if (section)
+ debug_line_file_size = section->GetFileSize();
+ } else {
+ const char *symfile_dir_cstr =
+ m_obj_file->GetFileSpec().GetDirectory().GetCString();
+ if (symfile_dir_cstr) {
+ if (strcasestr(symfile_dir_cstr, ".dsym")) {
+ if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo) {
+ // We have a dSYM file that didn't have a any debug info.
+ // If the string table has a size of 1, then it was made from
+ // an executable with no debug info, or from an executable that
+ // was stripped.
+ section =
+ section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true)
+ .get();
+ if (section && section->GetFileSize() == 1) {
+ m_obj_file->GetModule()->ReportWarning(
+ "empty dSYM file detected, dSYM was created with an "
+ "executable with no debug info.");
}
+ }
}
+ }
}
- std::set<CompilerType> compiler_type_set;
- size_t num_types_added = 0;
- for (Type *type : type_set)
- {
- CompilerType compiler_type = type->GetForwardCompilerType ();
- if (compiler_type_set.find(compiler_type) == compiler_type_set.end())
- {
- compiler_type_set.insert(compiler_type);
- type_list.Insert (type->shared_from_this());
- ++num_types_added;
- }
- }
- return num_types_added;
-}
-
-
-//----------------------------------------------------------------------
-// Gets the first parent that is a lexical block, function or inlined
-// subroutine, or compile unit.
-//----------------------------------------------------------------------
-DWARFDIE
-SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die)
-{
- DWARFDIE die;
- for (die = child_die.GetParent(); die; die = die.GetParent())
- {
- dw_tag_t tag = die.Tag();
+ if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
+ abilities |= CompileUnits | Functions | Blocks | GlobalVariables |
+ LocalVariables | VariableTypes;
- switch (tag)
- {
- case DW_TAG_compile_unit:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- return die;
- }
- }
- return DWARFDIE();
+ if (debug_line_file_size > 0)
+ abilities |= LineTables;
+ }
+ return abilities;
}
-
-SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
- SymbolFile (objfile),
- UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
- m_debug_map_module_wp (),
- m_debug_map_symfile (NULL),
- m_data_debug_abbrev (),
- m_data_debug_aranges (),
- m_data_debug_frame (),
- m_data_debug_info (),
- m_data_debug_line (),
- m_data_debug_macro (),
- m_data_debug_loc (),
- m_data_debug_ranges (),
- m_data_debug_str (),
- m_data_apple_names (),
- m_data_apple_types (),
- m_data_apple_namespaces (),
- m_abbr(),
- m_info(),
- m_line(),
- m_apple_names_ap (),
- m_apple_types_ap (),
- m_apple_namespaces_ap (),
- m_apple_objc_ap (),
- m_function_basename_index(),
- m_function_fullname_index(),
- m_function_method_index(),
- m_function_selector_index(),
- m_objc_class_selectors_index(),
- m_global_index(),
- m_type_index(),
- m_namespace_index(),
- m_indexed (false),
- m_using_apple_tables (false),
- m_fetched_external_modules (false),
- m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
- m_ranges(),
- m_unique_ast_type_map ()
-{
+const DWARFDataExtractor &
+SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
+ DWARFDataSegment &data_segment) {
+ std::call_once(data_segment.m_flag, &SymbolFileDWARF::LoadSectionData, this,
+ sect_type, std::ref(data_segment.m_data));
+ return data_segment.m_data;
}
-SymbolFileDWARF::~SymbolFileDWARF()
-{
+void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type,
+ DWARFDataExtractor &data) {
+ ModuleSP module_sp(m_obj_file->GetModule());
+ const SectionList *section_list = module_sp->GetSectionList();
+ if (section_list) {
+ SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
+ if (section_sp) {
+ // See if we memory mapped the DWARF segment?
+ if (m_dwarf_data.GetByteSize()) {
+ data.SetData(m_dwarf_data, section_sp->GetOffset(),
+ section_sp->GetFileSize());
+ } else {
+ if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
+ data.Clear();
+ }
+ }
+ }
}
-static const ConstString &
-GetDWARFMachOSegmentName ()
-{
- static ConstString g_dwarf_section_name ("__DWARF");
- return g_dwarf_section_name;
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_abbrev_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAbbrev,
+ m_data_debug_abbrev);
}
-UniqueDWARFASTTypeMap &
-SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
-{
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- return debug_map_symfile->GetUniqueDWARFASTTypeMap ();
- else
- return m_unique_ast_type_map;
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_addr_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAddr, m_data_debug_addr);
}
-TypeSystem *
-SymbolFileDWARF::GetTypeSystemForLanguage (LanguageType language)
-{
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- TypeSystem *type_system;
- if (debug_map_symfile)
- {
- type_system = debug_map_symfile->GetTypeSystemForLanguage(language);
- }
- else
- {
- type_system = m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
- if (type_system)
- type_system->SetSymbolFile(this);
- }
- return type_system;
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_aranges_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAranges,
+ m_data_debug_aranges);
}
-void
-SymbolFileDWARF::InitializeObject()
-{
- ModuleSP module_sp (m_obj_file->GetModule());
- if (module_sp)
- {
- const SectionList *section_list = module_sp->GetSectionList();
- const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
-
- // Memory map the DWARF mach-o segment so we have everything mmap'ed
- // to keep our heap memory usage down.
- if (section)
- m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
- }
-
- get_apple_names_data();
- if (m_data_apple_names.m_data.GetByteSize() > 0)
- {
- m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data,
- get_debug_str_data(),
- ".apple_names"));
- if (m_apple_names_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_names_ap.reset();
- }
- get_apple_types_data();
- if (m_data_apple_types.m_data.GetByteSize() > 0)
- {
- m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data,
- get_debug_str_data(),
- ".apple_types"));
- if (m_apple_types_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_types_ap.reset();
- }
-
- get_apple_namespaces_data();
- if (m_data_apple_namespaces.m_data.GetByteSize() > 0)
- {
- m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data,
- get_debug_str_data(),
- ".apple_namespaces"));
- if (m_apple_namespaces_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_namespaces_ap.reset();
- }
-
- get_apple_objc_data();
- if (m_data_apple_objc.m_data.GetByteSize() > 0)
- {
- m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data,
- get_debug_str_data(),
- ".apple_objc"));
- if (m_apple_objc_ap->IsValid())
- m_using_apple_tables = true;
- else
- m_apple_objc_ap.reset();
- }
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_frame_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame);
}
-bool
-SymbolFileDWARF::SupportedVersion(uint16_t version)
-{
- return version == 2 || version == 3 || version == 4;
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info);
}
-uint32_t
-SymbolFileDWARF::CalculateAbilities ()
-{
- uint32_t abilities = 0;
- if (m_obj_file != NULL)
- {
- const Section* section = NULL;
- const SectionList *section_list = m_obj_file->GetSectionList();
- if (section_list == NULL)
- return 0;
-
- uint64_t debug_abbrev_file_size = 0;
- uint64_t debug_info_file_size = 0;
- uint64_t debug_line_file_size = 0;
-
- section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
-
- if (section)
- section_list = §ion->GetChildren ();
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
- if (section != NULL)
- {
- debug_info_file_size = section->GetFileSize();
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
- if (section)
- debug_abbrev_file_size = section->GetFileSize();
-
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
- if (section)
- debug_line_file_size = section->GetFileSize();
- }
- else
- {
- const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
- if (symfile_dir_cstr)
- {
- if (strcasestr(symfile_dir_cstr, ".dsym"))
- {
- if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
- {
- // We have a dSYM file that didn't have a any debug info.
- // If the string table has a size of 1, then it was made from
- // an executable with no debug info, or from an executable that
- // was stripped.
- section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
- if (section && section->GetFileSize() == 1)
- {
- m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
- }
- }
- }
- }
- }
-
- if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
- abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
-
- if (debug_line_file_size > 0)
- abilities |= LineTables;
- }
- return abilities;
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment)
-{
- std::call_once(data_segment.m_flag,
- &SymbolFileDWARF::LoadSectionData,
- this,
- sect_type,
- std::ref(data_segment.m_data));
- return data_segment.m_data;
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
}
-void
-SymbolFileDWARF::LoadSectionData (lldb::SectionType sect_type, DWARFDataExtractor& data)
-{
- ModuleSP module_sp (m_obj_file->GetModule());
- const SectionList *section_list = module_sp->GetSectionList();
- if (section_list)
- {
- SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
- if (section_sp)
- {
- // See if we memory mapped the DWARF segment?
- if (m_dwarf_data.GetByteSize())
- {
- data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize());
- }
- else
- {
- if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
- data.Clear();
- }
- }
- }
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_abbrev_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugRanges,
+ m_data_debug_ranges);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_addr_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_aranges_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_offsets_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsets,
+ m_data_debug_str_offsets);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_frame_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_info_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_types_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleTypes, m_data_apple_types);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_line_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_namespaces_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleNamespaces,
+ m_data_apple_namespaces);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_macro_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugMacro, m_data_debug_macro);
+const DWARFDataExtractor &SymbolFileDWARF::get_apple_objc_data() {
+ return GetCachedSectionData(eSectionTypeDWARFAppleObjC, m_data_apple_objc);
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_loc_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc);
+DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
+ if (m_abbr.get() == NULL) {
+ const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
+ if (debug_abbrev_data.GetByteSize() > 0) {
+ m_abbr.reset(new DWARFDebugAbbrev());
+ if (m_abbr.get())
+ m_abbr->Parse(debug_abbrev_data);
+ }
+ }
+ return m_abbr.get();
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_ranges_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
+const DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() const {
+ return m_abbr.get();
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_str_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str);
+DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
+ if (m_info.get() == NULL) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p",
+ LLVM_PRETTY_FUNCTION, static_cast<void *>(this));
+ if (get_debug_info_data().GetByteSize() > 0) {
+ m_info.reset(new DWARFDebugInfo());
+ if (m_info.get()) {
+ m_info->SetDwarfData(this);
+ }
+ }
+ }
+ return m_info.get();
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_debug_str_offsets_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets);
+const DWARFDebugInfo *SymbolFileDWARF::DebugInfo() const {
+ return m_info.get();
}
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_names_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names);
-}
+DWARFCompileUnit *
+SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
+ if (!comp_unit)
+ return nullptr;
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_types_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types);
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ // Just a normal DWARF file whose user ID for the compile unit is
+ // the DWARF offset itself
+
+ DWARFCompileUnit *dwarf_cu =
+ info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
+ }
+ return NULL;
+}
+
+DWARFDebugRanges *SymbolFileDWARF::DebugRanges() {
+ if (m_ranges.get() == NULL) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p",
+ LLVM_PRETTY_FUNCTION, static_cast<void *>(this));
+ if (get_debug_ranges_data().GetByteSize() > 0) {
+ m_ranges.reset(new DWARFDebugRanges());
+ if (m_ranges.get())
+ m_ranges->Extract(this);
+ }
+ }
+ return m_ranges.get();
+}
+
+const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const {
+ return m_ranges.get();
+}
+
+lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) {
+ CompUnitSP cu_sp;
+ if (dwarf_cu) {
+ CompileUnit *comp_unit = (CompileUnit *)dwarf_cu->GetUserData();
+ if (comp_unit) {
+ // We already parsed this compile unit, had out a shared pointer to it
+ cu_sp = comp_unit->shared_from_this();
+ } else {
+ if (dwarf_cu->GetSymbolFileDWARF() != this) {
+ return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu,
+ cu_idx);
+ } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) {
+ // Let the debug map create the compile unit
+ cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+ dwarf_cu->SetUserData(cu_sp.get());
+ } else {
+ ModuleSP module_sp(m_obj_file->GetModule());
+ if (module_sp) {
+ const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (cu_die) {
+ FileSpec cu_file_spec{cu_die.GetName(), false};
+ if (cu_file_spec) {
+ // If we have a full path to the compile unit, we don't need to
+ // resolve
+ // the file. This can be expensive e.g. when the source files are
+ // NFS mounted.
+ if (cu_file_spec.IsRelative()) {
+ const char *cu_comp_dir{
+ cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
+ cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
+ }
+
+ std::string remapped_file;
+ if (module_sp->RemapSourceFile(cu_file_spec.GetCString(),
+ remapped_file))
+ cu_file_spec.SetFile(remapped_file, false);
+ }
+
+ LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(
+ cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
+
+ bool is_optimized = dwarf_cu->GetIsOptimized();
+ cu_sp.reset(new CompileUnit(
+ module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(),
+ cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo));
+ if (cu_sp) {
+ // If we just created a compile unit with an invalid file spec,
+ // try and get the
+ // first entry in the supports files from the line table as that
+ // should be the
+ // compile unit.
+ if (!cu_file_spec) {
+ cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
+ if (cu_file_spec) {
+ (FileSpec &)(*cu_sp) = cu_file_spec;
+ // Also fix the invalid file spec which was copied from the
+ // compile unit.
+ cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
+ }
+ }
+
+ dwarf_cu->SetUserData(cu_sp.get());
+
+ // Figure out the compile unit index if we weren't given one
+ if (cu_idx == UINT32_MAX)
+ DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
+
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cu_idx, cu_sp);
+ }
+ }
+ }
+ }
+ }
+ }
+ return cu_sp;
+}
+
+uint32_t SymbolFileDWARF::GetNumCompileUnits() {
+ DWARFDebugInfo *info = DebugInfo();
+ if (info)
+ return info->GetNumCompileUnits();
+ return 0;
+}
+
+CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
+ CompUnitSP cu_sp;
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu)
+ cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
+ }
+ return cu_sp;
+}
+
+Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc,
+ const DWARFDIE &die) {
+ if (die.IsValid()) {
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+
+ if (type_system) {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->ParseFunctionFromDWARF(sc, die);
+ }
+ }
+ return nullptr;
+}
+
+bool SymbolFileDWARF::FixupAddress(Address &addr) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ return debug_map_symfile->LinkOSOAddress(addr);
+ }
+ // This is a normal DWARF file, no address fixups need to happen
+ return true;
}
+lldb::LanguageType
+SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) {
+ assert(sc.comp_unit);
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
+ return dwarf_cu->GetLanguageType();
+ else
+ return eLanguageTypeUnknown;
+}
+
+size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
+ assert(sc.comp_unit);
+ size_t functions_added = 0;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ DWARFDIECollection function_dies;
+ const size_t num_functions =
+ dwarf_cu->AppendDIEsWithTag(DW_TAG_subprogram, function_dies);
+ size_t func_idx;
+ for (func_idx = 0; func_idx < num_functions; ++func_idx) {
+ DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
+ if (sc.comp_unit->FindFunctionByUID(die.GetID()).get() == NULL) {
+ if (ParseCompileUnitFunction(sc, die))
+ ++functions_added;
+ }
+ }
+ // FixupTypes();
+ }
+ return functions_added;
+}
+
+bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
+ const SymbolContext &sc, FileSpecList &support_files) {
+ assert(sc.comp_unit);
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+
+ if (cu_die) {
+ const char *cu_comp_dir = resolveCompDir(
+ cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
+ const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(
+ DW_AT_stmt_list, DW_INVALID_OFFSET);
+ if (stmt_list != DW_INVALID_OFFSET) {
+ // All file indexes in DWARF are one based and a file of index zero is
+ // supposed to be the compile unit itself.
+ support_files.Append(*sc.comp_unit);
+ return DWARFDebugLine::ParseSupportFiles(
+ sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir,
+ stmt_list, support_files);
+ }
+ }
+ }
+ return false;
+}
+
+bool SymbolFileDWARF::ParseCompileUnitIsOptimized(
+ const lldb_private::SymbolContext &sc) {
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu)
+ return dwarf_cu->GetIsOptimized();
+ return false;
+}
+
+bool SymbolFileDWARF::ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) {
+ assert(sc.comp_unit);
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ if (ClangModulesDeclVendor::LanguageSupportsClangModules(
+ sc.comp_unit->GetLanguage())) {
+ UpdateExternalModuleListIfNeeded();
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_namespaces_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
-}
+ if (sc.comp_unit) {
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
-const DWARFDataExtractor&
-SymbolFileDWARF::get_apple_objc_data()
-{
- return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc);
-}
+ if (die) {
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die;
+ child_die = child_die.GetSibling()) {
+ if (child_die.Tag() == DW_TAG_imported_declaration) {
+ if (DWARFDIE module_die =
+ child_die.GetReferencedDIE(DW_AT_import)) {
+ if (module_die.Tag() == DW_TAG_module) {
+ if (const char *name = module_die.GetAttributeValueAsString(
+ DW_AT_name, nullptr)) {
+ ConstString const_name(name);
+ imported_modules.push_back(const_name);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ for (const auto &pair : m_external_type_modules) {
+ imported_modules.push_back(pair.first);
+ }
+ }
+ }
+ }
+ return false;
+}
+
+struct ParseDWARFLineTableCallbackInfo {
+ LineTable *line_table;
+ std::unique_ptr<LineSequence> sequence_ap;
+ lldb::addr_t addr_mask;
+};
+
+//----------------------------------------------------------------------
+// ParseStatementTableCallback
+//----------------------------------------------------------------------
+static void ParseDWARFLineTableCallback(dw_offset_t offset,
+ const DWARFDebugLine::State &state,
+ void *userData) {
+ if (state.row == DWARFDebugLine::State::StartParsingLineTable) {
+ // Just started parsing the line table
+ } else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) {
+ // Done parsing line table, nothing to do for the cleanup
+ } else {
+ ParseDWARFLineTableCallbackInfo *info =
+ (ParseDWARFLineTableCallbackInfo *)userData;
+ LineTable *line_table = info->line_table;
+
+ // If this is our first time here, we need to create a
+ // sequence container.
+ if (!info->sequence_ap.get()) {
+ info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
+ assert(info->sequence_ap.get());
+ }
+ line_table->AppendLineEntryToSequence(
+ info->sequence_ap.get(), state.address & info->addr_mask, state.line,
+ state.column, state.file, state.is_stmt, state.basic_block,
+ state.prologue_end, state.epilogue_begin, state.end_sequence);
+ if (state.end_sequence) {
+ // First, put the current sequence into the line table.
+ line_table->InsertSequence(info->sequence_ap.get());
+ // Then, empty it to prepare for the next sequence.
+ info->sequence_ap->Clear();
+ }
+ }
+}
+
+bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
+ assert(sc.comp_unit);
+ if (sc.comp_unit->GetLineTable() != NULL)
+ return true;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (dwarf_cu_die) {
+ const dw_offset_t cu_line_offset =
+ dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list,
+ DW_INVALID_OFFSET);
+ if (cu_line_offset != DW_INVALID_OFFSET) {
+ std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
+ if (line_table_ap.get()) {
+ ParseDWARFLineTableCallbackInfo info;
+ info.line_table = line_table_ap.get();
+
+ /*
+ * MIPS:
+ * The SymbolContext may not have a valid target, thus we may not be
+ * able
+ * to call Address::GetOpcodeLoadAddress() which would clear the bit
+ * #0
+ * for MIPS. Use ArchSpec to clear the bit #0.
+ */
+ ArchSpec arch;
+ GetObjectFile()->GetArchitecture(arch);
+ switch (arch.GetMachine()) {
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ info.addr_mask = ~((lldb::addr_t)1);
+ break;
+ default:
+ info.addr_mask = ~((lldb::addr_t)0);
+ break;
+ }
-DWARFDebugAbbrev*
-SymbolFileDWARF::DebugAbbrev()
-{
- if (m_abbr.get() == NULL)
- {
- const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
- if (debug_abbrev_data.GetByteSize() > 0)
- {
- m_abbr.reset(new DWARFDebugAbbrev());
- if (m_abbr.get())
- m_abbr->Parse(debug_abbrev_data);
+ lldb::offset_t offset = cu_line_offset;
+ DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
+ ParseDWARFLineTableCallback,
+ &info);
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We have an object file that has a line table with addresses
+ // that are not linked. We need to link the line table and convert
+ // the addresses that are relative to the .o file into addresses
+ // for the main executable.
+ sc.comp_unit->SetLineTable(
+ debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get()));
+ } else {
+ sc.comp_unit->SetLineTable(line_table_ap.release());
+ return true;
+ }
}
+ }
}
- return m_abbr.get();
+ }
+ return false;
}
-const DWARFDebugAbbrev*
-SymbolFileDWARF::DebugAbbrev() const
-{
- return m_abbr.get();
-}
+lldb_private::DebugMacrosSP
+SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
+ auto iter = m_debug_macros_map.find(*offset);
+ if (iter != m_debug_macros_map.end())
+ return iter->second;
+ const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
+ if (debug_macro_data.GetByteSize() == 0)
+ return DebugMacrosSP();
-DWARFDebugInfo*
-SymbolFileDWARF::DebugInfo()
-{
- if (m_info.get() == NULL)
- {
- Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p",
- LLVM_PRETTY_FUNCTION, static_cast<void*>(this));
- if (get_debug_info_data().GetByteSize() > 0)
- {
- m_info.reset(new DWARFDebugInfo());
- if (m_info.get())
- {
- m_info->SetDwarfData(this);
- }
- }
- }
- return m_info.get();
-}
+ lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
+ m_debug_macros_map[*offset] = debug_macros_sp;
-const DWARFDebugInfo*
-SymbolFileDWARF::DebugInfo() const
-{
- return m_info.get();
+ const DWARFDebugMacroHeader &header =
+ DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
+ DWARFDebugMacroEntry::ReadMacroEntries(debug_macro_data, get_debug_str_data(),
+ header.OffsetIs64Bit(), offset, this,
+ debug_macros_sp);
+
+ return debug_macros_sp;
}
-DWARFCompileUnit*
-SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
-{
- if (!comp_unit)
- return nullptr;
+bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
+ assert(sc.comp_unit);
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- // Just a normal DWARF file whose user ID for the compile unit is
- // the DWARF offset itself
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu == nullptr)
+ return false;
- DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID());
- if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
- dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
- }
- return NULL;
-}
+ const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (!dwarf_cu_die)
+ return false;
+ lldb::offset_t sect_offset =
+ dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
+ if (sect_offset == DW_INVALID_OFFSET)
+ sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros,
+ DW_INVALID_OFFSET);
+ if (sect_offset == DW_INVALID_OFFSET)
+ return false;
-DWARFDebugRanges*
-SymbolFileDWARF::DebugRanges()
-{
- if (m_ranges.get() == NULL)
- {
- Timer scoped_timer(LLVM_PRETTY_FUNCTION, "%s this = %p",
- LLVM_PRETTY_FUNCTION, static_cast<void*>(this));
- if (get_debug_ranges_data().GetByteSize() > 0)
- {
- m_ranges.reset(new DWARFDebugRanges());
- if (m_ranges.get())
- m_ranges->Extract(this);
- }
- }
- return m_ranges.get();
-}
+ sc.comp_unit->SetDebugMacros(ParseDebugMacros(§_offset));
-const DWARFDebugRanges*
-SymbolFileDWARF::DebugRanges() const
-{
- return m_ranges.get();
+ return true;
}
-lldb::CompUnitSP
-SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
-{
- CompUnitSP cu_sp;
- if (dwarf_cu)
- {
- CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
- if (comp_unit)
- {
- // We already parsed this compile unit, had out a shared pointer to it
- cu_sp = comp_unit->shared_from_this();
- }
- else
- {
- if (dwarf_cu->GetSymbolFileDWARF() != this)
- {
- return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu, cu_idx);
- }
- else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile ())
- {
- // Let the debug map create the compile unit
- cu_sp = m_debug_map_symfile->GetCompileUnit(this);
- dwarf_cu->SetUserData(cu_sp.get());
- }
- else
- {
- ModuleSP module_sp (m_obj_file->GetModule());
- if (module_sp)
- {
- const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
- if (cu_die)
- {
- FileSpec cu_file_spec{cu_die.GetName(), false};
- if (cu_file_spec)
- {
- // If we have a full path to the compile unit, we don't need to resolve
- // the file. This can be expensive e.g. when the source files are NFS mounted.
- if (cu_file_spec.IsRelative())
- {
- const char *cu_comp_dir{cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr)};
- cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
- }
-
- std::string remapped_file;
- if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
- cu_file_spec.SetFile(remapped_file, false);
- }
-
- LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
+size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
+ Block *parent_block,
+ const DWARFDIE &orig_die,
+ addr_t subprogram_low_pc,
+ uint32_t depth) {
+ size_t blocks_added = 0;
+ DWARFDIE die = orig_die;
+ while (die) {
+ dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_subprogram:
+ case DW_TAG_lexical_block: {
+ Block *block = NULL;
+ if (tag == DW_TAG_subprogram) {
+ // Skip any DW_TAG_subprogram DIEs that are inside
+ // of a normal or inlined functions. These will be
+ // parsed on their own as separate entities.
+
+ if (depth > 0)
+ break;
+
+ block = parent_block;
+ } else {
+ BlockSP block_sp(new Block(die.GetID()));
+ parent_block->AddChild(block_sp);
+ block = block_sp.get();
+ }
+ DWARFRangeList ranges;
+ const char *name = NULL;
+ const char *mangled_name = NULL;
+
+ int decl_file = 0;
+ int decl_line = 0;
+ int decl_column = 0;
+ int call_file = 0;
+ int call_line = 0;
+ int call_column = 0;
+ if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
+ decl_line, decl_column, call_file, call_line,
+ call_column, nullptr)) {
+ if (tag == DW_TAG_subprogram) {
+ assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);
+ subprogram_low_pc = ranges.GetMinRangeBase(0);
+ } else if (tag == DW_TAG_inlined_subroutine) {
+ // We get called here for inlined subroutines in two ways.
+ // The first time is when we are making the Function object
+ // for this inlined concrete instance. Since we're creating a top
+ // level block at
+ // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
+ // need to
+ // adjust the containing address.
+ // The second time is when we are parsing the blocks inside the
+ // function that contains
+ // the inlined concrete instance. Since these will be blocks inside
+ // the containing "real"
+ // function the offset will be for that function.
+ if (subprogram_low_pc == LLDB_INVALID_ADDRESS) {
+ subprogram_low_pc = ranges.GetMinRangeBase(0);
+ }
+ }
+
+ const size_t num_ranges = ranges.GetSize();
+ for (size_t i = 0; i < num_ranges; ++i) {
+ const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
+ const addr_t range_base = range.GetRangeBase();
+ if (range_base >= subprogram_low_pc)
+ block->AddRange(Block::Range(range_base - subprogram_low_pc,
+ range.GetByteSize()));
+ else {
+ GetObjectFile()->GetModule()->ReportError(
+ "0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64
+ ") which has a base that is less than the function's low PC "
+ "0x%" PRIx64 ". Please file a bug and attach the file at the "
+ "start of this error message",
+ block->GetID(), range_base, range.GetRangeEnd(),
+ subprogram_low_pc);
+ }
+ }
+ block->FinalizeRanges();
+
+ if (tag != DW_TAG_subprogram &&
+ (name != NULL || mangled_name != NULL)) {
+ std::unique_ptr<Declaration> decl_ap;
+ if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+ decl_ap.reset(new Declaration(
+ sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
+ decl_line, decl_column));
+
+ std::unique_ptr<Declaration> call_ap;
+ if (call_file != 0 || call_line != 0 || call_column != 0)
+ call_ap.reset(new Declaration(
+ sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
+ call_line, call_column));
+
+ block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(),
+ call_ap.get());
+ }
+
+ ++blocks_added;
+
+ if (die.HasChildren()) {
+ blocks_added += ParseFunctionBlocks(sc, block, die.GetFirstChild(),
+ subprogram_low_pc, depth + 1);
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ // Only parse siblings of the block if we are not at depth zero. A depth
+ // of zero indicates we are currently parsing the top level
+ // DW_TAG_subprogram DIE
- bool is_optimized = dwarf_cu->GetIsOptimized ();
- cu_sp.reset(new CompileUnit(module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(), cu_language,
- is_optimized ? eLazyBoolYes : eLazyBoolNo));
- if (cu_sp)
- {
- // If we just created a compile unit with an invalid file spec, try and get the
- // first entry in the supports files from the line table as that should be the
- // compile unit.
- if (!cu_file_spec)
- {
- cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
- if (cu_file_spec)
- {
- (FileSpec &)(*cu_sp) = cu_file_spec;
- // Also fix the invalid file spec which was copied from the compile unit.
- cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
- }
- }
-
- dwarf_cu->SetUserData(cu_sp.get());
-
- // Figure out the compile unit index if we weren't given one
- if (cu_idx == UINT32_MAX)
- DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
-
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
- }
- }
- }
- }
- }
- }
- return cu_sp;
+ if (depth == 0)
+ die.Clear();
+ else
+ die = die.GetSibling();
+ }
+ return blocks_added;
+}
+
+bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
+ if (parent_die) {
+ for (DWARFDIE die = parent_die.GetFirstChild(); die;
+ die = die.GetSibling()) {
+ dw_tag_t tag = die.Tag();
+ bool check_virtuality = false;
+ switch (tag) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ check_virtuality = true;
+ break;
+ default:
+ break;
+ }
+ if (check_virtuality) {
+ if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
+ TypeSystem *type_system = decl_ctx.GetTypeSystem();
+ DWARFASTParser *ast_parser = type_system->GetDWARFParser();
+ std::vector<DWARFDIE> decl_ctx_die_list =
+ ast_parser->GetDIEForDeclContext(decl_ctx);
+
+ for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
+ for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl;
+ decl = decl.GetSibling())
+ ast_parser->GetDeclForUIDFromDWARF(decl);
+}
+
+SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
+ if (debug_map)
+ return debug_map->GetSymbolFileByOSOIndex(
+ debug_map->GetOSOIndexFromUserID(uid));
+ return this;
}
-uint32_t
-SymbolFileDWARF::GetNumCompileUnits()
-{
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- return info->GetNumCompileUnits();
- return 0;
+DWARFDIE
+SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
+ // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
+ // we must make sure we use the correct DWARF file when resolving things.
+ // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
+ // SymbolFileDWARF classes, one for each .o file. We can often end up
+ // with references to other DWARF objects and we must be ready to receive
+ // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
+ // instance.
+ SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
+ if (dwarf)
+ return dwarf->GetDIE(DIERef(uid, dwarf));
+ return DWARFDIE();
+}
+
+CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDecl();
+ return CompilerDecl();
}
-CompUnitSP
-SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
-{
- CompUnitSP cu_sp;
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
- }
- return cu_sp;
+CompilerDeclContext
+SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetDeclContext();
+ return CompilerDeclContext();
}
-Function *
-SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFDIE &die)
-{
- if (die.IsValid())
- {
- TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system)
- {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->ParseFunctionFromDWARF(sc, die);
- }
- }
+CompilerDeclContext
+SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE die = GetDIEFromUID(type_uid);
+ if (die)
+ return die.GetContainingDeclContext();
+ return CompilerDeclContext();
+}
+
+Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
+ // Anytime we have a lldb::user_id_t, we must get the DIE by
+ // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
+ // the SymbolFileDWARF::GetDIEFromUID() for details.
+ DWARFDIE type_die = GetDIEFromUID(type_uid);
+ if (type_die)
+ return type_die.ResolveType();
+ else
return nullptr;
}
-bool
-SymbolFileDWARF::FixupAddress (Address &addr)
-{
- SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- return debug_map_symfile->LinkOSOAddress(addr);
- }
- // This is a normal DWARF file, no address fixups need to happen
- return true;
-}
-lldb::LanguageType
-SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
-{
- assert (sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- return dwarf_cu->GetLanguageType();
- else
- return eLanguageTypeUnknown;
-}
-
-size_t
-SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
-{
- assert (sc.comp_unit);
- size_t functions_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- DWARFDIECollection function_dies;
- const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
- size_t func_idx;
- for (func_idx = 0; func_idx < num_functions; ++func_idx)
- {
- DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
- if (sc.comp_unit->FindFunctionByUID (die.GetID()).get() == NULL)
- {
- if (ParseCompileUnitFunction(sc, die))
- ++functions_added;
- }
- }
- //FixupTypes();
- }
- return functions_added;
+Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) {
+ return ResolveType(GetDIE(die_ref), true);
}
-bool
-SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
-{
- assert (sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- const DWARFDIE cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
+ bool assert_not_being_parsed) {
+ if (die) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+
+ // We might be coming in in the middle of a type tree (a class
+ // within a class, an enum within a class), so parse any needed
+ // parent DIEs before we get to this one...
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(die);
+ if (decl_ctx_die) {
+ if (log) {
+ switch (decl_ctx_die.Tag()) {
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type: {
+ // Get the type, which could be a forward declaration
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' "
+ "resolve parent forward type for 0x%8.8x",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName(),
+ decl_ctx_die.GetOffset());
+ } break;
- if (cu_die)
- {
- const char * cu_comp_dir = resolveCompDir(cu_die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr));
- const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
- if (stmt_list != DW_INVALID_OFFSET)
- {
- // All file indexes in DWARF are one based and a file of index zero is
- // supposed to be the compile unit itself.
- support_files.Append (*sc.comp_unit);
- return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(),
- get_debug_line_data(),
- cu_comp_dir,
- stmt_list,
- support_files);
- }
+ default:
+ break;
}
+ }
}
- return false;
+ return ResolveType(die);
+ }
+ return NULL;
}
-bool
-SymbolFileDWARF::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
-{
- DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- return dwarf_cu->GetIsOptimized();
- return false;
-}
+// This function is used when SymbolFileDWARFDebugMap owns a bunch of
+// SymbolFileDWARF objects to detect if this DWARF file is the one that
+// can resolve a compiler_type.
+bool SymbolFileDWARF::HasForwardDeclForClangType(
+ const CompilerType &compiler_type) {
+ CompilerType compiler_type_no_qualifiers =
+ ClangUtil::RemoveFastQualifiers(compiler_type);
+ if (GetForwardDeclClangTypeToDie().count(
+ compiler_type_no_qualifiers.GetOpaqueQualType())) {
+ return true;
+ }
+ TypeSystem *type_system = compiler_type.GetTypeSystem();
-bool
-SymbolFileDWARF::ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules)
-{
- assert (sc.comp_unit);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
- {
- UpdateExternalModuleListIfNeeded();
-
- if (sc.comp_unit)
- {
- const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
-
- if (die)
- {
- for (DWARFDIE child_die = die.GetFirstChild();
- child_die;
- child_die = child_die.GetSibling())
- {
- if (child_die.Tag() == DW_TAG_imported_declaration)
- {
- if (DWARFDIE module_die = child_die.GetReferencedDIE(DW_AT_import))
- {
- if (module_die.Tag() == DW_TAG_module)
- {
- if (const char *name = module_die.GetAttributeValueAsString(DW_AT_name, nullptr))
- {
- ConstString const_name(name);
- imported_modules.push_back(const_name);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- for (const auto &pair : m_external_type_modules)
- {
- imported_modules.push_back(pair.first);
- }
- }
- }
- }
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
return false;
-}
+ DWARFASTParserClang *ast_parser =
+ static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ return ast_parser->GetClangASTImporter().CanImport(compiler_type);
+}
+
+bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetObjectFile()->GetModule()->GetMutex());
+
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
+ if (clang_type_system) {
+ DWARFASTParserClang *ast_parser =
+ static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
+ if (ast_parser &&
+ ast_parser->GetClangASTImporter().CanImport(compiler_type))
+ return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
+ }
+
+ // We have a struct/union/class/enum that needs to be fully resolved.
+ CompilerType compiler_type_no_qualifiers =
+ ClangUtil::RemoveFastQualifiers(compiler_type);
+ auto die_it = GetForwardDeclClangTypeToDie().find(
+ compiler_type_no_qualifiers.GetOpaqueQualType());
+ if (die_it == GetForwardDeclClangTypeToDie().end()) {
+ // We have already resolved this type...
+ return true;
+ }
-struct ParseDWARFLineTableCallbackInfo
-{
- LineTable* line_table;
- std::unique_ptr<LineSequence> sequence_ap;
- lldb::addr_t addr_mask;
-};
+ DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
+ if (dwarf_die) {
+ // Once we start resolving this type, remove it from the forward declaration
+ // map in case anyone child members or other types require this type to get
+ // resolved.
+ // The type will get resolved when all of the calls to
+ // SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
+ // are done.
+ GetForwardDeclClangTypeToDie().erase(die_it);
-//----------------------------------------------------------------------
-// ParseStatementTableCallback
-//----------------------------------------------------------------------
-static void
-ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
-{
- if (state.row == DWARFDebugLine::State::StartParsingLineTable)
- {
- // Just started parsing the line table
- }
- else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
- {
- // Done parsing line table, nothing to do for the cleanup
- }
- else
- {
- ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
- LineTable* line_table = info->line_table;
-
- // If this is our first time here, we need to create a
- // sequence container.
- if (!info->sequence_ap.get())
- {
- info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
- assert(info->sequence_ap.get());
- }
- line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
- state.address & info->addr_mask,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- if (state.end_sequence)
- {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->sequence_ap.get());
- // Then, empty it to prepare for the next sequence.
- info->sequence_ap->Clear();
- }
- }
+ Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
+
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO |
+ DWARF_LOG_TYPE_COMPLETION));
+ if (log)
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
+ dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
+ type->GetName().AsCString());
+ assert(compiler_type);
+ DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
+ }
+ return false;
+}
+
+Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
+ bool assert_not_being_parsed,
+ bool resolve_function_context) {
+ if (die) {
+ Type *type = GetTypeForDIE(die, resolve_function_context).get();
+
+ if (assert_not_being_parsed) {
+ if (type != DIE_IS_BEING_PARSED)
+ return type;
+
+ GetObjectFile()->GetModule()->ReportError(
+ "Parsing a die that is being parsed die: 0x%8.8x: %s %s",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+
+ } else
+ return type;
+ }
+ return nullptr;
+}
+
+CompileUnit *
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx) {
+ // Check if the symbol vendor already knows about this compile unit?
+ if (dwarf_cu->GetUserData() == NULL) {
+ // The symbol vendor doesn't know about this compile unit, we
+ // need to parse and add it to the symbol vendor object.
+ return ParseCompileUnit(dwarf_cu, cu_idx).get();
+ }
+ return (CompileUnit *)dwarf_cu->GetUserData();
+}
+
+size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
+ DIEArray &method_die_offsets) {
+ method_die_offsets.clear();
+ if (m_using_apple_tables) {
+ if (m_apple_objc_ap.get())
+ m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_objc_class_selectors_index.Find(class_name, method_die_offsets);
+ }
+ return method_die_offsets.size();
}
-bool
-SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
-{
- assert (sc.comp_unit);
- if (sc.comp_unit->GetLineTable() != NULL)
- return true;
+bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
+ sc.Clear(false);
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
- if (dwarf_cu_die)
- {
- const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET);
- if (cu_line_offset != DW_INVALID_OFFSET)
- {
- std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
- if (line_table_ap.get())
- {
- ParseDWARFLineTableCallbackInfo info;
- info.line_table = line_table_ap.get();
-
- /*
- * MIPS:
- * The SymbolContext may not have a valid target, thus we may not be able
- * to call Address::GetOpcodeLoadAddress() which would clear the bit #0
- * for MIPS. Use ArchSpec to clear the bit #0.
- */
- ArchSpec arch;
- GetObjectFile()->GetArchitecture(arch);
- switch (arch.GetMachine())
- {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- info.addr_mask = ~((lldb::addr_t)1);
- break;
- default:
- info.addr_mask = ~((lldb::addr_t)0);
- break;
- }
+ if (die) {
+ // Check if the symbol vendor already knows about this compile unit?
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
- lldb::offset_t offset = cu_line_offset;
- DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- {
- // We have an object file that has a line table with addresses
- // that are not linked. We need to link the line table and convert
- // the addresses that are relative to the .o file into addresses
- // for the main executable.
- sc.comp_unit->SetLineTable (debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
- }
- else
- {
- sc.comp_unit->SetLineTable(line_table_ap.release());
- return true;
- }
- }
- }
- }
+ sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
+ if (sc.function == NULL)
+ sc.function = ParseCompileUnitFunction(sc, die);
+
+ if (sc.function) {
+ sc.module_sp = sc.function->CalculateSymbolContextModule();
+ return true;
}
- return false;
+ }
+
+ return false;
}
-lldb_private::DebugMacrosSP
-SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset)
-{
- auto iter = m_debug_macros_map.find(*offset);
- if (iter != m_debug_macros_map.end())
- return iter->second;
+lldb::ModuleSP SymbolFileDWARF::GetDWOModule(ConstString name) {
+ UpdateExternalModuleListIfNeeded();
+ const auto &pos = m_external_type_modules.find(name);
+ if (pos != m_external_type_modules.end())
+ return pos->second;
+ else
+ return lldb::ModuleSP();
+}
- const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
- if (debug_macro_data.GetByteSize() == 0)
- return DebugMacrosSP();
+DWARFDIE
+SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info)
+ return debug_info->GetDIE(die_ref);
+ else
+ return DWARFDIE();
+}
- lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
- m_debug_macros_map[*offset] = debug_macros_sp;
+std::unique_ptr<SymbolFileDWARFDwo>
+SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
+ DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) {
+ // If we are using a dSYM file, we never want the standard DWO files since
+ // the -gmodule support uses the same DWO machanism to specify full debug
+ // info files for modules.
+ if (GetDebugMapSymfile())
+ return nullptr;
- const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
- DWARFDebugMacroEntry::ReadMacroEntries(
- debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, this, debug_macros_sp);
+ const char *dwo_name = cu_die.GetAttributeValueAsString(
+ this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
+ if (!dwo_name)
+ return nullptr;
- return debug_macros_sp;
-}
+ FileSpec dwo_file(dwo_name, true);
+ if (dwo_file.IsRelative()) {
+ const char *comp_dir = cu_die.GetAttributeValueAsString(
+ this, &dwarf_cu, DW_AT_comp_dir, nullptr);
+ if (!comp_dir)
+ return nullptr;
+
+ dwo_file.SetFile(comp_dir, true);
+ dwo_file.AppendPathComponent(dwo_name);
+ }
-bool
-SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext& sc)
-{
- assert (sc.comp_unit);
-
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu == nullptr)
- return false;
-
- const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
- if (!dwarf_cu_die)
- return false;
-
- lldb::offset_t sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
- if (sect_offset == DW_INVALID_OFFSET)
- sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, DW_INVALID_OFFSET);
- if (sect_offset == DW_INVALID_OFFSET)
- return false;
-
- sc.comp_unit->SetDebugMacros(ParseDebugMacros(§_offset));
-
- return true;
-}
-
-size_t
-SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
- Block *parent_block,
- const DWARFDIE &orig_die,
- addr_t subprogram_low_pc,
- uint32_t depth)
-{
- size_t blocks_added = 0;
- DWARFDIE die = orig_die;
- while (die)
- {
- dw_tag_t tag = die.Tag();
-
- switch (tag)
- {
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- case DW_TAG_lexical_block:
- {
- Block *block = NULL;
- if (tag == DW_TAG_subprogram)
- {
- // Skip any DW_TAG_subprogram DIEs that are inside
- // of a normal or inlined functions. These will be
- // parsed on their own as separate entities.
-
- if (depth > 0)
- break;
-
- block = parent_block;
- }
- else
- {
- BlockSP block_sp(new Block (die.GetID()));
- parent_block->AddChild(block_sp);
- block = block_sp.get();
- }
- DWARFRangeList ranges;
- const char *name = NULL;
- const char *mangled_name = NULL;
-
- int decl_file = 0;
- int decl_line = 0;
- int decl_column = 0;
- int call_file = 0;
- int call_line = 0;
- int call_column = 0;
- if (die.GetDIENamesAndRanges (name,
- mangled_name,
- ranges,
- decl_file, decl_line, decl_column,
- call_file, call_line, call_column, nullptr))
- {
- if (tag == DW_TAG_subprogram)
- {
- assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
- subprogram_low_pc = ranges.GetMinRangeBase(0);
- }
- else if (tag == DW_TAG_inlined_subroutine)
- {
- // We get called here for inlined subroutines in two ways.
- // The first time is when we are making the Function object
- // for this inlined concrete instance. Since we're creating a top level block at
- // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
- // adjust the containing address.
- // The second time is when we are parsing the blocks inside the function that contains
- // the inlined concrete instance. Since these will be blocks inside the containing "real"
- // function the offset will be for that function.
- if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
- {
- subprogram_low_pc = ranges.GetMinRangeBase(0);
- }
- }
-
- const size_t num_ranges = ranges.GetSize();
- for (size_t i = 0; i<num_ranges; ++i)
- {
- const DWARFRangeList::Entry &range = ranges.GetEntryRef (i);
- const addr_t range_base = range.GetRangeBase();
- if (range_base >= subprogram_low_pc)
- block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
- else
- {
- GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
- block->GetID(),
- range_base,
- range.GetRangeEnd(),
- subprogram_low_pc);
- }
- }
- block->FinalizeRanges ();
-
- if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
- {
- std::unique_ptr<Declaration> decl_ap;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line, decl_column));
-
- std::unique_ptr<Declaration> call_ap;
- if (call_file != 0 || call_line != 0 || call_column != 0)
- call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
- call_line, call_column));
-
- block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
- }
-
- ++blocks_added;
-
- if (die.HasChildren())
- {
- blocks_added += ParseFunctionBlocks (sc,
- block,
- die.GetFirstChild(),
- subprogram_low_pc,
- depth + 1);
- }
- }
- }
- break;
- default:
- break;
- }
-
- // Only parse siblings of the block if we are not at depth zero. A depth
- // of zero indicates we are currently parsing the top level
- // DW_TAG_subprogram DIE
-
- if (depth == 0)
- die.Clear();
- else
- die = die.GetSibling();
- }
- return blocks_added;
-}
-
-bool
-SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
-{
- if (parent_die)
- {
- for (DWARFDIE die = parent_die.GetFirstChild(); die; die = die.GetSibling())
- {
- dw_tag_t tag = die.Tag();
- bool check_virtuality = false;
- switch (tag)
- {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- check_virtuality = true;
- break;
- default:
- break;
- }
- if (check_virtuality)
- {
- if (die.GetAttributeValueAsUnsigned(DW_AT_virtuality, 0) != 0)
- return true;
- }
- }
- }
- return false;
-}
-
-void
-SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
-{
- TypeSystem *type_system = decl_ctx.GetTypeSystem();
- DWARFASTParser *ast_parser = type_system->GetDWARFParser();
- std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
-
- for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
- for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
- ast_parser->GetDeclForUIDFromDWARF(decl);
-}
-
-SymbolFileDWARF *
-SymbolFileDWARF::GetDWARFForUID (lldb::user_id_t uid)
-{
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
- // we must make sure we use the correct DWARF file when resolving things.
- // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up
- // with references to other DWARF objects and we must be ready to receive
- // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
- // instance.
- SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
- if (debug_map)
- return debug_map->GetSymbolFileByOSOIndex(debug_map->GetOSOIndexFromUserID(uid));
- return this;
-}
-
-DWARFDIE
-SymbolFileDWARF::GetDIEFromUID (lldb::user_id_t uid)
-{
- // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API
- // we must make sure we use the correct DWARF file when resolving things.
- // On MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
- // SymbolFileDWARF classes, one for each .o file. We can often end up
- // with references to other DWARF objects and we must be ready to receive
- // a "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
- // instance.
- SymbolFileDWARF *dwarf = GetDWARFForUID(uid);
- if (dwarf)
- return dwarf->GetDIE(DIERef(uid, dwarf));
- return DWARFDIE();
-}
-
-CompilerDecl
-SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
- return die.GetDecl();
- return CompilerDecl();
-}
-
-CompilerDeclContext
-SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
- return die.GetDeclContext();
- return CompilerDeclContext();
-}
-
-CompilerDeclContext
-SymbolFileDWARF::GetDeclContextContainingUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE die = GetDIEFromUID(type_uid);
- if (die)
- return die.GetContainingDeclContext();
- return CompilerDeclContext();
-}
-
-
-Type*
-SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
-{
- // Anytime we have a lldb::user_id_t, we must get the DIE by
- // calling SymbolFileDWARF::GetDIEFromUID(). See comments inside
- // the SymbolFileDWARF::GetDIEFromUID() for details.
- DWARFDIE type_die = GetDIEFromUID(type_uid);
- if (type_die)
- return type_die.ResolveType();
- else
- return nullptr;
-}
-
-Type*
-SymbolFileDWARF::ResolveTypeUID (const DIERef &die_ref)
-{
- return ResolveType (GetDIE(die_ref), true);
-}
-
-Type*
-SymbolFileDWARF::ResolveTypeUID (const DWARFDIE &die, bool assert_not_being_parsed)
-{
- if (die)
- {
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
-
- // We might be coming in in the middle of a type tree (a class
- // within a class, an enum within a class), so parse any needed
- // parent DIEs before we get to this one...
- DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE (die);
- if (decl_ctx_die)
- {
- if (log)
- {
- switch (decl_ctx_die.Tag())
- {
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- {
- // Get the type, which could be a forward declaration
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName(),
- decl_ctx_die.GetOffset());
- }
- break;
-
- default:
- break;
- }
- }
- }
- return ResolveType (die);
- }
- return NULL;
-}
-
-// This function is used when SymbolFileDWARFDebugMap owns a bunch of
-// SymbolFileDWARF objects to detect if this DWARF file is the one that
-// can resolve a compiler_type.
-bool
-SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type)
-{
- CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
- if (GetForwardDeclClangTypeToDie().count (compiler_type_no_qualifiers.GetOpaqueQualType()))
- {
- return true;
- }
- TypeSystem *type_system = compiler_type.GetTypeSystem();
-
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
- if (!clang_type_system)
- return false;
- DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
- return ast_parser->GetClangASTImporter().CanImport(compiler_type);
-}
-
-
-bool
-SymbolFileDWARF::CompleteType (CompilerType &compiler_type)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectFile()->GetModule()->GetMutex());
-
- ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
- if (clang_type_system)
- {
- DWARFASTParserClang *ast_parser = static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
- if (ast_parser && ast_parser->GetClangASTImporter().CanImport(compiler_type))
- return ast_parser->GetClangASTImporter().CompleteType(compiler_type);
- }
-
- // We have a struct/union/class/enum that needs to be fully resolved.
- CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type);
- auto die_it = GetForwardDeclClangTypeToDie().find (compiler_type_no_qualifiers.GetOpaqueQualType());
- if (die_it == GetForwardDeclClangTypeToDie().end())
- {
- // We have already resolved this type...
- return true;
- }
-
- DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
- if (dwarf_die)
- {
- // Once we start resolving this type, remove it from the forward declaration
- // map in case anyone child members or other types require this type to get resolved.
- // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
- // are done.
- GetForwardDeclClangTypeToDie().erase (die_it);
-
- Type *type = GetDIEToType().lookup (dwarf_die.GetDIE());
-
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
- if (log)
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
- "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
- dwarf_die.GetID(),
- dwarf_die.GetTagAsCString(),
- type->GetName().AsCString());
- assert (compiler_type);
- DWARFASTParser *dwarf_ast = dwarf_die.GetDWARFParser();
- if (dwarf_ast)
- return dwarf_ast->CompleteTypeFromDWARF (dwarf_die, type, compiler_type);
- }
- return false;
-}
-
-Type*
-SymbolFileDWARF::ResolveType (const DWARFDIE &die, bool assert_not_being_parsed, bool resolve_function_context)
-{
- if (die)
- {
- Type *type = GetTypeForDIE (die, resolve_function_context).get();
-
- if (assert_not_being_parsed)
- {
- if (type != DIE_IS_BEING_PARSED)
- return type;
-
- GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
- die.GetOffset(),
- die.GetTagAsCString(),
- die.GetName());
-
- }
- else
- return type;
- }
+ if (!dwo_file.Exists())
return nullptr;
-}
-
-CompileUnit*
-SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
-{
- // Check if the symbol vendor already knows about this compile unit?
- if (dwarf_cu->GetUserData() == NULL)
- {
- // The symbol vendor doesn't know about this compile unit, we
- // need to parse and add it to the symbol vendor object.
- return ParseCompileUnit(dwarf_cu, cu_idx).get();
- }
- return (CompileUnit*)dwarf_cu->GetUserData();
-}
-
-size_t
-SymbolFileDWARF::GetObjCMethodDIEOffsets (ConstString class_name, DIEArray &method_die_offsets)
-{
- method_die_offsets.clear();
- if (m_using_apple_tables)
- {
- if (m_apple_objc_ap.get())
- m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_objc_class_selectors_index.Find (class_name, method_die_offsets);
- }
- return method_die_offsets.size();
-}
-
-bool
-SymbolFileDWARF::GetFunction (const DWARFDIE &die, SymbolContext& sc)
-{
- sc.Clear(false);
-
- if (die)
- {
- // Check if the symbol vendor already knows about this compile unit?
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
-
- sc.function = sc.comp_unit->FindFunctionByUID (die.GetID()).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, die);
-
- if (sc.function)
- {
- sc.module_sp = sc.function->CalculateSymbolContextModule();
- return true;
- }
- }
-
- return false;
-}
-
-lldb::ModuleSP
-SymbolFileDWARF::GetDWOModule (ConstString name)
-{
- UpdateExternalModuleListIfNeeded();
- const auto &pos = m_external_type_modules.find(name);
- if (pos != m_external_type_modules.end())
- return pos->second;
- else
- return lldb::ModuleSP();
-}
-
-DWARFDIE
-SymbolFileDWARF::GetDIE (const DIERef &die_ref)
-{
- DWARFDebugInfo * debug_info = DebugInfo();
- if (debug_info)
- return debug_info->GetDIE(die_ref);
- else
- return DWARFDIE();
-}
-
-std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die)
-{
- // If we are using a dSYM file, we never want the standard DWO files since
- // the -gmodule support uses the same DWO machanism to specify full debug
- // info files for modules.
- if (GetDebugMapSymfile())
- return nullptr;
-
- const char *dwo_name = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
- if (!dwo_name)
- return nullptr;
-
- FileSpec dwo_file(dwo_name, true);
- if (dwo_file.IsRelative())
- {
- const char *comp_dir = cu_die.GetAttributeValueAsString(this, &dwarf_cu, DW_AT_comp_dir, nullptr);
- if (!comp_dir)
- return nullptr;
-
- dwo_file.SetFile(comp_dir, true);
- dwo_file.AppendPathComponent(dwo_name);
- }
-
- if (!dwo_file.Exists())
- return nullptr;
-
- const lldb::offset_t file_offset = 0;
- DataBufferSP dwo_file_data_sp;
- lldb::offset_t dwo_file_data_offset = 0;
- ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(GetObjectFile()->GetModule(), &dwo_file, file_offset,
- dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset);
- if (dwo_obj_file == nullptr)
- return nullptr;
+ const lldb::offset_t file_offset = 0;
+ DataBufferSP dwo_file_data_sp;
+ lldb::offset_t dwo_file_data_offset = 0;
+ ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(
+ GetObjectFile()->GetModule(), &dwo_file, file_offset,
+ dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset);
+ if (dwo_obj_file == nullptr)
+ return nullptr;
- return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
+ return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
}
-void
-SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
-{
- if (m_fetched_external_modules)
- return;
- m_fetched_external_modules = true;
-
- DWARFDebugInfo * debug_info = DebugInfo();
-
- const uint32_t num_compile_units = GetNumCompileUnits();
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
-
- const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
- if (die && die.HasChildren() == false)
- {
- const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
-
- if (name)
- {
- ConstString const_name(name);
- if (m_external_type_modules.find(const_name) == m_external_type_modules.end())
- {
- ModuleSP module_sp;
- const char *dwo_path = die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
- if (dwo_path)
- {
- ModuleSpec dwo_module_spec;
- dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
- if (dwo_module_spec.GetFileSpec().IsRelative())
- {
- const char *comp_dir = die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
- if (comp_dir)
- {
- dwo_module_spec.GetFileSpec().SetFile(comp_dir, true);
- dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
- }
- }
- dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
- //printf ("Loading dwo = '%s'\n", dwo_path);
- Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
- if (!module_sp)
- {
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: unable to locate module needed for external types: %s\nerror: %s\nDebugging will be degraded due to missing types. Rebuilding your project will regenerate the needed module files.",
- die.GetOffset(),
- dwo_module_spec.GetFileSpec().GetPath().c_str(),
- error.AsCString("unknown error"));
+void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
+ if (m_fetched_external_modules)
+ return;
+ m_fetched_external_modules = true;
+
+ DWARFDebugInfo *debug_info = DebugInfo();
+
+ const uint32_t num_compile_units = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+ const DWARFDIE die = dwarf_cu->GetCompileUnitDIEOnly();
+ if (die && die.HasChildren() == false) {
+ const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
+
+ if (name) {
+ ConstString const_name(name);
+ if (m_external_type_modules.find(const_name) ==
+ m_external_type_modules.end()) {
+ ModuleSP module_sp;
+ const char *dwo_path =
+ die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
+ if (dwo_path) {
+ ModuleSpec dwo_module_spec;
+ dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
+ if (dwo_module_spec.GetFileSpec().IsRelative()) {
+ const char *comp_dir =
+ die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
+ if (comp_dir) {
+ dwo_module_spec.GetFileSpec().SetFile(comp_dir, true);
+ dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
+ }
+ }
+ dwo_module_spec.GetArchitecture() =
+ m_obj_file->GetModule()->GetArchitecture();
+ // printf ("Loading dwo = '%s'\n", dwo_path);
+ Error error = ModuleList::GetSharedModule(
+ dwo_module_spec, module_sp, NULL, NULL, NULL);
+ if (!module_sp) {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8x: unable to locate module needed for external types: "
+ "%s\nerror: %s\nDebugging will be degraded due to missing "
+ "types. Rebuilding your project will regenerate the needed "
+ "module files.",
+ die.GetOffset(),
+ dwo_module_spec.GetFileSpec().GetPath().c_str(),
+ error.AsCString("unknown error"));
+ }
+ }
+ m_external_type_modules[const_name] = module_sp;
+ }
+ }
+ }
+ }
+}
+
+SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
+ if (!m_global_aranges_ap) {
+ m_global_aranges_ap.reset(new GlobalVariableMap());
+
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ if (module_sp) {
+ const size_t num_cus = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_cus; ++i) {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
+ if (cu_sp) {
+ VariableListSP globals_sp = cu_sp->GetVariableList(true);
+ if (globals_sp) {
+ const size_t num_globals = globals_sp->GetSize();
+ for (size_t g = 0; g < num_globals; ++g) {
+ VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
+ if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
+ const DWARFExpression &location = var_sp->LocationExpression();
+ Value location_result;
+ Error error;
+ if (location.Evaluate(nullptr, nullptr, nullptr,
+ LLDB_INVALID_ADDRESS, nullptr, nullptr,
+ location_result, &error)) {
+ if (location_result.GetValueType() ==
+ Value::eValueTypeFileAddress) {
+ lldb::addr_t file_addr =
+ location_result.GetScalar().ULongLong();
+ lldb::addr_t byte_size = 1;
+ if (var_sp->GetType())
+ byte_size = var_sp->GetType()->GetByteSize();
+ m_global_aranges_ap->Append(GlobalVariableMap::Entry(
+ file_addr, byte_size, var_sp.get()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ m_global_aranges_ap->Sort();
+ }
+ return *m_global_aranges_ap;
+}
+
+uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
+ uint32_t resolve_scope,
+ SymbolContext &sc) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "SymbolFileDWARF::"
+ "ResolveSymbolContext (so_addr = { "
+ "section = %p, offset = 0x%" PRIx64
+ " }, resolve_scope = 0x%8.8x)",
+ static_cast<void *>(so_addr.GetSection().get()),
+ so_addr.GetOffset(), resolve_scope);
+ uint32_t resolved = 0;
+ if (resolve_scope &
+ (eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextBlock |
+ eSymbolContextLineEntry | eSymbolContextVariable)) {
+ lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
+
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info) {
+ const dw_offset_t cu_offset =
+ debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
+ if (cu_offset == DW_INVALID_OFFSET) {
+ // Global variables are not in the compile unit address ranges. The only
+ // way to
+ // currently find global variables is to iterate over the
+ // .debug_pubnames or the
+ // __apple_names table and find all items in there that point to
+ // DW_TAG_variable
+ // DIEs and then find the address that matches.
+ if (resolve_scope & eSymbolContextVariable) {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry =
+ map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data) {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc) {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
+ }
+ return sc.GetResolvedMask();
+ }
+ }
+ } else {
+ uint32_t cu_idx = DW_INVALID_INDEX;
+ DWARFCompileUnit *dwarf_cu =
+ debug_info->GetCompileUnit(cu_offset, &cu_idx);
+ if (dwarf_cu) {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ if (sc.comp_unit) {
+ resolved |= eSymbolContextCompUnit;
+
+ bool force_check_line_table = false;
+ if (resolve_scope &
+ (eSymbolContextFunction | eSymbolContextBlock)) {
+ DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die) {
+ sc.function =
+ sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
+ if (sc.function == NULL)
+ sc.function = ParseCompileUnitFunction(sc, function_die);
+
+ if (sc.function && (resolve_scope & eSymbolContextBlock))
+ block_die = function_die.LookupDeepestBlock(file_vm_addr);
+ } else {
+ // We might have had a compile unit that had discontiguous
+ // address ranges where the gaps are symbols that don't have
+ // any debug info. Discontiguous compile unit address ranges
+ // should only happen when there aren't other functions from
+ // other compile units in these gaps. This helps keep the size
+ // of the aranges down.
+ force_check_line_table = true;
+ }
+
+ if (sc.function != NULL) {
+ resolved |= eSymbolContextFunction;
+
+ if (resolve_scope & eSymbolContextBlock) {
+ Block &block = sc.function->GetBlock(true);
+
+ if (block_die)
+ sc.block = block.FindBlockByID(block_die.GetID());
+ else
+ sc.block = block.FindBlockByID(function_die.GetID());
+ if (sc.block)
+ resolved |= eSymbolContextBlock;
+ }
+ }
+ }
+
+ if ((resolve_scope & eSymbolContextLineEntry) ||
+ force_check_line_table) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+ if (line_table != NULL) {
+ // And address that makes it into this function should be in
+ // terms
+ // of this debug file if there is no debug map, or it will be an
+ // address in the .o file which needs to be fixed up to be in
+ // terms
+ // of the debug map executable. Either way, calling
+ // FixupAddress()
+ // will work for us.
+ Address exe_so_addr(so_addr);
+ if (FixupAddress(exe_so_addr)) {
+ if (line_table->FindLineEntryByAddress(exe_so_addr,
+ sc.line_entry)) {
+ resolved |= eSymbolContextLineEntry;
+ }
+ }
+ }
+ }
+
+ if (force_check_line_table &&
+ !(resolved & eSymbolContextLineEntry)) {
+ // We might have had a compile unit that had discontiguous
+ // address ranges where the gaps are symbols that don't have
+ // any debug info. Discontiguous compile unit address ranges
+ // should only happen when there aren't other functions from
+ // other compile units in these gaps. This helps keep the size
+ // of the aranges down.
+ sc.comp_unit = NULL;
+ resolved &= ~eSymbolContextCompUnit;
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8x: compile unit %u failed to create a valid "
+ "lldb_private::CompileUnit class.",
+ cu_offset, cu_idx);
+ }
+ }
+ }
+ }
+ }
+ return resolved;
+}
+
+uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList &sc_list) {
+ const uint32_t prev_size = sc_list.GetSize();
+ if (resolve_scope & eSymbolContextCompUnit) {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info) {
+ uint32_t cu_idx;
+ DWARFCompileUnit *dwarf_cu = NULL;
+
+ for (cu_idx = 0;
+ (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL;
+ ++cu_idx) {
+ CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ const bool full_match = (bool)file_spec.GetDirectory();
+ bool file_spec_matches_cu_file_spec =
+ dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
+ if (check_inlines || file_spec_matches_cu_file_spec) {
+ SymbolContext sc(m_obj_file->GetModule());
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+ if (sc.comp_unit) {
+ uint32_t file_idx = UINT32_MAX;
+
+ // If we are looking for inline functions only and we don't
+ // find it in the support files, we are done.
+ if (check_inlines) {
+ file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
+ 1, file_spec, true);
+ if (file_idx == UINT32_MAX)
+ continue;
+ }
+
+ if (line != 0) {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table != NULL && line != 0) {
+ // We will have already looked up the file index if
+ // we are searching for inline entries.
+ if (!check_inlines)
+ file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
+ 1, file_spec, true);
+
+ if (file_idx != UINT32_MAX) {
+ uint32_t found_line;
+ uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
+ 0, file_idx, line, false, &sc.line_entry);
+ found_line = sc.line_entry.line;
+
+ while (line_idx != UINT32_MAX) {
+ sc.function = NULL;
+ sc.block = NULL;
+ if (resolve_scope &
+ (eSymbolContextFunction | eSymbolContextBlock)) {
+ const lldb::addr_t file_vm_addr =
+ sc.line_entry.range.GetBaseAddress().GetFileAddress();
+ if (file_vm_addr != LLDB_INVALID_ADDRESS) {
+ DWARFDIE function_die =
+ dwarf_cu->LookupAddress(file_vm_addr);
+ DWARFDIE block_die;
+ if (function_die) {
+ sc.function =
+ sc.comp_unit
+ ->FindFunctionByUID(function_die.GetID())
+ .get();
+ if (sc.function == NULL)
+ sc.function =
+ ParseCompileUnitFunction(sc, function_die);
+
+ if (sc.function &&
+ (resolve_scope & eSymbolContextBlock))
+ block_die =
+ function_die.LookupDeepestBlock(file_vm_addr);
}
- }
- m_external_type_modules[const_name] = module_sp;
- }
- }
- }
- }
-}
-SymbolFileDWARF::GlobalVariableMap &
-SymbolFileDWARF::GetGlobalAranges()
-{
- if (!m_global_aranges_ap)
- {
- m_global_aranges_ap.reset (new GlobalVariableMap());
-
- ModuleSP module_sp = GetObjectFile()->GetModule();
- if (module_sp)
- {
- const size_t num_cus = module_sp->GetNumCompileUnits();
- for (size_t i = 0; i < num_cus; ++i)
- {
- CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
- if (cu_sp)
- {
- VariableListSP globals_sp = cu_sp->GetVariableList(true);
- if (globals_sp)
- {
- const size_t num_globals = globals_sp->GetSize();
- for (size_t g = 0; g < num_globals; ++g)
- {
- VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
- if (var_sp && !var_sp->GetLocationIsConstantValueData())
- {
- const DWARFExpression &location = var_sp->LocationExpression();
- Value location_result;
- Error error;
- if (location.Evaluate(nullptr, nullptr, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr, location_result, &error))
- {
- if (location_result.GetValueType() == Value::eValueTypeFileAddress)
- {
- lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
- lldb::addr_t byte_size = 1;
- if (var_sp->GetType())
- byte_size = var_sp->GetType()->GetByteSize();
- m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
- }
- }
- }
- }
- }
- }
- }
- }
- m_global_aranges_ap->Sort();
- }
- return *m_global_aranges_ap;
-}
+ if (sc.function != NULL) {
+ Block &block = sc.function->GetBlock(true);
-
-uint32_t
-SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
-{
- Timer scoped_timer(LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
- static_cast<void*>(so_addr.GetSection().get()),
- so_addr.GetOffset(), resolve_scope);
- uint32_t resolved = 0;
- if (resolve_scope & ( eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextBlock |
- eSymbolContextLineEntry |
- eSymbolContextVariable ))
- {
- lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
-
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
- if (cu_offset == DW_INVALID_OFFSET)
- {
- // Global variables are not in the compile unit address ranges. The only way to
- // currently find global variables is to iterate over the .debug_pubnames or the
- // __apple_names table and find all items in there that point to DW_TAG_variable
- // DIEs and then find the address that matches.
- if (resolve_scope & eSymbolContextVariable)
- {
- GlobalVariableMap &map = GetGlobalAranges();
- const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
- if (entry && entry->data)
- {
- Variable *variable = entry->data;
- SymbolContextScope *scc = variable->GetSymbolContextScope();
- if (scc)
- {
- scc->CalculateSymbolContext(&sc);
- sc.variable = variable;
+ if (block_die)
+ sc.block = block.FindBlockByID(block_die.GetID());
+ else if (function_die)
+ sc.block =
+ block.FindBlockByID(function_die.GetID());
}
- return sc.GetResolvedMask();
- }
- }
- }
- else
- {
- uint32_t cu_idx = DW_INVALID_INDEX;
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx);
- if (dwarf_cu)
- {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- if (sc.comp_unit)
- {
- resolved |= eSymbolContextCompUnit;
-
- bool force_check_line_table = false;
- if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
- {
- DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die)
- {
- sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, function_die);
-
- if (sc.function && (resolve_scope & eSymbolContextBlock))
- block_die = function_die.LookupDeepestBlock(file_vm_addr);
- }
- else
- {
- // We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have
- // any debug info. Discontiguous compile unit address ranges
- // should only happen when there aren't other functions from
- // other compile units in these gaps. This helps keep the size
- // of the aranges down.
- force_check_line_table = true;
- }
-
- if (sc.function != NULL)
- {
- resolved |= eSymbolContextFunction;
-
- if (resolve_scope & eSymbolContextBlock)
- {
- Block& block = sc.function->GetBlock (true);
-
- if (block_die)
- sc.block = block.FindBlockByID (block_die.GetID());
- else
- sc.block = block.FindBlockByID (function_die.GetID());
- if (sc.block)
- resolved |= eSymbolContextBlock;
- }
- }
- }
-
- if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != NULL)
- {
- // And address that makes it into this function should be in terms
- // of this debug file if there is no debug map, or it will be an
- // address in the .o file which needs to be fixed up to be in terms
- // of the debug map executable. Either way, calling FixupAddress()
- // will work for us.
- Address exe_so_addr (so_addr);
- if (FixupAddress(exe_so_addr))
- {
- if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
- }
- }
- }
-
- if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
- {
- // We might have had a compile unit that had discontiguous
- // address ranges where the gaps are symbols that don't have
- // any debug info. Discontiguous compile unit address ranges
- // should only happen when there aren't other functions from
- // other compile units in these gaps. This helps keep the size
- // of the aranges down.
- sc.comp_unit = NULL;
- resolved &= ~eSymbolContextCompUnit;
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
- cu_offset,
- cu_idx);
+ }
}
- }
- }
- }
- }
- return resolved;
-}
-
-
-uint32_t
-SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
-{
- const uint32_t prev_size = sc_list.GetSize();
- if (resolve_scope & eSymbolContextCompUnit)
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- uint32_t cu_idx;
- DWARFCompileUnit* dwarf_cu = NULL;
-
- for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
- {
- CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- const bool full_match = (bool)file_spec.GetDirectory();
- bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
- if (check_inlines || file_spec_matches_cu_file_spec)
- {
- SymbolContext sc (m_obj_file->GetModule());
- sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
- if (sc.comp_unit)
- {
- uint32_t file_idx = UINT32_MAX;
-
- // If we are looking for inline functions only and we don't
- // find it in the support files, we are done.
- if (check_inlines)
- {
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
- if (file_idx == UINT32_MAX)
- continue;
- }
+ sc_list.Append(sc);
+ line_idx = line_table->FindLineEntryIndexByFileIndex(
+ line_idx + 1, file_idx, found_line, true,
+ &sc.line_entry);
+ }
+ }
+ } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+ // only append the context if we aren't looking for inline call
+ // sites
+ // by file and line and if the file spec matches that of the
+ // compile unit
+ sc_list.Append(sc);
+ }
+ } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+ // only append the context if we aren't looking for inline call
+ // sites
+ // by file and line and if the file spec matches that of the
+ // compile unit
+ sc_list.Append(sc);
+ }
+
+ if (!check_inlines)
+ break;
+ }
+ }
+ }
+ }
+ }
+ return sc_list.GetSize() - prev_size;
+}
+
+void SymbolFileDWARF::Index() {
+ if (m_indexed)
+ return;
+ m_indexed = true;
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION, "SymbolFileDWARF::Index (%s)",
+ GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
- if (line != 0)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table != NULL && line != 0)
- {
- // We will have already looked up the file index if
- // we are searching for inline entries.
- if (!check_inlines)
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
-
- if (file_idx != UINT32_MAX)
- {
- uint32_t found_line;
- uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
- found_line = sc.line_entry.line;
-
- while (line_idx != UINT32_MAX)
- {
- sc.function = NULL;
- sc.block = NULL;
- if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
- {
- const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
- if (file_vm_addr != LLDB_INVALID_ADDRESS)
- {
- DWARFDIE function_die = dwarf_cu->LookupAddress(file_vm_addr);
- DWARFDIE block_die;
- if (function_die)
- {
- sc.function = sc.comp_unit->FindFunctionByUID (function_die.GetID()).get();
- if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, function_die);
-
- if (sc.function && (resolve_scope & eSymbolContextBlock))
- block_die = function_die.LookupDeepestBlock(file_vm_addr);
- }
-
- if (sc.function != NULL)
- {
- Block& block = sc.function->GetBlock (true);
-
- if (block_die)
- sc.block = block.FindBlockByID (block_die.GetID());
- else if (function_die)
- sc.block = block.FindBlockByID (function_die.GetID());
- }
- }
- }
-
- sc_list.Append(sc);
- line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
- }
- }
- }
- else if (file_spec_matches_cu_file_spec && !check_inlines)
- {
- // only append the context if we aren't looking for inline call sites
- // by file and line and if the file spec matches that of the compile unit
- sc_list.Append(sc);
- }
- }
- else if (file_spec_matches_cu_file_spec && !check_inlines)
- {
- // only append the context if we aren't looking for inline call sites
- // by file and line and if the file spec matches that of the compile unit
- sc_list.Append(sc);
- }
+ DWARFDebugInfo *debug_info = DebugInfo();
+ if (debug_info) {
+ const uint32_t num_compile_units = GetNumCompileUnits();
+ if (num_compile_units == 0)
+ return;
- if (!check_inlines)
- break;
- }
- }
- }
- }
- }
- return sc_list.GetSize() - prev_size;
-}
+ std::vector<NameToDIE> function_basename_index(num_compile_units);
+ std::vector<NameToDIE> function_fullname_index(num_compile_units);
+ std::vector<NameToDIE> function_method_index(num_compile_units);
+ std::vector<NameToDIE> function_selector_index(num_compile_units);
+ std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
+ std::vector<NameToDIE> global_index(num_compile_units);
+ std::vector<NameToDIE> type_index(num_compile_units);
+ std::vector<NameToDIE> namespace_index(num_compile_units);
+
+ std::vector<bool> clear_cu_dies(num_compile_units, false);
+ auto parser_fn = [this, debug_info, &function_basename_index,
+ &function_fullname_index, &function_method_index,
+ &function_selector_index, &objc_class_selectors_index,
+ &global_index, &type_index,
+ &namespace_index](uint32_t cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu) {
+ dwarf_cu->Index(
+ function_basename_index[cu_idx], function_fullname_index[cu_idx],
+ function_method_index[cu_idx], function_selector_index[cu_idx],
+ objc_class_selectors_index[cu_idx], global_index[cu_idx],
+ type_index[cu_idx], namespace_index[cu_idx]);
+ }
+ return cu_idx;
+ };
-void
-SymbolFileDWARF::Index ()
-{
- if (m_indexed)
- return;
- m_indexed = true;
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARF::Index (%s)",
- GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
-
- DWARFDebugInfo* debug_info = DebugInfo();
- if (debug_info)
- {
- const uint32_t num_compile_units = GetNumCompileUnits();
- if (num_compile_units == 0)
- return;
-
- std::vector<NameToDIE> function_basename_index(num_compile_units);
- std::vector<NameToDIE> function_fullname_index(num_compile_units);
- std::vector<NameToDIE> function_method_index(num_compile_units);
- std::vector<NameToDIE> function_selector_index(num_compile_units);
- std::vector<NameToDIE> objc_class_selectors_index(num_compile_units);
- std::vector<NameToDIE> global_index(num_compile_units);
- std::vector<NameToDIE> type_index(num_compile_units);
- std::vector<NameToDIE> namespace_index(num_compile_units);
-
- std::vector<bool> clear_cu_dies(num_compile_units, false);
- auto parser_fn = [this,
- debug_info,
- &function_basename_index,
- &function_fullname_index,
- &function_method_index,
- &function_selector_index,
- &objc_class_selectors_index,
- &global_index,
- &type_index,
- &namespace_index](uint32_t cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- {
- dwarf_cu->Index(function_basename_index[cu_idx],
- function_fullname_index[cu_idx],
- function_method_index[cu_idx],
- function_selector_index[cu_idx],
- objc_class_selectors_index[cu_idx],
- global_index[cu_idx],
- type_index[cu_idx],
- namespace_index[cu_idx]);
- }
- return cu_idx;
- };
+ auto extract_fn = [this, debug_info, num_compile_units](uint32_t cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu) {
+ // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
+ // DIEs for a compile unit have already been parsed.
+ return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
+ }
+ return std::make_pair(cu_idx, false);
+ };
- auto extract_fn = [this,
- debug_info,
- num_compile_units](uint32_t cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu)
- {
- // dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
- // DIEs for a compile unit have already been parsed.
- return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
- }
- return std::make_pair(cu_idx, false);
- };
+ // Create a task runner that extracts dies for each DWARF compile unit in a
+ // separate thread
+ TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner_extract.AddTask(extract_fn, cu_idx);
- // Create a task runner that extracts dies for each DWARF compile unit in a separate thread
- TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- task_runner_extract.AddTask(extract_fn, cu_idx);
-
- //----------------------------------------------------------------------
- // First figure out which compile units didn't have their DIEs already
- // parsed and remember this. If no DIEs were parsed prior to this index
- // function call, we are going to want to clear the CU dies after we
- // are done indexing to make sure we don't pull in all DWARF dies, but
- // we need to wait until all compile units have been indexed in case
- // a DIE in one compile unit refers to another and the indexes accesses
- // those DIEs.
- //----------------------------------------------------------------------
- while (true)
- {
- auto f = task_runner_extract.WaitForNextCompletedTask();
- if (!f.valid())
- break;
- unsigned cu_idx;
- bool clear;
- std::tie(cu_idx, clear) = f.get();
- clear_cu_dies[cu_idx] = clear;
- }
-
- // Now create a task runner that can index each DWARF compile unit in a separate
- // thread so we can index quickly.
-
- TaskRunner<uint32_t> task_runner;
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- task_runner.AddTask(parser_fn, cu_idx);
-
- while (true)
- {
- std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
- if (!f.valid())
- break;
- uint32_t cu_idx = f.get();
+ //----------------------------------------------------------------------
+ // First figure out which compile units didn't have their DIEs already
+ // parsed and remember this. If no DIEs were parsed prior to this index
+ // function call, we are going to want to clear the CU dies after we
+ // are done indexing to make sure we don't pull in all DWARF dies, but
+ // we need to wait until all compile units have been indexed in case
+ // a DIE in one compile unit refers to another and the indexes accesses
+ // those DIEs.
+ //----------------------------------------------------------------------
+ while (true) {
+ auto f = task_runner_extract.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ unsigned cu_idx;
+ bool clear;
+ std::tie(cu_idx, clear) = f.get();
+ clear_cu_dies[cu_idx] = clear;
+ }
+
+ // Now create a task runner that can index each DWARF compile unit in a
+ // separate
+ // thread so we can index quickly.
- m_function_basename_index.Append(function_basename_index[cu_idx]);
- m_function_fullname_index.Append(function_fullname_index[cu_idx]);
- m_function_method_index.Append(function_method_index[cu_idx]);
- m_function_selector_index.Append(function_selector_index[cu_idx]);
- m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
- m_global_index.Append(global_index[cu_idx]);
- m_type_index.Append(type_index[cu_idx]);
- m_namespace_index.Append(namespace_index[cu_idx]);
- }
-
- TaskPool::RunTasks(
- [&]() { m_function_basename_index.Finalize(); },
- [&]() { m_function_fullname_index.Finalize(); },
- [&]() { m_function_method_index.Finalize(); },
- [&]() { m_function_selector_index.Finalize(); },
- [&]() { m_objc_class_selectors_index.Finalize(); },
- [&]() { m_global_index.Finalize(); },
- [&]() { m_type_index.Finalize(); },
- [&]() { m_namespace_index.Finalize(); });
-
- //----------------------------------------------------------------------
- // Keep memory down by clearing DIEs for any compile units if indexing
- // caused us to load the compile unit's DIEs.
- //----------------------------------------------------------------------
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- if (clear_cu_dies[cu_idx])
- debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
- }
-
-#if defined (ENABLE_DEBUG_PRINTF)
- StreamFile s(stdout, false);
- s.Printf ("DWARF index for '%s':",
- GetObjectFile()->GetFileSpec().GetPath().c_str());
- s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
- s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
- s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
- s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
- s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
- s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
- s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
- s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
-#endif
- }
-}
+ TaskRunner<uint32_t> task_runner;
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ task_runner.AddTask(parser_fn, cu_idx);
-bool
-SymbolFileDWARF::DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx)
-{
- if (decl_ctx == nullptr || !decl_ctx->IsValid())
- {
- // Invalid namespace decl which means we aren't matching only things
- // in this symbol file, so return true to indicate it matches this
- // symbol file.
- return true;
+ while (true) {
+ std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
+ if (!f.valid())
+ break;
+ uint32_t cu_idx = f.get();
+
+ m_function_basename_index.Append(function_basename_index[cu_idx]);
+ m_function_fullname_index.Append(function_fullname_index[cu_idx]);
+ m_function_method_index.Append(function_method_index[cu_idx]);
+ m_function_selector_index.Append(function_selector_index[cu_idx]);
+ m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
+ m_global_index.Append(global_index[cu_idx]);
+ m_type_index.Append(type_index[cu_idx]);
+ m_namespace_index.Append(namespace_index[cu_idx]);
+ }
+
+ TaskPool::RunTasks([&]() { m_function_basename_index.Finalize(); },
+ [&]() { m_function_fullname_index.Finalize(); },
+ [&]() { m_function_method_index.Finalize(); },
+ [&]() { m_function_selector_index.Finalize(); },
+ [&]() { m_objc_class_selectors_index.Finalize(); },
+ [&]() { m_global_index.Finalize(); },
+ [&]() { m_type_index.Finalize(); },
+ [&]() { m_namespace_index.Finalize(); });
+
+ //----------------------------------------------------------------------
+ // Keep memory down by clearing DIEs for any compile units if indexing
+ // caused us to load the compile unit's DIEs.
+ //----------------------------------------------------------------------
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ if (clear_cu_dies[cu_idx])
+ debug_info->GetCompileUnitAtIndex(cu_idx)->ClearDIEs(true);
}
- TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
- TypeSystem *type_system = GetTypeSystemForLanguage(decl_ctx_type_system->GetMinimumLanguage(nullptr));
- if (decl_ctx_type_system == type_system)
- return true; // The type systems match, return true
-
- // The namespace AST was valid, and it does not match...
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
-
- return false;
+#if defined(ENABLE_DEBUG_PRINTF)
+ StreamFile s(stdout, false);
+ s.Printf("DWARF index for '%s':",
+ GetObjectFile()->GetFileSpec().GetPath().c_str());
+ s.Printf("\nFunction basenames:\n");
+ m_function_basename_index.Dump(&s);
+ s.Printf("\nFunction fullnames:\n");
+ m_function_fullname_index.Dump(&s);
+ s.Printf("\nFunction methods:\n");
+ m_function_method_index.Dump(&s);
+ s.Printf("\nFunction selectors:\n");
+ m_function_selector_index.Dump(&s);
+ s.Printf("\nObjective C class selectors:\n");
+ m_objc_class_selectors_index.Dump(&s);
+ s.Printf("\nGlobals and statics:\n");
+ m_global_index.Dump(&s);
+ s.Printf("\nTypes:\n");
+ m_type_index.Dump(&s);
+ s.Printf("\nNamespaces:\n") m_namespace_index.Dump(&s);
+#endif
+ }
}
-uint32_t
-SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- append, max_matches);
-
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
-
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
-
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
-
- DIEArray die_offsets;
-
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
- const char *name_cstr = name.GetCString();
- llvm::StringRef basename;
- llvm::StringRef context;
-
- if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, basename))
- basename = name_cstr;
-
- m_apple_names_ap->FindByName (basename.data(), die_offsets);
- }
- }
- else
- {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
-
- m_global_index.Find (name, die_offsets);
- }
+bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
+ const lldb_private::CompilerDeclContext *decl_ctx) {
+ if (decl_ctx == nullptr || !decl_ctx->IsValid()) {
+ // Invalid namespace decl which means we aren't matching only things
+ // in this symbol file, so return true to indicate it matches this
+ // symbol file.
+ return true;
+ }
- const size_t num_die_matches = die_offsets.size();
- if (num_die_matches)
- {
- SymbolContext sc;
- sc.module_sp = m_obj_file->GetModule();
- assert (sc.module_sp);
-
- bool done = false;
- for (size_t i=0; i<num_die_matches && !done; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- switch (die.Tag())
- {
- default:
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_try_block:
- case DW_TAG_catch_block:
- break;
-
- case DW_TAG_variable:
- {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
-
- if (parent_decl_ctx)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- {
- CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
- if (!actual_parent_decl_ctx || actual_parent_decl_ctx != *parent_decl_ctx)
- continue;
- }
- }
+ TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
+ TypeSystem *type_system = GetTypeSystemForLanguage(
+ decl_ctx_type_system->GetMinimumLanguage(nullptr));
+ if (decl_ctx_type_system == type_system)
+ return true; // The type systems match, return true
- ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
+ // The namespace AST was valid, and it does not match...
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
- if (variables.GetSize() - original_size >= max_matches)
- done = true;
- }
- break;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
- }
- }
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "Valid namespace does not match symbol file");
- // Return the number of variable that were appended to the list
- const uint32_t num_matches = variables.GetSize() - original_size;
- if (log && num_matches > 0)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- append, max_matches,
- num_matches);
- }
- return num_matches;
+ return false;
}
-uint32_t
-SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+uint32_t SymbolFileDWARF::FindGlobalVariables(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches, VariableList &variables) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
- regex.GetText(), append,
- max_matches);
- }
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
+ "parent_decl_ctx=%p, append=%u, max_matches=%u, variables)",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx), append,
+ max_matches);
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- variables.Clear();
-
- // Remember how many variables are in the list before we search in case
- // we are appending the results to a variable list.
- const uint32_t original_size = variables.GetSize();
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- DIEArray die_offsets;
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
+
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
+
+ DIEArray die_offsets;
+
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ llvm::StringRef basename;
+ llvm::StringRef context;
+
+ if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
+ basename))
+ basename = name_cstr;
+
+ m_apple_names_ap->FindByName(basename.data(), die_offsets);
+ }
+ } else {
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
- DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
- }
- }
- else
- {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
-
- m_global_index.Find (regex, die_offsets);
- }
+ m_global_index.Find(name, die_offsets);
+ }
+ const size_t num_die_matches = die_offsets.size();
+ if (num_die_matches) {
SymbolContext sc;
sc.module_sp = m_obj_file->GetModule();
- assert (sc.module_sp);
-
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+ assert(sc.module_sp);
- ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
+ bool done = false;
+ for (size_t i = 0; i < num_die_matches && !done; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
- if (variables.GetSize() - original_size >= max_matches)
- break;
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
- die_ref.die_offset, regex.GetText());
- }
- }
- }
- }
-
- // Return the number of variable that were appended to the list
- return variables.GetSize() - original_size;
-}
+ if (die) {
+ switch (die.Tag()) {
+ default:
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_try_block:
+ case DW_TAG_catch_block:
+ break;
+
+ case DW_TAG_variable: {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
+
+ if (parent_decl_ctx) {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast) {
+ CompilerDeclContext actual_parent_decl_ctx =
+ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ if (!actual_parent_decl_ctx ||
+ actual_parent_decl_ctx != *parent_decl_ctx)
+ continue;
+ }
+ }
+
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false,
+ &variables);
+
+ if (variables.GetSize() - original_size >= max_matches)
+ done = true;
+ } break;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
+ }
+ }
+ }
+ }
+
+ // Return the number of variable that were appended to the list
+ const uint32_t num_matches = variables.GetSize() - original_size;
+ if (log && num_matches > 0) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", "
+ "parent_decl_ctx=%p, append=%u, max_matches=%u, variables) => %u",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx), append,
+ max_matches, num_matches);
+ }
+ return num_matches;
+}
+
+uint32_t SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex,
+ bool append, uint32_t max_matches,
+ VariableList &variables) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, "
+ "max_matches=%u, variables)",
+ regex.GetText(), append, max_matches);
+ }
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
-bool
-SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DWARFDIE die = DebugInfo()->GetDIE (die_ref);
- return ResolveFunction (die, include_inlines, sc_list);
-}
-
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ variables.Clear();
+
+ // Remember how many variables are in the list before we search in case
+ // we are appending the results to a variable list.
+ const uint32_t original_size = variables.GetSize();
+
+ DIEArray die_offsets;
+
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex(regex,
+ hash_data_array))
+ DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
+ }
+ } else {
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
+
+ m_global_index.Find(regex, die_offsets);
+ }
+
+ SymbolContext sc;
+ sc.module_sp = m_obj_file->GetModule();
+ assert(sc.module_sp);
+
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
-bool
-SymbolFileDWARF::ResolveFunction (const DWARFDIE &orig_die,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- SymbolContext sc;
+ if (die) {
+ sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU(), UINT32_MAX);
- if (!orig_die)
- return false;
+ ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
- // If we were passed a die that is not a function, just return false...
- if (!(orig_die.Tag() == DW_TAG_subprogram || (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
- return false;
-
- DWARFDIE die = orig_die;
- DWARFDIE inlined_die;
- if (die.Tag() == DW_TAG_inlined_subroutine)
- {
- inlined_die = die;
-
- while (1)
- {
- die = die.GetParent();
-
- if (die)
- {
- if (die.Tag() == DW_TAG_subprogram)
- break;
- }
- else
- break;
- }
- }
- assert (die && die.Tag() == DW_TAG_subprogram);
- if (GetFunction (die, sc))
- {
- Address addr;
- // Parse all blocks if needed
- if (inlined_die)
- {
- Block &function_block = sc.function->GetBlock (true);
- sc.block = function_block.FindBlockByID (inlined_die.GetID());
- if (sc.block == NULL)
- sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
- if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
- addr.Clear();
- }
- else
- {
- sc.block = NULL;
- addr = sc.function->GetAddressRange().GetBaseAddress();
- }
-
- if (addr.IsValid())
- {
- sc_list.Append(sc);
- return true;
+ if (variables.GetSize() - original_size >= max_matches)
+ break;
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for regex '%s')\n",
+ die_ref.die_offset, regex.GetText());
}
+ }
}
-
- return false;
-}
+ }
-void
-SymbolFileDWARF::FindFunctions (const ConstString &name,
- const NameToDIE &name_to_die,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DIEArray die_offsets;
- if (name_to_die.Find (name, die_offsets))
- {
- ParseFunctions (die_offsets, include_inlines, sc_list);
- }
+ // Return the number of variable that were appended to the list
+ return variables.GetSize() - original_size;
}
-
-void
-SymbolFileDWARF::FindFunctions (const RegularExpression ®ex,
- const NameToDIE &name_to_die,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DIEArray die_offsets;
- if (name_to_die.Find (regex, die_offsets))
- {
- ParseFunctions (die_offsets, include_inlines, sc_list);
- }
+bool SymbolFileDWARF::ResolveFunction(const DIERef &die_ref,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ DWARFDIE die = DebugInfo()->GetDIE(die_ref);
+ return ResolveFunction(die, include_inlines, sc_list);
}
+bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ SymbolContext sc;
-void
-SymbolFileDWARF::FindFunctions (const RegularExpression ®ex,
- const DWARFMappedHash::MemoryTable &memory_table,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- DIEArray die_offsets;
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
- {
- DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
- ParseFunctions (die_offsets, include_inlines, sc_list);
- }
-}
-
-void
-SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
- bool include_inlines,
- SymbolContextList& sc_list)
-{
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- ResolveFunction (die_offsets[i], include_inlines, sc_list);
- }
-}
-
-bool
-SymbolFileDWARF::DIEInDeclContext (const CompilerDeclContext *decl_ctx,
- const DWARFDIE &die)
-{
- // If we have no parent decl context to match this DIE matches, and if the parent
- // decl context isn't valid, we aren't trying to look for any particular decl
- // context so any die matches.
- if (decl_ctx == nullptr || !decl_ctx->IsValid())
- return true;
-
- if (die)
- {
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- {
- CompilerDeclContext actual_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF (die);
- if (actual_decl_ctx)
- return actual_decl_ctx == *decl_ctx;
- }
- }
+ if (!orig_die)
return false;
-}
-uint32_t
-SymbolFileDWARF::FindFunctions (const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask,
- bool include_inlines,
- bool append,
- SymbolContextList& sc_list)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARF::FindFunctions (name = '%s')",
- name.AsCString());
+ // If we were passed a die that is not a function, just return false...
+ if (!(orig_die.Tag() == DW_TAG_subprogram ||
+ (include_inlines && orig_die.Tag() == DW_TAG_inlined_subroutine)))
+ return false;
- // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
- assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
+ DWARFDIE die = orig_die;
+ DWARFDIE inlined_die;
+ if (die.Tag() == DW_TAG_inlined_subroutine) {
+ inlined_die = die;
+
+ while (1) {
+ die = die.GetParent();
+
+ if (die) {
+ if (die.Tag() == DW_TAG_subprogram)
+ break;
+ } else
+ break;
+ }
+ }
+ assert(die && die.Tag() == DW_TAG_subprogram);
+ if (GetFunction(die, sc)) {
+ Address addr;
+ // Parse all blocks if needed
+ if (inlined_die) {
+ Block &function_block = sc.function->GetBlock(true);
+ sc.block = function_block.FindBlockByID(inlined_die.GetID());
+ if (sc.block == NULL)
+ sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
+ if (sc.block == NULL || sc.block->GetStartAddress(addr) == false)
+ addr.Clear();
+ } else {
+ sc.block = NULL;
+ addr = sc.function->GetAddressRange().GetBaseAddress();
+ }
+
+ if (addr.IsValid()) {
+ sc_list.Append(sc);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void SymbolFileDWARF::FindFunctions(const ConstString &name,
+ const NameToDIE &name_to_die,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ DIEArray die_offsets;
+ if (name_to_die.Find(name, die_offsets)) {
+ ParseFunctions(die_offsets, include_inlines, sc_list);
+ }
+}
+
+void SymbolFileDWARF::FindFunctions(const RegularExpression ®ex,
+ const NameToDIE &name_to_die,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ DIEArray die_offsets;
+ if (name_to_die.Find(regex, die_offsets)) {
+ ParseFunctions(die_offsets, include_inlines, sc_list);
+ }
+}
+
+void SymbolFileDWARF::FindFunctions(
+ const RegularExpression ®ex,
+ const DWARFMappedHash::MemoryTable &memory_table, bool include_inlines,
+ SymbolContextList &sc_list) {
+ DIEArray die_offsets;
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (memory_table.AppendAllDIEsThatMatchingRegex(regex, hash_data_array)) {
+ DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
+ ParseFunctions(die_offsets, include_inlines, sc_list);
+ }
+}
+
+void SymbolFileDWARF::ParseFunctions(const DIEArray &die_offsets,
+ bool include_inlines,
+ SymbolContextList &sc_list) {
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i)
+ ResolveFunction(die_offsets[i], include_inlines, sc_list);
+ }
+}
+
+bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
+ const DWARFDIE &die) {
+ // If we have no parent decl context to match this DIE matches, and if the
+ // parent
+ // decl context isn't valid, we aren't trying to look for any particular decl
+ // context so any die matches.
+ if (decl_ctx == nullptr || !decl_ctx->IsValid())
+ return true;
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
- name.GetCString(),
- name_type_mask,
- append);
+ if (die) {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast) {
+ CompilerDeclContext actual_decl_ctx =
+ dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
+ if (actual_decl_ctx)
+ return actual_decl_ctx == *decl_ctx;
}
+ }
+ return false;
+}
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
-
- // If name is empty then we won't find anything.
- if (name.IsEmpty())
- return 0;
+uint32_t
+SymbolFileDWARF::FindFunctions(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines,
+ bool append, SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARF::FindFunctions (name = '%s')",
+ name.AsCString());
+
+ // eFunctionNameTypeAuto should be pre-resolved by a call to
+ // Module::PrepareForFunctionNameLookup()
+ assert((name_type_mask & eFunctionNameTypeAuto) == 0);
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, append=%u, sc_list)",
+ name.GetCString(), name_type_mask, append);
+ }
+
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ sc_list.Clear();
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ return 0;
- const char *name_cstr = name.GetCString();
+ // If name is empty then we won't find anything.
+ if (name.IsEmpty())
+ return 0;
- const uint32_t original_size = sc_list.GetSize();
-
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
+ // Remember how many sc_list are in the list before we search in case
+ // we are appending the results to a variable list.
- std::set<const DWARFDebugInfoEntry *> resolved_dies;
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
-
- DIEArray die_offsets;
-
- uint32_t num_matches = 0;
-
- if (name_type_mask & eFunctionNameTypeFull)
- {
- // If they asked for the full name, match what they typed. At some point we may
- // want to canonicalize this (strip double spaces, etc. For now, we just add all the
- // dies that we find by exact match.
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
- for (uint32_t i = 0; i < num_matches; i++)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE (die_ref);
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- }
+ const char *name_cstr = name.GetCString();
- if (name_type_mask & eFunctionNameTypeSelector)
- {
- if (parent_decl_ctx && parent_decl_ctx->IsValid())
- return 0; // no selectors in namespaces
-
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
- // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
- // and if it is an ObjC method name, we're good.
-
- for (uint32_t i = 0; i < num_matches; i++)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE (die_ref);
- if (die)
- {
- const char *die_name = die.GetName();
- if (ObjCLanguage::IsPossibleObjCMethodName(die_name))
- {
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- die_offsets.clear();
- }
-
- if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) || name_type_mask & eFunctionNameTypeBase)
- {
- // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
- // extract the base name, look that up, and if there is any other information in the name we were
- // passed in we have to post-filter based on that.
-
- // FIXME: Arrange the logic above so that we don't calculate the base name twice:
- num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
-
- for (uint32_t i = 0; i < num_matches; i++)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = info->GetDIE (die_ref);
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
-
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() && ResolveFunction (die, include_inlines, sc_list))
- {
- bool keep_die = true;
- if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
- {
- // We are looking for either basenames or methods, so we need to
- // trim out the ones we won't want by looking at the type
- SymbolContext sc;
- if (sc_list.GetLastContext(sc))
- {
- if (sc.block)
- {
- // We have an inlined function
- }
- else if (sc.function)
- {
- Type *type = sc.function->GetType();
-
- if (type)
- {
- CompilerDeclContext decl_ctx = GetDeclContextContainingUID (type->GetID());
- if (decl_ctx.IsStructUnionOrClass())
- {
- if (name_type_mask & eFunctionNameTypeBase)
- {
- sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
- keep_die = false;
- }
- }
- else
- {
- if (name_type_mask & eFunctionNameTypeMethod)
- {
- sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
- keep_die = false;
- }
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
- die_ref.die_offset);
- }
- }
- }
- }
- if (keep_die)
- resolved_dies.insert(die.GetDIE());
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
- die_ref.die_offset, name_cstr);
- }
- }
- die_offsets.clear();
- }
- }
- }
- else
- {
+ const uint32_t original_size = sc_list.GetSize();
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- if (name_type_mask & eFunctionNameTypeFull)
- {
- FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
-
- // FIXME Temporary workaround for global/anonymous namespace
- // functions debugging FreeBSD and Linux binaries.
- // If we didn't find any functions in the global namespace try
- // looking in the basename index but ignore any returned
- // functions that have a namespace but keep functions which
- // have an anonymous namespace
- // TODO: The arch in the object file isn't correct for MSVC
- // binaries on windows, we should find a way to make it
- // correct and handle those symbols as well.
- if (sc_list.GetSize() == original_size)
- {
- ArchSpec arch;
- if (!parent_decl_ctx &&
- GetObjectFile()->GetArchitecture(arch) &&
- (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
- arch.GetMachine() == llvm::Triple::hexagon))
- {
- SymbolContextList temp_sc_list;
- FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
- SymbolContext sc;
- for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
- {
- if (temp_sc_list.GetContextAtIndex(i, sc))
- {
- ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
- ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
- // Mangled names on Linux and FreeBSD are of the form:
- // _ZN18function_namespace13function_nameEv.
- if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
- !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
- {
- sc_list.Append(sc);
- }
+ std::set<const DWARFDebugInfoEntry *> resolved_dies;
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+
+ DIEArray die_offsets;
+
+ uint32_t num_matches = 0;
+
+ if (name_type_mask & eFunctionNameTypeFull) {
+ // If they asked for the full name, match what they typed. At some
+ // point we may
+ // want to canonicalize this (strip double spaces, etc. For now, we
+ // just add all the
+ // dies that we find by exact match.
+ num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
+ for (uint32_t i = 0; i < num_matches; i++) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE(die_ref);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')",
+ die_ref.die_offset, name_cstr);
+ }
+ }
+ }
+
+ if (name_type_mask & eFunctionNameTypeSelector) {
+ if (parent_decl_ctx && parent_decl_ctx->IsValid())
+ return 0; // no selectors in namespaces
+
+ num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
+ // Now make sure these are actually ObjC methods. In this case we can
+ // simply look up the name,
+ // and if it is an ObjC method name, we're good.
+
+ for (uint32_t i = 0; i < num_matches; i++) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE(die_ref);
+ if (die) {
+ const char *die_name = die.GetName();
+ if (ObjCLanguage::IsPossibleObjCMethodName(die_name)) {
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportError(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')",
+ die_ref.die_offset, name_cstr);
+ }
+ }
+ die_offsets.clear();
+ }
+
+ if (((name_type_mask & eFunctionNameTypeMethod) && !parent_decl_ctx) ||
+ name_type_mask & eFunctionNameTypeBase) {
+ // The apple_names table stores just the "base name" of C++ methods in
+ // the table. So we have to
+ // extract the base name, look that up, and if there is any other
+ // information in the name we were
+ // passed in we have to post-filter based on that.
+
+ // FIXME: Arrange the logic above so that we don't calculate the base
+ // name twice:
+ num_matches = m_apple_names_ap->FindByName(name_cstr, die_offsets);
+
+ for (uint32_t i = 0; i < num_matches; i++) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = info->GetDIE(die_ref);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end() &&
+ ResolveFunction(die, include_inlines, sc_list)) {
+ bool keep_die = true;
+ if ((name_type_mask &
+ (eFunctionNameTypeBase | eFunctionNameTypeMethod)) !=
+ (eFunctionNameTypeBase | eFunctionNameTypeMethod)) {
+ // We are looking for either basenames or methods, so we need to
+ // trim out the ones we won't want by looking at the type
+ SymbolContext sc;
+ if (sc_list.GetLastContext(sc)) {
+ if (sc.block) {
+ // We have an inlined function
+ } else if (sc.function) {
+ Type *type = sc.function->GetType();
+
+ if (type) {
+ CompilerDeclContext decl_ctx =
+ GetDeclContextContainingUID(type->GetID());
+ if (decl_ctx.IsStructUnionOrClass()) {
+ if (name_type_mask & eFunctionNameTypeBase) {
+ sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
+ keep_die = false;
}
- }
- }
- }
- }
- DIEArray die_offsets;
- if (name_type_mask & eFunctionNameTypeBase)
- {
- uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
- for (uint32_t i = 0; i < num_base; i++)
- {
- DWARFDIE die = info->GetDIE (die_offsets[i]);
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
- }
- }
- }
- die_offsets.clear();
- }
-
- if (name_type_mask & eFunctionNameTypeMethod)
- {
- if (parent_decl_ctx && parent_decl_ctx->IsValid())
- return 0; // no methods in namespaces
-
- uint32_t num_base = m_function_method_index.Find(name, die_offsets);
- {
- for (uint32_t i = 0; i < num_base; i++)
- {
- DWARFDIE die = info->GetDIE (die_offsets[i]);
- if (die)
- {
- // If we get to here, the die is good, and we should add it:
- if (resolved_dies.find(die.GetDIE()) == resolved_dies.end())
- {
- if (ResolveFunction (die, include_inlines, sc_list))
- resolved_dies.insert(die.GetDIE());
+ } else {
+ if (name_type_mask & eFunctionNameTypeMethod) {
+ sc_list.RemoveContextAtIndex(sc_list.GetSize() - 1);
+ keep_die = false;
}
- }
- }
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportWarning(
+ "function at die offset 0x%8.8x had no function type",
+ die_ref.die_offset);
+ }
+ }
+ }
+ }
+ if (keep_die)
+ resolved_dies.insert(die.GetDIE());
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_names "
+ "accelerator table had bad die 0x%8.8x for '%s')",
+ die_ref.die_offset, name_cstr);
+ }
+ }
+ die_offsets.clear();
+ }
+ }
+ } else {
+
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
+
+ if (name_type_mask & eFunctionNameTypeFull) {
+ FindFunctions(name, m_function_fullname_index, include_inlines, sc_list);
+
+ // FIXME Temporary workaround for global/anonymous namespace
+ // functions debugging FreeBSD and Linux binaries.
+ // If we didn't find any functions in the global namespace try
+ // looking in the basename index but ignore any returned
+ // functions that have a namespace but keep functions which
+ // have an anonymous namespace
+ // TODO: The arch in the object file isn't correct for MSVC
+ // binaries on windows, we should find a way to make it
+ // correct and handle those symbols as well.
+ if (sc_list.GetSize() == original_size) {
+ ArchSpec arch;
+ if (!parent_decl_ctx && GetObjectFile()->GetArchitecture(arch) &&
+ (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
+ arch.GetMachine() == llvm::Triple::hexagon)) {
+ SymbolContextList temp_sc_list;
+ FindFunctions(name, m_function_basename_index, include_inlines,
+ temp_sc_list);
+ SymbolContext sc;
+ for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) {
+ if (temp_sc_list.GetContextAtIndex(i, sc)) {
+ ConstString mangled_name =
+ sc.GetFunctionName(Mangled::ePreferMangled);
+ ConstString demangled_name =
+ sc.GetFunctionName(Mangled::ePreferDemangled);
+ // Mangled names on Linux and FreeBSD are of the form:
+ // _ZN18function_namespace13function_nameEv.
+ if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
+ !strncmp(demangled_name.GetCString(), "(anonymous namespace)",
+ 21)) {
+ sc_list.Append(sc);
+ }
}
- die_offsets.clear();
+ }
}
-
- if ((name_type_mask & eFunctionNameTypeSelector) && (!parent_decl_ctx || !parent_decl_ctx->IsValid()))
- {
- FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
- }
-
- }
-
- // Return the number of variable that were appended to the list
- const uint32_t num_matches = sc_list.GetSize() - original_size;
-
- if (log && num_matches > 0)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
- name.GetCString(),
- name_type_mask,
- include_inlines,
- append,
- num_matches);
- }
- return num_matches;
-}
-
-uint32_t
-SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
-{
- Timer scoped_timer (LLVM_PRETTY_FUNCTION,
- "SymbolFileDWARF::FindFunctions (regex = '%s')",
- regex.GetText());
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
- regex.GetText(),
- append);
- }
-
-
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- sc_list.Clear();
-
- // Remember how many sc_list are in the list before we search in case
- // we are appending the results to a variable list.
- uint32_t original_size = sc_list.GetSize();
-
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
- }
- else
- {
- // Index the DWARF if we haven't already
- if (!m_indexed)
- Index ();
-
- FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
-
- FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
- }
-
- // Return the number of variable that were appended to the list
- return sc_list.GetSize() - original_size;
-}
-
-void
-SymbolFileDWARF::GetMangledNamesForFunction (const std::string &scope_qualified_name,
- std::vector<ConstString> &mangled_names)
-{
- DWARFDebugInfo* info = DebugInfo();
- uint32_t num_comp_units = 0;
- if (info)
- num_comp_units = info->GetNumCompileUnits();
-
- for (uint32_t i = 0; i < num_comp_units; i++)
- {
- DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i);
- if (cu == nullptr)
- continue;
-
- SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
- if (dwo)
- dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
- }
-
- NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
- if (iter == m_function_scope_qualified_name_map.end())
- return;
-
- DIERefSetSP set_sp = (*iter).second;
- std::set<DIERef>::iterator set_iter;
- for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++)
- {
- DWARFDIE die = DebugInfo()->GetDIE (*set_iter);
- mangled_names.push_back(ConstString(die.GetMangledName()));
- }
-}
-
-
-uint32_t
-SymbolFileDWARF::FindTypes (const SymbolContext& sc,
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap& types)
-{
- // If we aren't appending the results to this list, then clear the list
- if (!append)
- types.Clear();
-
- // Make sure we haven't already searched this SymbolFile before...
- if (searched_symbol_files.count(this))
- return 0;
- else
- searched_symbol_files.insert(this);
-
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
-
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- if (parent_decl_ctx)
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list)",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"),
- append, max_matches);
- else
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list)",
- name.GetCString(), append,
- max_matches);
+ }
}
-
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return 0;
-
DIEArray die_offsets;
+ if (name_type_mask & eFunctionNameTypeBase) {
+ uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
+ for (uint32_t i = 0; i < num_base; i++) {
+ DWARFDIE die = info->GetDIE(die_offsets[i]);
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
+ }
+ }
+ die_offsets.clear();
+ }
+
+ if (name_type_mask & eFunctionNameTypeMethod) {
+ if (parent_decl_ctx && parent_decl_ctx->IsValid())
+ return 0; // no methods in namespaces
+
+ uint32_t num_base = m_function_method_index.Find(name, die_offsets);
+ {
+ for (uint32_t i = 0; i < num_base; i++) {
+ DWARFDIE die = info->GetDIE(die_offsets[i]);
+ if (die) {
+ // If we get to here, the die is good, and we should add it:
+ if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) {
+ if (ResolveFunction(die, include_inlines, sc_list))
+ resolved_dies.insert(die.GetDIE());
+ }
+ }
+ }
+ }
+ die_offsets.clear();
+ }
+
+ if ((name_type_mask & eFunctionNameTypeSelector) &&
+ (!parent_decl_ctx || !parent_decl_ctx->IsValid())) {
+ FindFunctions(name, m_function_selector_index, include_inlines, sc_list);
+ }
+ }
+
+ // Return the number of variable that were appended to the list
+ const uint32_t num_matches = sc_list.GetSize() - original_size;
+
+ if (log && num_matches > 0) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindFunctions (name=\"%s\", "
+ "name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => "
+ "%u",
+ name.GetCString(), name_type_mask, include_inlines, append,
+ num_matches);
+ }
+ return num_matches;
+}
+
+uint32_t SymbolFileDWARF::FindFunctions(const RegularExpression ®ex,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "SymbolFileDWARF::FindFunctions (regex = '%s')",
+ regex.GetText());
+
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
+ regex.GetText(), append);
+ }
+
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ sc_list.Clear();
+
+ // Remember how many sc_list are in the list before we search in case
+ // we are appending the results to a variable list.
+ uint32_t original_size = sc_list.GetSize();
+
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get())
+ FindFunctions(regex, *m_apple_names_ap, include_inlines, sc_list);
+ } else {
+ // Index the DWARF if we haven't already
+ if (!m_indexed)
+ Index();
+
+ FindFunctions(regex, m_function_basename_index, include_inlines, sc_list);
+
+ FindFunctions(regex, m_function_fullname_index, include_inlines, sc_list);
+ }
+
+ // Return the number of variable that were appended to the list
+ return sc_list.GetSize() - original_size;
+}
+
+void SymbolFileDWARF::GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<ConstString> &mangled_names) {
+ DWARFDebugInfo *info = DebugInfo();
+ uint32_t num_comp_units = 0;
+ if (info)
+ num_comp_units = info->GetNumCompileUnits();
+
+ for (uint32_t i = 0; i < num_comp_units; i++) {
+ DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i);
+ if (cu == nullptr)
+ continue;
+
+ SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
+ if (dwo)
+ dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names);
+ }
+
+ NameToOffsetMap::iterator iter =
+ m_function_scope_qualified_name_map.find(scope_qualified_name);
+ if (iter == m_function_scope_qualified_name_map.end())
+ return;
+
+ DIERefSetSP set_sp = (*iter).second;
+ std::set<DIERef>::iterator set_iter;
+ for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) {
+ DWARFDIE die = DebugInfo()->GetDIE(*set_iter);
+ mangled_names.push_back(ConstString(die.GetMangledName()));
+ }
+}
+
+uint32_t SymbolFileDWARF::FindTypes(
+ const SymbolContext &sc, const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {
+ // If we aren't appending the results to this list, then clear the list
+ if (!append)
+ types.Clear();
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const char *name_cstr = name.GetCString();
- m_apple_types_ap->FindByName (name_cstr, die_offsets);
- }
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (name, die_offsets);
- }
-
- const size_t num_die_matches = die_offsets.size();
-
- if (num_die_matches)
- {
- const uint32_t initial_types_size = types.GetSize();
- for (size_t i=0; i<num_die_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- if (!DIEInDeclContext(parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- Type *matching_type = ResolveType (die, true, true);
- if (matching_type)
- {
- // We found a type pointer, now find the shared pointer form our type list
- types.InsertUnique (matching_type->shared_from_this());
- if (types.GetSize() >= max_matches)
- break;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
-
- }
- const uint32_t num_matches = types.GetSize() - initial_types_size;
- if (log && num_matches)
- {
- if (parent_decl_ctx)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(),
- static_cast<const void*>(parent_decl_ctx),
- parent_decl_ctx->GetName().AsCString("<NULL>"),
- append, max_matches,
- num_matches);
- }
- else
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = NULL, append=%u, max_matches=%u, type_list) => %u",
- name.GetCString(),
- append, max_matches,
- num_matches);
- }
- }
- return num_matches;
- }
- else
- {
- UpdateExternalModuleListIfNeeded();
-
- for (const auto &pair : m_external_type_modules)
- {
- ModuleSP external_module_sp = pair.second;
- if (external_module_sp)
- {
- SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
- if (sym_vendor)
- {
- const uint32_t num_external_matches = sym_vendor->FindTypes (sc,
- name,
- parent_decl_ctx,
- append,
- max_matches,
- searched_symbol_files,
- types);
- if (num_external_matches)
- return num_external_matches;
- }
- }
- }
- }
-
+ // Make sure we haven't already searched this SymbolFile before...
+ if (searched_symbol_files.count(this))
return 0;
-}
-
+ else
+ searched_symbol_files.insert(this);
-size_t
-SymbolFileDWARF::FindTypes (const std::vector<CompilerContext> &context,
- bool append,
- TypeMap& types)
-{
- if (!append)
- types.Clear();
-
- if (context.empty())
- return 0;
-
- DIEArray die_offsets;
-
- ConstString name = context.back().name;
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
- if (!name)
- return 0;
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const char *name_cstr = name.GetCString();
- m_apple_types_ap->FindByName (name_cstr, die_offsets);
- }
- }
+ if (log) {
+ if (parent_decl_ctx)
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "%p (\"%s\"), append=%u, max_matches=%u, type_list)",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches);
else
- {
- if (!m_indexed)
- Index ();
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = "
+ "NULL, append=%u, max_matches=%u, type_list)",
+ name.GetCString(), append, max_matches);
+ }
- m_type_index.Find (name, die_offsets);
- }
-
- const size_t num_die_matches = die_offsets.size();
-
- if (num_die_matches)
- {
- size_t num_matches = 0;
- for (size_t i=0; i<num_die_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- std::vector<CompilerContext> die_context;
- die.GetDWOContext(die_context);
- if (die_context != context)
- continue;
-
- Type *matching_type = ResolveType (die, true, true);
- if (matching_type)
- {
- // We found a type pointer, now find the shared pointer form our type list
- types.InsertUnique (matching_type->shared_from_this());
- ++num_matches;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
-
- }
- return num_matches;
- }
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return 0;
-}
+ DIEArray die_offsets;
-CompilerDeclContext
-SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx)
-{
- Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
- name.GetCString());
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ m_apple_types_ap->FindByName(name_cstr, die_offsets);
+ }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(name, die_offsets);
+ }
+
+ const size_t num_die_matches = die_offsets.size();
+
+ if (num_die_matches) {
+ const uint32_t initial_types_size = types.GetSize();
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ Type *matching_type = ResolveType(die, true, true);
+ if (matching_type) {
+ // We found a type pointer, now find the shared pointer form our type
+ // list
+ types.InsertUnique(matching_type->shared_from_this());
+ if (types.GetSize() >= max_matches)
+ break;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
+ }
+ }
+ }
+ const uint32_t num_matches = types.GetSize() - initial_types_size;
+ if (log && num_matches) {
+ if (parent_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u",
+ name.GetCString(), static_cast<const void *>(parent_decl_ctx),
+ parent_decl_ctx->GetName().AsCString("<NULL>"), append, max_matches,
+ num_matches);
+ } else {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx "
+ "= NULL, append=%u, max_matches=%u, type_list) => %u",
+ name.GetCString(), append, max_matches, num_matches);
+ }
}
+ return num_matches;
+ } else {
+ UpdateExternalModuleListIfNeeded();
- CompilerDeclContext namespace_decl_ctx;
-
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return namespace_decl_ctx;
+ for (const auto &pair : m_external_type_modules) {
+ ModuleSP external_module_sp = pair.second;
+ if (external_module_sp) {
+ SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
+ if (sym_vendor) {
+ const uint32_t num_external_matches =
+ sym_vendor->FindTypes(sc, name, parent_decl_ctx, append,
+ max_matches, searched_symbol_files, types);
+ if (num_external_matches)
+ return num_external_matches;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
+ bool append, TypeMap &types) {
+ if (!append)
+ types.Clear();
+ if (context.empty())
+ return 0;
- DWARFDebugInfo* info = DebugInfo();
- if (info)
- {
- DIEArray die_offsets;
+ DIEArray die_offsets;
- // Index if we already haven't to make sure the compile units
- // get indexed and make their global DIE index list
- if (m_using_apple_tables)
- {
- if (m_apple_namespaces_ap.get())
- {
- const char *name_cstr = name.GetCString();
- m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
- }
- }
- else
- {
- if (!m_indexed)
- Index ();
+ ConstString name = context.back().name;
- m_namespace_index.Find (name, die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
-
- if (die)
- {
- if (!DIEInDeclContext (parent_decl_ctx, die))
- continue; // The containing decl contexts don't match
-
- DWARFASTParser *dwarf_ast = die.GetDWARFParser();
- if (dwarf_ast)
- {
- namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF (die);
- if (namespace_decl_ctx)
- break;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, name.GetCString());
- }
- }
+ if (!name)
+ return 0;
- }
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ m_apple_types_ap->FindByName(name_cstr, die_offsets);
+ }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(name, die_offsets);
+ }
+
+ const size_t num_die_matches = die_offsets.size();
+
+ if (num_die_matches) {
+ size_t num_matches = 0;
+ for (size_t i = 0; i < num_die_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ std::vector<CompilerContext> die_context;
+ die.GetDWOContext(die_context);
+ if (die_context != context)
+ continue;
+
+ Type *matching_type = ResolveType(die, true, true);
+ if (matching_type) {
+ // We found a type pointer, now find the shared pointer form our type
+ // list
+ types.InsertUnique(matching_type->shared_from_this());
+ ++num_matches;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, name.GetCString());
}
+ }
}
- if (log && namespace_decl_ctx)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => CompilerDeclContext(%p/%p) \"%s\"",
- name.GetCString(),
- static_cast<const void*>(namespace_decl_ctx.GetTypeSystem()),
- static_cast<const void*>(namespace_decl_ctx.GetOpaqueDeclContext()),
- namespace_decl_ctx.GetName().AsCString("<NULL>"));
- }
+ return num_matches;
+ }
+ return 0;
+}
+CompilerDeclContext
+SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) {
+ Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
+ name.GetCString());
+ }
+
+ CompilerDeclContext namespace_decl_ctx;
+
+ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
return namespace_decl_ctx;
-}
-TypeSP
-SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context)
-{
- TypeSP type_sp;
- if (die)
- {
- Type *type_ptr = GetDIEToType().lookup (die.GetDIE());
- if (type_ptr == NULL)
- {
- CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
- assert (lldb_cu);
- SymbolContext sc(lldb_cu);
- const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE();
- while (parent_die != nullptr)
- {
- if (parent_die->Tag() == DW_TAG_subprogram)
- break;
- parent_die = parent_die->GetParent();
- }
- SymbolContext sc_backup = sc;
- if (resolve_function_context && parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc))
- sc = sc_backup;
-
- type_sp = ParseType(sc, die, NULL);
- }
- else if (type_ptr != DIE_IS_BEING_PARSED)
- {
- // Grab the existing type from the master types lists
- type_sp = type_ptr->shared_from_this();
- }
+ DWARFDebugInfo *info = DebugInfo();
+ if (info) {
+ DIEArray die_offsets;
+ // Index if we already haven't to make sure the compile units
+ // get indexed and make their global DIE index list
+ if (m_using_apple_tables) {
+ if (m_apple_namespaces_ap.get()) {
+ const char *name_cstr = name.GetCString();
+ m_apple_namespaces_ap->FindByName(name_cstr, die_offsets);
+ }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_namespace_index.Find(name, die_offsets);
}
- return type_sp;
-}
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+
+ if (die) {
+ if (!DIEInDeclContext(parent_decl_ctx, die))
+ continue; // The containing decl contexts don't match
+
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast) {
+ namespace_decl_ctx = dwarf_ast->GetDeclContextForUIDFromDWARF(die);
+ if (namespace_decl_ctx)
+ break;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified "
+ "(.apple_namespaces accelerator table had bad die 0x%8.8x for "
+ "'%s')\n",
+ die_ref.die_offset, name.GetCString());
+ }
+ }
+ }
+ }
+ }
+ if (log && namespace_decl_ctx) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => "
+ "CompilerDeclContext(%p/%p) \"%s\"",
+ name.GetCString(),
+ static_cast<const void *>(namespace_decl_ctx.GetTypeSystem()),
+ static_cast<const void *>(namespace_decl_ctx.GetOpaqueDeclContext()),
+ namespace_decl_ctx.GetName().AsCString("<NULL>"));
+ }
+
+ return namespace_decl_ctx;
+}
+
+TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
+ bool resolve_function_context) {
+ TypeSP type_sp;
+ if (die) {
+ Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
+ if (type_ptr == NULL) {
+ CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
+ assert(lldb_cu);
+ SymbolContext sc(lldb_cu);
+ const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
+ while (parent_die != nullptr) {
+ if (parent_die->Tag() == DW_TAG_subprogram)
+ break;
+ parent_die = parent_die->GetParent();
+ }
+ SymbolContext sc_backup = sc;
+ if (resolve_function_context && parent_die != nullptr &&
+ !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
+ sc = sc_backup;
+
+ type_sp = ParseType(sc, die, NULL);
+ } else if (type_ptr != DIE_IS_BEING_PARSED) {
+ // Grab the existing type from the master types lists
+ type_sp = type_ptr->shared_from_this();
+ }
+ }
+ return type_sp;
+}
DWARFDIE
-SymbolFileDWARF::GetDeclContextDIEContainingDIE (const DWARFDIE &orig_die)
-{
- if (orig_die)
- {
- DWARFDIE die = orig_die;
-
- while (die)
- {
- // If this is the original DIE that we are searching for a declaration
- // for, then don't look in the cache as we don't want our own decl
- // context to be our decl context...
- if (orig_die != die)
- {
- switch (die.Tag())
- {
- case DW_TAG_compile_unit:
- case DW_TAG_namespace:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type:
- case DW_TAG_lexical_block:
- case DW_TAG_subprogram:
- return die;
-
- default:
- break;
- }
- }
-
- DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
- if (spec_die)
- {
- DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
+ if (orig_die) {
+ DWARFDIE die = orig_die;
- DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
- if (abs_die)
- {
- DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
- if (decl_ctx_die)
- return decl_ctx_die;
- }
+ while (die) {
+ // If this is the original DIE that we are searching for a declaration
+ // for, then don't look in the cache as we don't want our own decl
+ // context to be our decl context...
+ if (orig_die != die) {
+ switch (die.Tag()) {
+ case DW_TAG_compile_unit:
+ case DW_TAG_namespace:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ case DW_TAG_lexical_block:
+ case DW_TAG_subprogram:
+ return die;
- die = die.GetParent();
+ default:
+ break;
}
+ }
+
+ DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification);
+ if (spec_die) {
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(spec_die);
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+
+ DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
+ if (abs_die) {
+ DWARFDIE decl_ctx_die = GetDeclContextDIEContainingDIE(abs_die);
+ if (decl_ctx_die)
+ return decl_ctx_die;
+ }
+
+ die = die.GetParent();
}
- return DWARFDIE();
+ }
+ return DWARFDIE();
}
-
Symbol *
-SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
-{
- Symbol *objc_class_symbol = NULL;
- if (m_obj_file)
- {
- Symtab *symtab = m_obj_file->GetSymtab ();
- if (symtab)
- {
- objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
- eSymbolTypeObjCClass,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
- }
- }
- return objc_class_symbol;
-}
-
-// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
-// then we can end up looking through all class types for a complete type and never find
-// the full definition. We need to know if this attribute is supported, so we determine
-// this here and cache th result. We also need to worry about the debug map DWARF file
+SymbolFileDWARF::GetObjCClassSymbol(const ConstString &objc_class_name) {
+ Symbol *objc_class_symbol = NULL;
+ if (m_obj_file) {
+ Symtab *symtab = m_obj_file->GetSymtab();
+ if (symtab) {
+ objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
+ objc_class_name, eSymbolTypeObjCClass, Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+ }
+ }
+ return objc_class_symbol;
+}
+
+// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If
+// they don't
+// then we can end up looking through all class types for a complete type and
+// never find
+// the full definition. We need to know if this attribute is supported, so we
+// determine
+// this here and cache th result. We also need to worry about the debug map
+// DWARF file
// if we are doing darwin DWARF in .o file debugging.
-bool
-SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
-{
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
- if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
- else
- {
- DWARFDebugInfo* debug_info = DebugInfo();
- const uint32_t num_compile_units = GetNumCompileUnits();
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- {
- DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
- if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
- {
- m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
- break;
- }
- }
- }
- if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
- return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
- }
- return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
+bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(
+ DWARFCompileUnit *cu) {
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
+ if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+ else {
+ DWARFDebugInfo *debug_info = DebugInfo();
+ const uint32_t num_compile_units = GetNumCompileUnits();
+ for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
+ DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+ if (dwarf_cu != cu &&
+ dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) {
+ m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+ break;
+ }
+ }
+ }
+ if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo &&
+ GetDebugMapSymfile())
+ return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type(this);
+ }
+ return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}
// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
-TypeSP
-SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const ConstString &type_name,
- bool must_be_implementation)
-{
-
- TypeSP type_sp;
-
- if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
- return type_sp;
-
- DIEArray die_offsets;
-
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const char *name_cstr = type_name.GetCString();
- m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
+TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const ConstString &type_name,
+ bool must_be_implementation) {
+
+ TypeSP type_sp;
+
+ if (!type_name || (must_be_implementation && !GetObjCClassSymbol(type_name)))
+ return type_sp;
+
+ DIEArray die_offsets;
+
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const char *name_cstr = type_name.GetCString();
+ m_apple_types_ap->FindCompleteObjCClassByName(name_cstr, die_offsets,
+ must_be_implementation);
+ }
+ } else {
+ if (!m_indexed)
+ Index();
+
+ m_type_index.Find(type_name, die_offsets);
+ }
+
+ const size_t num_matches = die_offsets.size();
+
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE type_die = GetDIE(die_ref);
+
+ if (type_die) {
+ bool try_resolving_type = false;
+
+ // Don't try and resolve the DIE we are looking for with the DIE itself!
+ if (type_die != die) {
+ switch (type_die.Tag()) {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ try_resolving_type = true;
+ break;
+ default:
+ break;
+ }
}
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (type_name, die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
-
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = GetDIE (die_ref);
-
- if (type_die)
- {
- bool try_resolving_type = false;
-
- // Don't try and resolve the DIE we are looking for with the DIE itself!
- if (type_die != die)
- {
- switch (type_die.Tag())
- {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- try_resolving_type = true;
- break;
- default:
- break;
- }
- }
-
- if (try_resolving_type)
- {
- if (must_be_implementation && type_die.Supports_DW_AT_APPLE_objc_complete_type())
- try_resolving_type = type_die.GetAttributeValueAsUnsigned (DW_AT_APPLE_objc_complete_type, 0);
-
- if (try_resolving_type)
- {
- Type *resolved_type = ResolveType (type_die, false, true);
- if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
- {
- DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
- die.GetID(),
- m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
- type_die.GetID(),
- type_cu->GetID());
-
- if (die)
- GetDIEToType()[die.GetDIE()] = resolved_type;
- type_sp = resolved_type->shared_from_this();
- break;
- }
- }
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, type_name.GetCString());
- }
- }
-
+
+ if (try_resolving_type) {
+ if (must_be_implementation &&
+ type_die.Supports_DW_AT_APPLE_objc_complete_type())
+ try_resolving_type = type_die.GetAttributeValueAsUnsigned(
+ DW_AT_APPLE_objc_complete_type, 0);
+
+ if (try_resolving_type) {
+ Type *resolved_type = ResolveType(type_die, false, true);
+ if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) {
+ DEBUG_PRINTF("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64
+ " (cu 0x%8.8" PRIx64 ")\n",
+ die.GetID(),
+ m_obj_file->GetFileSpec().GetFilename().AsCString(
+ "<Unknown>"),
+ type_die.GetID(), type_cu->GetID());
+
+ if (die)
+ GetDIEToType()[die.GetDIE()] = resolved_type;
+ type_sp = resolved_type->shared_from_this();
+ break;
+ }
+ }
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, type_name.GetCString());
}
+ }
}
- return type_sp;
+ }
+ return type_sp;
}
-
//----------------------------------------------------------------------
// This function helps to ensure that the declaration contexts match for
-// two different DIEs. Often times debug information will refer to a
+// two different DIEs. Often times debug information will refer to a
// forward declaration of a type (the equivalent of "struct my_struct;".
// There will often be a declaration of that type elsewhere that has the
// full definition. When we go looking for the full type "my_struct", we
// will find one or more matches in the accelerator tables and we will
-// then need to make sure the type was in the same declaration context
+// then need to make sure the type was in the same declaration context
// as the original DIE. This function can efficiently compare two DIEs
// and will return true when the declaration context matches, and false
-// when they don't.
+// when they don't.
//----------------------------------------------------------------------
-bool
-SymbolFileDWARF::DIEDeclContextsMatch (const DWARFDIE &die1,
- const DWARFDIE &die2)
-{
- if (die1 == die2)
- return true;
+bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE &die1,
+ const DWARFDIE &die2) {
+ if (die1 == die2)
+ return true;
- DWARFDIECollection decl_ctx_1;
- DWARFDIECollection decl_ctx_2;
- //The declaration DIE stack is a stack of the declaration context
- // DIEs all the way back to the compile unit. If a type "T" is
- // declared inside a class "B", and class "B" is declared inside
- // a class "A" and class "A" is in a namespace "lldb", and the
- // namespace is in a compile unit, there will be a stack of DIEs:
- //
- // [0] DW_TAG_class_type for "B"
- // [1] DW_TAG_class_type for "A"
- // [2] DW_TAG_namespace for "lldb"
- // [3] DW_TAG_compile_unit for the source file.
- //
- // We grab both contexts and make sure that everything matches
- // all the way back to the compiler unit.
-
- // First lets grab the decl contexts for both DIEs
- die1.GetDeclContextDIEs (decl_ctx_1);
- die2.GetDeclContextDIEs (decl_ctx_2);
- // Make sure the context arrays have the same size, otherwise
- // we are done
- const size_t count1 = decl_ctx_1.Size();
- const size_t count2 = decl_ctx_2.Size();
- if (count1 != count2)
- return false;
-
- // Make sure the DW_TAG values match all the way back up the
- // compile unit. If they don't, then we are done.
- DWARFDIE decl_ctx_die1;
- DWARFDIE decl_ctx_die2;
- size_t i;
- for (i=0; i<count1; i++)
- {
- decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
- decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
- if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
- return false;
- }
+ DWARFDIECollection decl_ctx_1;
+ DWARFDIECollection decl_ctx_2;
+ // The declaration DIE stack is a stack of the declaration context
+ // DIEs all the way back to the compile unit. If a type "T" is
+ // declared inside a class "B", and class "B" is declared inside
+ // a class "A" and class "A" is in a namespace "lldb", and the
+ // namespace is in a compile unit, there will be a stack of DIEs:
+ //
+ // [0] DW_TAG_class_type for "B"
+ // [1] DW_TAG_class_type for "A"
+ // [2] DW_TAG_namespace for "lldb"
+ // [3] DW_TAG_compile_unit for the source file.
+ //
+ // We grab both contexts and make sure that everything matches
+ // all the way back to the compiler unit.
+
+ // First lets grab the decl contexts for both DIEs
+ die1.GetDeclContextDIEs(decl_ctx_1);
+ die2.GetDeclContextDIEs(decl_ctx_2);
+ // Make sure the context arrays have the same size, otherwise
+ // we are done
+ const size_t count1 = decl_ctx_1.Size();
+ const size_t count2 = decl_ctx_2.Size();
+ if (count1 != count2)
+ return false;
+
+ // Make sure the DW_TAG values match all the way back up the
+ // compile unit. If they don't, then we are done.
+ DWARFDIE decl_ctx_die1;
+ DWARFDIE decl_ctx_die2;
+ size_t i;
+ for (i = 0; i < count1; i++) {
+ decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
+ decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
+ if (decl_ctx_die1.Tag() != decl_ctx_die2.Tag())
+ return false;
+ }
#if defined LLDB_CONFIGURATION_DEBUG
- // Make sure the top item in the decl context die array is always
- // DW_TAG_compile_unit. If it isn't then something went wrong in
- // the DWARFDIE::GetDeclContextDIEs() function...
- assert (decl_ctx_1.GetDIEAtIndex (count1 - 1).Tag() == DW_TAG_compile_unit);
+ // Make sure the top item in the decl context die array is always
+ // DW_TAG_compile_unit. If it isn't then something went wrong in
+ // the DWARFDIE::GetDeclContextDIEs() function...
+ assert(decl_ctx_1.GetDIEAtIndex(count1 - 1).Tag() == DW_TAG_compile_unit);
#endif
- // Always skip the compile unit when comparing by only iterating up to
- // "count - 1". Here we compare the names as we go.
- for (i=0; i<count1 - 1; i++)
- {
- decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex (i);
- decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex (i);
- const char *name1 = decl_ctx_die1.GetName();
- const char *name2 = decl_ctx_die2.GetName();
- // If the string was from a DW_FORM_strp, then the pointer will often
- // be the same!
- if (name1 == name2)
- continue;
-
- // Name pointers are not equal, so only compare the strings
- // if both are not NULL.
- if (name1 && name2)
- {
- // If the strings don't compare, we are done...
- if (strcmp(name1, name2) != 0)
- return false;
- }
- else
- {
- // One name was NULL while the other wasn't
- return false;
- }
- }
- // We made it through all of the checks and the declaration contexts
- // are equal.
- return true;
-}
-
-
-TypeSP
-SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
-{
- TypeSP type_sp;
-
- const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
- if (dwarf_decl_ctx_count > 0)
- {
- const ConstString type_name(dwarf_decl_ctx[0].name);
- const dw_tag_t tag = dwarf_decl_ctx[0].tag;
-
- if (type_name)
- {
- Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
+ // Always skip the compile unit when comparing by only iterating up to
+ // "count - 1". Here we compare the names as we go.
+ for (i = 0; i < count1 - 1; i++) {
+ decl_ctx_die1 = decl_ctx_1.GetDIEAtIndex(i);
+ decl_ctx_die2 = decl_ctx_2.GetDIEAtIndex(i);
+ const char *name1 = decl_ctx_die1.GetName();
+ const char *name2 = decl_ctx_die2.GetName();
+ // If the string was from a DW_FORM_strp, then the pointer will often
+ // be the same!
+ if (name1 == name2)
+ continue;
+
+ // Name pointers are not equal, so only compare the strings
+ // if both are not NULL.
+ if (name1 && name2) {
+ // If the strings don't compare, we are done...
+ if (strcmp(name1, name2) != 0)
+ return false;
+ } else {
+ // One name was NULL while the other wasn't
+ return false;
+ }
+ }
+ // We made it through all of the checks and the declaration contexts
+ // are equal.
+ return true;
+}
+
+TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
+ const DWARFDeclContext &dwarf_decl_ctx) {
+ TypeSP type_sp;
+
+ const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
+ if (dwarf_decl_ctx_count > 0) {
+ const ConstString type_name(dwarf_decl_ctx[0].name);
+ const dw_tag_t tag = dwarf_decl_ctx[0].tag;
+
+ if (type_name) {
+ Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
+ DWARF_LOG_LOOKUPS));
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%"
+ "s, qualified-name='%s')",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName());
+ }
+
+ DIEArray die_offsets;
+
+ if (m_using_apple_tables) {
+ if (m_apple_types_ap.get()) {
+ const bool has_tag =
+ m_apple_types_ap->GetHeader().header_data.ContainsAtom(
+ DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash =
+ m_apple_types_ap->GetHeader().header_data.ContainsAtom(
+ DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash) {
+ const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
+ const uint32_t qualified_name_hash =
+ MappedHash::HashStringUsingDJB(qualified_name);
if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName());
- }
-
- DIEArray die_offsets;
-
- if (m_using_apple_tables)
- {
- if (m_apple_types_ap.get())
- {
- const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
- const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
- if (has_tag && has_qualified_name_hash)
- {
- const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
- const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
- m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
- }
- else if (has_tag)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
- m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
- }
- else
- {
- m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
- }
- }
- }
- else
- {
- if (!m_indexed)
- Index ();
-
- m_type_index.Find (type_name, die_offsets);
- }
-
- const size_t num_matches = die_offsets.size();
-
- // Get the type system that we are looking to find a type for. We will use this
- // to ensure any matches we find are in a language that this type system supports
- const LanguageType language = dwarf_decl_ctx.GetLanguage();
- TypeSystem *type_system = (language == eLanguageTypeUnknown) ? nullptr : GetTypeSystemForLanguage(language);
-
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE type_die = GetDIE (die_ref);
-
- if (type_die)
- {
- // Make sure type_die's langauge matches the type system we are looking for.
- // We don't want to find a "Foo" type from Java if we are looking for a "Foo"
- // type for C, C++, ObjC, or ObjC++.
- if (type_system && !type_system->SupportsLanguage(type_die.GetLanguage()))
- continue;
- bool try_resolving_type = false;
-
- // Don't try and resolve the DIE we are looking for with the DIE itself!
- const dw_tag_t type_tag = type_die.Tag();
- // Make sure the tags match
- if (type_tag == tag)
- {
- // The tags match, lets try resolving this type
- try_resolving_type = true;
- }
- else
- {
- // The tags don't match, but we need to watch our for a
- // forward declaration for a struct and ("struct foo")
- // ends up being a class ("class foo { ... };") or
- // vice versa.
- switch (type_tag)
- {
- case DW_TAG_class_type:
- // We had a "class foo", see if we ended up with a "struct foo { ... };"
- try_resolving_type = (tag == DW_TAG_structure_type);
- break;
- case DW_TAG_structure_type:
- // We had a "struct foo", see if we ended up with a "class foo { ... };"
- try_resolving_type = (tag == DW_TAG_class_type);
- break;
- default:
- // Tags don't match, don't event try to resolve
- // using this type whose name matches....
- break;
- }
- }
-
- if (try_resolving_type)
- {
- DWARFDeclContext type_dwarf_decl_ctx;
- type_die.GetDWARFDeclContext (type_dwarf_decl_ctx);
-
- if (log)
- {
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName(),
- type_die.GetOffset(),
- type_dwarf_decl_ctx.GetQualifiedName());
- }
-
- // Make sure the decl contexts match all the way up
- if (dwarf_decl_ctx == type_dwarf_decl_ctx)
- {
- Type *resolved_type = ResolveType (type_die, false);
- if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
- {
- type_sp = resolved_type->shared_from_this();
- break;
- }
- }
- }
- else
- {
- if (log)
- {
- std::string qualified_name;
- type_die.GetQualifiedName(qualified_name);
- GetObjectFile()->GetModule()->LogMessage (log,
- "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
- DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
- dwarf_decl_ctx.GetQualifiedName(),
- type_die.GetOffset(),
- qualified_name.c_str());
- }
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
- die_ref.die_offset, type_name.GetCString());
- }
- }
-
- }
- }
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash(
+ type_name.GetCString(), tag, qualified_name_hash, die_offsets);
+ } else if (has_tag) {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage(log,
+ "FindByNameAndTag()");
+ m_apple_types_ap->FindByNameAndTag(type_name.GetCString(), tag,
+ die_offsets);
+ } else {
+ m_apple_types_ap->FindByName(type_name.GetCString(), die_offsets);
+ }
}
- }
- return type_sp;
-}
+ } else {
+ if (!m_indexed)
+ Index();
-TypeSP
-SymbolFileDWARF::ParseType (const SymbolContext& sc, const DWARFDIE &die, bool *type_is_new_ptr)
-{
- TypeSP type_sp;
+ m_type_index.Find(type_name, die_offsets);
+ }
- if (die)
- {
- TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
-
- if (type_system)
- {
- DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
- if (dwarf_ast)
- {
- Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
- type_sp = dwarf_ast->ParseTypeFromDWARF (sc, die, log, type_is_new_ptr);
- if (type_sp)
- {
- TypeList* type_list = GetTypeList();
- if (type_list)
- type_list->Insert(type_sp);
-
- if (die.Tag() == DW_TAG_subprogram)
- {
- DIERef die_ref = die.GetDIERef();
- std::string scope_qualified_name(GetDeclContextForUID(die.GetID()).GetScopeQualifiedName().AsCString(""));
- if (scope_qualified_name.size())
- {
- NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name);
- if (iter != m_function_scope_qualified_name_map.end())
- (*iter).second->insert(die_ref);
- else
- {
- DIERefSetSP new_set(new std::set<DIERef>);
- new_set->insert(die_ref);
- m_function_scope_qualified_name_map.emplace(std::make_pair(scope_qualified_name, new_set));
- }
- }
- }
- }
- }
- }
- }
-
- return type_sp;
-}
+ const size_t num_matches = die_offsets.size();
-size_t
-SymbolFileDWARF::ParseTypes
-(
- const SymbolContext& sc,
- const DWARFDIE &orig_die,
- bool parse_siblings,
- bool parse_children
-)
-{
- size_t types_added = 0;
- DWARFDIE die = orig_die;
- while (die)
- {
- bool type_is_new = false;
- if (ParseType(sc, die, &type_is_new).get())
- {
- if (type_is_new)
- ++types_added;
- }
-
- if (parse_children && die.HasChildren())
- {
- if (die.Tag() == DW_TAG_subprogram)
- {
- SymbolContext child_sc(sc);
- child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
- types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
+ // Get the type system that we are looking to find a type for. We will use
+ // this
+ // to ensure any matches we find are in a language that this type system
+ // supports
+ const LanguageType language = dwarf_decl_ctx.GetLanguage();
+ TypeSystem *type_system = (language == eLanguageTypeUnknown)
+ ? nullptr
+ : GetTypeSystemForLanguage(language);
+
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE type_die = GetDIE(die_ref);
+
+ if (type_die) {
+ // Make sure type_die's langauge matches the type system we are
+ // looking for.
+ // We don't want to find a "Foo" type from Java if we are looking
+ // for a "Foo"
+ // type for C, C++, ObjC, or ObjC++.
+ if (type_system &&
+ !type_system->SupportsLanguage(type_die.GetLanguage()))
+ continue;
+ bool try_resolving_type = false;
+
+ // Don't try and resolve the DIE we are looking for with the DIE
+ // itself!
+ const dw_tag_t type_tag = type_die.Tag();
+ // Make sure the tags match
+ if (type_tag == tag) {
+ // The tags match, lets try resolving this type
+ try_resolving_type = true;
+ } else {
+ // The tags don't match, but we need to watch our for a
+ // forward declaration for a struct and ("struct foo")
+ // ends up being a class ("class foo { ... };") or
+ // vice versa.
+ switch (type_tag) {
+ case DW_TAG_class_type:
+ // We had a "class foo", see if we ended up with a "struct foo {
+ // ... };"
+ try_resolving_type = (tag == DW_TAG_structure_type);
+ break;
+ case DW_TAG_structure_type:
+ // We had a "struct foo", see if we ended up with a "class foo {
+ // ... };"
+ try_resolving_type = (tag == DW_TAG_class_type);
+ break;
+ default:
+ // Tags don't match, don't event try to resolve
+ // using this type whose name matches....
+ break;
+ }
}
- else
- types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
- }
- if (parse_siblings)
- die = die.GetSibling();
- else
- die.Clear();
+ if (try_resolving_type) {
+ DWARFDeclContext type_dwarf_decl_ctx;
+ type_die.GetDWARFDeclContext(type_dwarf_decl_ctx);
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') trying die=0x%8.8x (%s)",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
+ type_dwarf_decl_ctx.GetQualifiedName());
+ }
+
+ // Make sure the decl contexts match all the way up
+ if (dwarf_decl_ctx == type_dwarf_decl_ctx) {
+ Type *resolved_type = ResolveType(type_die, false);
+ if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) {
+ type_sp = resolved_type->shared_from_this();
+ break;
+ }
+ }
+ } else {
+ if (log) {
+ std::string qualified_name;
+ type_die.GetQualifiedName(qualified_name);
+ GetObjectFile()->GetModule()->LogMessage(
+ log, "SymbolFileDWARF::"
+ "FindDefinitionTypeForDWARFDeclContext(tag=%s, "
+ "qualified-name='%s') ignoring die=0x%8.8x (%s)",
+ DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+ dwarf_decl_ctx.GetQualifiedName(), type_die.GetOffset(),
+ qualified_name.c_str());
+ }
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified (.apple_types "
+ "accelerator table had bad die 0x%8.8x for '%s')\n",
+ die_ref.die_offset, type_name.GetCString());
+ }
+ }
+ }
+ }
+ }
+ }
+ return type_sp;
+}
+
+TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
+ bool *type_is_new_ptr) {
+ TypeSP type_sp;
+
+ if (die) {
+ TypeSystem *type_system =
+ GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
+
+ if (type_system) {
+ DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
+ if (dwarf_ast) {
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+ type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+ if (type_sp) {
+ TypeList *type_list = GetTypeList();
+ if (type_list)
+ type_list->Insert(type_sp);
+
+ if (die.Tag() == DW_TAG_subprogram) {
+ DIERef die_ref = die.GetDIERef();
+ std::string scope_qualified_name(GetDeclContextForUID(die.GetID())
+ .GetScopeQualifiedName()
+ .AsCString(""));
+ if (scope_qualified_name.size()) {
+ NameToOffsetMap::iterator iter =
+ m_function_scope_qualified_name_map.find(
+ scope_qualified_name);
+ if (iter != m_function_scope_qualified_name_map.end())
+ (*iter).second->insert(die_ref);
+ else {
+ DIERefSetSP new_set(new std::set<DIERef>);
+ new_set->insert(die_ref);
+ m_function_scope_qualified_name_map.emplace(
+ std::make_pair(scope_qualified_name, new_set));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return type_sp;
+}
+
+size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
+ const DWARFDIE &orig_die,
+ bool parse_siblings, bool parse_children) {
+ size_t types_added = 0;
+ DWARFDIE die = orig_die;
+ while (die) {
+ bool type_is_new = false;
+ if (ParseType(sc, die, &type_is_new).get()) {
+ if (type_is_new)
+ ++types_added;
+ }
+
+ if (parse_children && die.HasChildren()) {
+ if (die.Tag() == DW_TAG_subprogram) {
+ SymbolContext child_sc(sc);
+ child_sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
+ types_added += ParseTypes(child_sc, die.GetFirstChild(), true, true);
+ } else
+ types_added += ParseTypes(sc, die.GetFirstChild(), true, true);
}
- return types_added;
-}
+ if (parse_siblings)
+ die = die.GetSibling();
+ else
+ die.Clear();
+ }
+ return types_added;
+}
+
+size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) {
+ assert(sc.comp_unit && sc.function);
+ size_t functions_added = 0;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ const dw_offset_t function_die_offset = sc.function->GetID();
+ DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset);
+ if (function_die) {
+ ParseFunctionBlocks(sc, &sc.function->GetBlock(false), function_die,
+ LLDB_INVALID_ADDRESS, 0);
+ }
+ }
+
+ return functions_added;
+}
+
+size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) {
+ // At least a compile unit must be valid
+ assert(sc.comp_unit);
+ size_t types_added = 0;
+ DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ if (dwarf_cu) {
+ if (sc.function) {
+ dw_offset_t function_die_offset = sc.function->GetID();
+ DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
+ if (func_die && func_die.HasChildren()) {
+ types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
+ }
+ } else {
+ DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
+ if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {
+ types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
+ }
+ }
+ }
+
+ return types_added;
+}
+
+size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
+ if (sc.comp_unit != NULL) {
+ DWARFDebugInfo *info = DebugInfo();
+ if (info == NULL)
+ return 0;
-size_t
-SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
-{
- assert(sc.comp_unit && sc.function);
- size_t functions_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- const dw_offset_t function_die_offset = sc.function->GetID();
- DWARFDIE function_die = dwarf_cu->GetDIE (function_die_offset);
- if (function_die)
- {
- ParseFunctionBlocks(sc, &sc.function->GetBlock (false), function_die, LLDB_INVALID_ADDRESS, 0);
- }
- }
+ if (sc.function) {
+ DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
- return functions_added;
-}
+ const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress(
+ DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (func_lo_pc != LLDB_INVALID_ADDRESS) {
+ const size_t num_variables = ParseVariables(
+ sc, function_die.GetFirstChild(), func_lo_pc, true, true);
+
+ // Let all blocks know they have parse all their variables
+ sc.function->GetBlock(false).SetDidParseVariables(true, true);
+ return num_variables;
+ }
+ } else if (sc.comp_unit) {
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
+ if (dwarf_cu == NULL)
+ return 0;
-size_t
-SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
-{
- // At least a compile unit must be valid
- assert(sc.comp_unit);
- size_t types_added = 0;
- DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu)
- {
- if (sc.function)
- {
- dw_offset_t function_die_offset = sc.function->GetID();
- DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
- if (func_die && func_die.HasChildren())
- {
- types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
- }
- }
- else
- {
- DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
- if (dwarf_cu_die && dwarf_cu_die.HasChildren())
- {
- types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
- }
- }
- }
+ uint32_t vars_added = 0;
+ VariableListSP variables(sc.comp_unit->GetVariableList(false));
- return types_added;
-}
+ if (variables.get() == NULL) {
+ variables.reset(new VariableList());
+ sc.comp_unit->SetVariableList(variables);
-size_t
-SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
-{
- if (sc.comp_unit != NULL)
- {
- DWARFDebugInfo* info = DebugInfo();
- if (info == NULL)
- return 0;
-
- if (sc.function)
- {
- DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID(), this));
-
- const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
- if (func_lo_pc != LLDB_INVALID_ADDRESS)
- {
- const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
-
- // Let all blocks know they have parse all their variables
- sc.function->GetBlock (false).SetDidParseVariables (true, true);
- return num_variables;
- }
+ DIEArray die_offsets;
+ if (m_using_apple_tables) {
+ if (m_apple_names_ap.get()) {
+ DWARFMappedHash::DIEInfoArray hash_data_array;
+ if (m_apple_names_ap->AppendAllDIEsInRange(
+ dwarf_cu->GetOffset(), dwarf_cu->GetNextCompileUnitOffset(),
+ hash_data_array)) {
+ DWARFMappedHash::ExtractDIEArray(hash_data_array, die_offsets);
+ }
+ }
+ } else {
+ // Index if we already haven't to make sure the compile units
+ // get indexed and make their global DIE index list
+ if (!m_indexed)
+ Index();
+
+ m_global_index.FindAllEntriesForCompileUnit(dwarf_cu->GetOffset(),
+ die_offsets);
}
- else if (sc.comp_unit)
- {
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID());
-
- if (dwarf_cu == NULL)
- return 0;
-
- uint32_t vars_added = 0;
- VariableListSP variables (sc.comp_unit->GetVariableList(false));
-
- if (variables.get() == NULL)
- {
- variables.reset(new VariableList());
- sc.comp_unit->SetVariableList(variables);
-
- DIEArray die_offsets;
- if (m_using_apple_tables)
- {
- if (m_apple_names_ap.get())
- {
- DWARFMappedHash::DIEInfoArray hash_data_array;
- if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
- dwarf_cu->GetNextCompileUnitOffset(),
- hash_data_array))
- {
- DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
- }
- }
- }
- else
- {
- // Index if we already haven't to make sure the compile units
- // get indexed and make their global DIE index list
- if (!m_indexed)
- Index ();
- m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
- die_offsets);
- }
+ const size_t num_matches = die_offsets.size();
+ if (num_matches) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ const DIERef &die_ref = die_offsets[i];
+ DWARFDIE die = GetDIE(die_ref);
+ if (die) {
+ VariableSP var_sp(
+ ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
+ if (var_sp) {
+ variables->AddVariableIfUnique(var_sp);
+ ++vars_added;
+ }
+ } else {
+ if (m_using_apple_tables) {
+ GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
+ "the DWARF debug information has been modified "
+ "(.apple_names accelerator table had bad die 0x%8.8x)\n",
+ die_ref.die_offset);
+ }
+ }
+ }
+ }
+ }
+ return vars_added;
+ }
+ }
+ return 0;
+}
+
+VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
+ const DWARFDIE &die,
+ const lldb::addr_t func_low_pc) {
+ if (die.GetDWARF() != this)
+ return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
- const size_t num_matches = die_offsets.size();
- if (num_matches)
- {
- for (size_t i=0; i<num_matches; ++i)
- {
- const DIERef& die_ref = die_offsets[i];
- DWARFDIE die = GetDIE (die_ref);
- if (die)
- {
- VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
- if (var_sp)
- {
- variables->AddVariableIfUnique (var_sp);
- ++vars_added;
- }
- }
- else
- {
- if (m_using_apple_tables)
- {
- GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset);
- }
- }
+ VariableSP var_sp;
+ if (!die)
+ return var_sp;
- }
+ var_sp = GetDIEToVariable()[die.GetDIE()];
+ if (var_sp)
+ return var_sp; // Already been parsed!
+
+ const dw_tag_t tag = die.Tag();
+ ModuleSP module = GetObjectFile()->GetModule();
+
+ if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
+ (tag == DW_TAG_formal_parameter && sc.function)) {
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ DWARFDIE spec_die;
+ if (num_attributes > 0) {
+ const char *name = NULL;
+ const char *mangled = NULL;
+ Declaration decl;
+ uint32_t i;
+ DWARFFormValue type_die_form;
+ DWARFExpression location(die.GetCU());
+ bool is_external = false;
+ bool is_artificial = false;
+ bool location_is_const_value_data = false;
+ bool has_explicit_location = false;
+ DWARFFormValue const_value;
+ Variable::RangeList scope_ranges;
+ // AccessType accessibility = eAccessNone;
+
+ for (i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ mangled = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_external:
+ is_external = form_value.Boolean();
+ break;
+ case DW_AT_const_value:
+ // If we have already found a DW_AT_location attribute, ignore this
+ // attribute.
+ if (!has_explicit_location) {
+ location_is_const_value_data = true;
+ // The constant value will be either a block, a data value or a
+ // string.
+ const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+ if (DWARFFormValue::IsBlockForm(form_value.Form())) {
+ // Retrieve the value as a block expression.
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ location.CopyOpcodeData(module, debug_info_data, block_offset,
+ block_length);
+ } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
+ // Retrieve the value as a data expression.
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(
+ attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
+ attributes.CompileUnitAtIndex(i)->IsDWARF64());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length =
+ fixed_form_sizes.GetSize(form_value.Form());
+ if (data_length == 0) {
+ const uint8_t *data_pointer = form_value.BlockData();
+ if (data_pointer) {
+ form_value.Unsigned();
+ } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
+ // we need to get the byte size of the type later after we
+ // create the variable
+ const_value = form_value;
+ }
+ } else
+ location.CopyOpcodeData(module, debug_info_data, data_offset,
+ data_length);
+ } else {
+ // Retrieve the value as a string expression.
+ if (form_value.Form() == DW_FORM_strp) {
+ DWARFFormValue::FixedFormSizes fixed_form_sizes =
+ DWARFFormValue::GetFixedFormSizesForAddressSize(
+ attributes.CompileUnitAtIndex(i)
+ ->GetAddressByteSize(),
+ attributes.CompileUnitAtIndex(i)->IsDWARF64());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length =
+ fixed_form_sizes.GetSize(form_value.Form());
+ location.CopyOpcodeData(module, debug_info_data, data_offset,
+ data_length);
+ } else {
+ const char *str = form_value.AsCString();
+ uint32_t string_offset =
+ str - (const char *)debug_info_data.GetDataStart();
+ uint32_t string_length = strlen(str) + 1;
+ location.CopyOpcodeData(module, debug_info_data,
+ string_offset, string_length);
}
+ }
}
- return vars_added;
+ break;
+ case DW_AT_location: {
+ location_is_const_value_data = false;
+ has_explicit_location = true;
+ if (DWARFFormValue::IsBlockForm(form_value.Form())) {
+ const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ location.CopyOpcodeData(module, get_debug_info_data(),
+ block_offset, block_length);
+ } else {
+ const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
+ const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+ size_t loc_list_length = DWARFExpression::LocationListSize(
+ die.GetCU(), debug_loc_data, debug_loc_offset);
+ if (loc_list_length > 0) {
+ location.CopyOpcodeData(module, debug_loc_data,
+ debug_loc_offset, loc_list_length);
+ assert(func_low_pc != LLDB_INVALID_ADDRESS);
+ location.SetLocationListSlide(
+ func_low_pc -
+ attributes.CompileUnitAtIndex(i)->GetBaseAddress());
+ }
+ }
+ } break;
+ case DW_AT_specification:
+ spec_die = GetDIE(DIERef(form_value));
+ break;
+ case DW_AT_start_scope: {
+ if (form_value.Form() == DW_FORM_sec_offset) {
+ DWARFRangeList dwarf_scope_ranges;
+ const DWARFDebugRanges *debug_ranges = DebugRanges();
+ debug_ranges->FindRanges(form_value.Unsigned(),
+ dwarf_scope_ranges);
+
+ // All DW_AT_start_scope are relative to the base address of the
+ // compile unit. We add the compile unit base address to make
+ // sure all the addresses are properly fixed up.
+ for (size_t i = 0, count = dwarf_scope_ranges.GetSize();
+ i < count; ++i) {
+ const DWARFRangeList::Entry &range =
+ dwarf_scope_ranges.GetEntryRef(i);
+ scope_ranges.Append(range.GetRangeBase() +
+ die.GetCU()->GetBaseAddress(),
+ range.GetByteSize());
+ }
+ } else {
+ // TODO: Handle the case when DW_AT_start_scope have form
+ // constant. The
+ // dwarf spec is a bit ambiguous about what is the expected
+ // behavior in
+ // case the enclosing block have a non coninious address range and
+ // the
+ // DW_AT_start_scope entry have a form constant.
+ GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64
+ ": DW_AT_start_scope has unsupported form type (0x%x)\n",
+ die.GetID(), form_value.Form());
+ }
+
+ scope_ranges.Sort();
+ scope_ranges.CombineConsecutiveRanges();
+ } break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+ case DW_AT_accessibility:
+ break; // accessibility =
+ // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_endianity:
+ case DW_AT_segment:
+ case DW_AT_visibility:
+ default:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
}
- }
- return 0;
-}
-
-VariableSP
-SymbolFileDWARF::ParseVariableDIE
-(
- const SymbolContext& sc,
- const DWARFDIE &die,
- const lldb::addr_t func_low_pc
-)
-{
- if (die.GetDWARF() != this)
- return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
-
- VariableSP var_sp;
- if (!die)
- return var_sp;
+ }
- var_sp = GetDIEToVariable()[die.GetDIE()];
- if (var_sp)
- return var_sp; // Already been parsed!
-
- const dw_tag_t tag = die.Tag();
- ModuleSP module = GetObjectFile()->GetModule();
-
- if ((tag == DW_TAG_variable) ||
- (tag == DW_TAG_constant) ||
- (tag == DW_TAG_formal_parameter && sc.function))
- {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- DWARFDIE spec_die;
- if (num_attributes > 0)
- {
- const char *name = NULL;
- const char *mangled = NULL;
- Declaration decl;
- uint32_t i;
- DWARFFormValue type_die_form;
- DWARFExpression location(die.GetCU());
- bool is_external = false;
- bool is_artificial = false;
- bool location_is_const_value_data = false;
- bool has_explicit_location = false;
- DWARFFormValue const_value;
- Variable::RangeList scope_ranges;
- //AccessType accessibility = eAccessNone;
-
- for (i=0; i<num_attributes; ++i)
- {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
-
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- switch (attr)
- {
- case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
- case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
- case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
- case DW_AT_name: name = form_value.AsCString(); break;
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
- case DW_AT_type: type_die_form = form_value; break;
- case DW_AT_external: is_external = form_value.Boolean(); break;
- case DW_AT_const_value:
- // If we have already found a DW_AT_location attribute, ignore this attribute.
- if (!has_explicit_location)
- {
- location_is_const_value_data = true;
- // The constant value will be either a block, a data value or a string.
- const DWARFDataExtractor& debug_info_data = get_debug_info_data();
- if (DWARFFormValue::IsBlockForm(form_value.Form()))
- {
- // Retrieve the value as a block expression.
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
- }
- else if (DWARFFormValue::IsDataForm(form_value.Form()))
- {
- // Retrieve the value as a data expression.
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (
- attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
- attributes.CompileUnitAtIndex(i)->IsDWARF64());
- uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
- if (data_length == 0)
- {
- const uint8_t *data_pointer = form_value.BlockData();
- if (data_pointer)
- {
- form_value.Unsigned();
- }
- else if (DWARFFormValue::IsDataForm(form_value.Form()))
- {
- // we need to get the byte size of the type later after we create the variable
- const_value = form_value;
- }
- }
- else
- location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
- }
- else
- {
- // Retrieve the value as a string expression.
- if (form_value.Form() == DW_FORM_strp)
- {
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize (
- attributes.CompileUnitAtIndex(i)->GetAddressByteSize(),
- attributes.CompileUnitAtIndex(i)->IsDWARF64());
- uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form());
- location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
- }
- else
- {
- const char *str = form_value.AsCString();
- uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
- uint32_t string_length = strlen(str) + 1;
- location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
- }
- }
+ const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
+ const dw_tag_t parent_tag = die.GetParent().Tag();
+ bool is_static_member =
+ parent_tag == DW_TAG_compile_unit &&
+ (parent_context_die.Tag() == DW_TAG_class_type ||
+ parent_context_die.Tag() == DW_TAG_structure_type);
+
+ ValueType scope = eValueTypeInvalid;
+
+ const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
+ SymbolContextScope *symbol_context_scope = NULL;
+
+ if (!mangled) {
+ // LLDB relies on the mangled name (DW_TAG_linkage_name or
+ // DW_AT_MIPS_linkage_name) to
+ // generate fully qualified names of global variables with commands like
+ // "frame var j".
+ // For example, if j were an int variable holding a value 4 and declared
+ // in a namespace
+ // B which in turn is contained in a namespace A, the command "frame var
+ // j" returns
+ // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we
+ // should be able
+ // to generate a fully qualified name from the declaration context.
+ if (parent_tag == DW_TAG_compile_unit &&
+ Language::LanguageIsCPlusPlus(die.GetLanguage())) {
+ DWARFDeclContext decl_ctx;
+
+ die.GetDWARFDeclContext(decl_ctx);
+ mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
+ }
+ }
+
+ // DWARF doesn't specify if a DW_TAG_variable is a local, global
+ // or static variable, so we have to do a little digging by
+ // looking at the location of a variable to see if it contains
+ // a DW_OP_addr opcode _somewhere_ in the definition. I say
+ // somewhere because clang likes to combine small global variables
+ // into the same symbol and have locations like:
+ // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
+ // So if we don't have a DW_TAG_formal_parameter, we can look at
+ // the location to see if it contains a DW_OP_addr opcode, and
+ // then we can correctly classify our variables.
+ if (tag == DW_TAG_formal_parameter)
+ scope = eValueTypeVariableArgument;
+ else {
+ bool op_error = false;
+ // Check if the location has a DW_OP_addr with any address value...
+ lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
+ if (!location_is_const_value_data) {
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
+ if (op_error) {
+ StreamString strm;
+ location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
+ NULL);
+ GetObjectFile()->GetModule()->ReportError(
+ "0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
+ die.GetTagAsCString(), strm.GetString().c_str());
+ }
+ }
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+
+ if (location_DW_OP_addr != LLDB_INVALID_ADDRESS) {
+ if (is_external)
+ scope = eValueTypeVariableGlobal;
+ else
+ scope = eValueTypeVariableStatic;
+
+ if (debug_map_symfile) {
+ // When leaving the DWARF in the .o files on darwin,
+ // when we have a global variable that wasn't initialized,
+ // the .o file might not have allocated a virtual
+ // address for the global variable. In this case it will
+ // have created a symbol for the global variable
+ // that is undefined/data and external and the value will
+ // be the byte size of the variable. When we do the
+ // address map in SymbolFileDWARFDebugMap we rely on
+ // having an address, we need to do some magic here
+ // so we can get the correct address for our global
+ // variable. The address for all of these entries
+ // will be zero, and there will be an undefined symbol
+ // in this object file, and the executable will have
+ // a matching symbol with a good address. So here we
+ // dig up the correct address and replace it in the
+ // location for the variable, and set the variable's
+ // symbol context scope to be that of the main executable
+ // so the file address will resolve correctly.
+ bool linked_oso_file_addr = false;
+ if (is_external && location_DW_OP_addr == 0) {
+ // we have a possible uninitialized extern global
+ ConstString const_name(mangled ? mangled : name);
+ ObjectFile *debug_map_objfile =
+ debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile) {
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ if (debug_map_symtab) {
+ Symbol *exe_symbol =
+ debug_map_symtab->FindFirstSymbolWithNameAndType(
+ const_name, eSymbolTypeData, Symtab::eDebugYes,
+ Symtab::eVisibilityExtern);
+ if (exe_symbol) {
+ if (exe_symbol->ValueIsAddress()) {
+ const addr_t exe_file_addr =
+ exe_symbol->GetAddressRef().GetFileAddress();
+ if (exe_file_addr != LLDB_INVALID_ADDRESS) {
+ if (location.Update_DW_OP_addr(exe_file_addr)) {
+ linked_oso_file_addr = true;
+ symbol_context_scope = exe_symbol;
}
- break;
- case DW_AT_location:
- {
- location_is_const_value_data = false;
- has_explicit_location = true;
- if (DWARFFormValue::IsBlockForm(form_value.Form()))
- {
- const DWARFDataExtractor& debug_info_data = get_debug_info_data();
-
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
- }
- else
- {
- const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
- const dw_offset_t debug_loc_offset = form_value.Unsigned();
-
- size_t loc_list_length = DWARFExpression::LocationListSize(die.GetCU(), debug_loc_data, debug_loc_offset);
- if (loc_list_length > 0)
- {
- location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
- assert (func_low_pc != LLDB_INVALID_ADDRESS);
- location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
- }
- }
- }
- break;
- case DW_AT_specification:
- spec_die = GetDIE(DIERef(form_value));
- break;
- case DW_AT_start_scope:
- {
- if (form_value.Form() == DW_FORM_sec_offset)
- {
- DWARFRangeList dwarf_scope_ranges;
- const DWARFDebugRanges* debug_ranges = DebugRanges();
- debug_ranges->FindRanges(form_value.Unsigned(), dwarf_scope_ranges);
-
- // All DW_AT_start_scope are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
- for (size_t i = 0, count = dwarf_scope_ranges.GetSize(); i < count; ++i)
- {
- const DWARFRangeList::Entry& range = dwarf_scope_ranges.GetEntryRef(i);
- scope_ranges.Append(range.GetRangeBase() + die.GetCU()->GetBaseAddress(),
- range.GetByteSize());
- }
- }
- else
- {
- // TODO: Handle the case when DW_AT_start_scope have form constant. The
- // dwarf spec is a bit ambiguous about what is the expected behavior in
- // case the enclosing block have a non coninious address range and the
- // DW_AT_start_scope entry have a form constant.
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_start_scope has unsupported form type (0x%x)\n",
- die.GetID(),
- form_value.Form());
- }
-
- scope_ranges.Sort();
- scope_ranges.CombineConsecutiveRanges();
- }
- break;
- case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
- case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_endianity:
- case DW_AT_segment:
- case DW_AT_visibility:
- default:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
+ }
}
+ }
}
+ }
}
- const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
- const dw_tag_t parent_tag = die.GetParent().Tag();
- bool is_static_member = parent_tag == DW_TAG_compile_unit && (parent_context_die.Tag() == DW_TAG_class_type || parent_context_die.Tag() == DW_TAG_structure_type);
-
- ValueType scope = eValueTypeInvalid;
-
- const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
- SymbolContextScope * symbol_context_scope = NULL;
-
- if (!mangled)
- {
- // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
- // generate fully qualified names of global variables with commands like "frame var j".
- // For example, if j were an int variable holding a value 4 and declared in a namespace
- // B which in turn is contained in a namespace A, the command "frame var j" returns
- // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
- // to generate a fully qualified name from the declaration context.
- if (parent_tag == DW_TAG_compile_unit &&
- Language::LanguageIsCPlusPlus(die.GetLanguage()))
- {
- DWARFDeclContext decl_ctx;
-
- die.GetDWARFDeclContext(decl_ctx);
- mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
- }
+ if (!linked_oso_file_addr) {
+ // The DW_OP_addr is not zero, but it contains a .o file address
+ // which
+ // needs to be linked up correctly.
+ const lldb::addr_t exe_file_addr =
+ debug_map_symfile->LinkOSOFileAddress(this,
+ location_DW_OP_addr);
+ if (exe_file_addr != LLDB_INVALID_ADDRESS) {
+ // Update the file address for this variable
+ location.Update_DW_OP_addr(exe_file_addr);
+ } else {
+ // Variable didn't make it into the final executable
+ return var_sp;
+ }
}
-
- // DWARF doesn't specify if a DW_TAG_variable is a local, global
- // or static variable, so we have to do a little digging by
- // looking at the location of a variable to see if it contains
- // a DW_OP_addr opcode _somewhere_ in the definition. I say
- // somewhere because clang likes to combine small global variables
- // into the same symbol and have locations like:
- // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
- // So if we don't have a DW_TAG_formal_parameter, we can look at
- // the location to see if it contains a DW_OP_addr opcode, and
- // then we can correctly classify our variables.
- if (tag == DW_TAG_formal_parameter)
- scope = eValueTypeVariableArgument;
- else
- {
- bool op_error = false;
- // Check if the location has a DW_OP_addr with any address value...
- lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
- if (!location_is_const_value_data)
- {
- location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
- if (op_error)
- {
- StreamString strm;
- location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
- GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die.GetOffset(), die.GetTagAsCString(), strm.GetString().c_str());
- }
- }
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
-
- if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
- {
- if (is_external)
- scope = eValueTypeVariableGlobal;
- else
- scope = eValueTypeVariableStatic;
-
- if (debug_map_symfile)
- {
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined/data and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
- bool linked_oso_file_addr = false;
- if (is_external && location_DW_OP_addr == 0)
- {
- // we have a possible uninitialized extern global
- ConstString const_name(mangled ? mangled : name);
- ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
- if (debug_map_objfile)
- {
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- if (debug_map_symtab)
- {
- Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeData,
- Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (exe_symbol)
- {
- if (exe_symbol->ValueIsAddress())
- {
- const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
- if (exe_file_addr != LLDB_INVALID_ADDRESS)
- {
- if (location.Update_DW_OP_addr (exe_file_addr))
- {
- linked_oso_file_addr = true;
- symbol_context_scope = exe_symbol;
- }
- }
- }
- }
- }
- }
- }
-
- if (!linked_oso_file_addr)
- {
- // The DW_OP_addr is not zero, but it contains a .o file address which
- // needs to be linked up correctly.
- const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
- if (exe_file_addr != LLDB_INVALID_ADDRESS)
- {
- // Update the file address for this variable
- location.Update_DW_OP_addr (exe_file_addr);
- }
- else
- {
- // Variable didn't make it into the final executable
- return var_sp;
- }
- }
- }
- }
- else
- {
- if (location_is_const_value_data)
- scope = eValueTypeVariableStatic;
- else
- {
- scope = eValueTypeVariableLocal;
- if (debug_map_symfile)
- {
- // We need to check for TLS addresses that we need to fixup
- if (location.ContainsThreadLocalStorage())
- {
- location.LinkThreadLocalStorage(
- debug_map_symfile->GetObjectFile()->GetModule(),
- [this, debug_map_symfile](lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
- return debug_map_symfile->LinkOSOFileAddress(this, unlinked_file_addr);
- });
- scope = eValueTypeVariableThreadLocal;
- }
- }
- }
- }
+ }
+ } else {
+ if (location_is_const_value_data)
+ scope = eValueTypeVariableStatic;
+ else {
+ scope = eValueTypeVariableLocal;
+ if (debug_map_symfile) {
+ // We need to check for TLS addresses that we need to fixup
+ if (location.ContainsThreadLocalStorage()) {
+ location.LinkThreadLocalStorage(
+ debug_map_symfile->GetObjectFile()->GetModule(),
+ [this, debug_map_symfile](
+ lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
+ return debug_map_symfile->LinkOSOFileAddress(
+ this, unlinked_file_addr);
+ });
+ scope = eValueTypeVariableThreadLocal;
+ }
}
+ }
+ }
+ }
+ if (symbol_context_scope == NULL) {
+ switch (parent_tag) {
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ if (sc.function) {
+ symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(
+ sc_parent_die.GetID());
if (symbol_context_scope == NULL)
- {
- switch (parent_tag)
- {
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- if (sc.function)
- {
- symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- }
- break;
-
- default:
- symbol_context_scope = sc.comp_unit;
- break;
- }
- }
+ symbol_context_scope = sc.function;
+ }
+ break;
- if (symbol_context_scope)
- {
- SymbolFileTypeSP type_sp(new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
-
- if (const_value.Form() && type_sp && type_sp->GetType())
- location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
-
- var_sp.reset (new Variable (die.GetID(),
- name,
- mangled,
- type_sp,
- scope,
- symbol_context_scope,
- scope_ranges,
- &decl,
- location,
- is_external,
- is_artificial,
- is_static_member));
-
- var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
- }
- else
- {
- // Not ready to parse this variable yet. It might be a global
- // or static variable that is in a function scope and the function
- // in the symbol context wasn't filled in yet
- return var_sp;
- }
+ default:
+ symbol_context_scope = sc.comp_unit;
+ break;
}
- // Cache var_sp even if NULL (the variable was just a specification or
- // was missing vital information to be able to be displayed in the debugger
- // (missing location due to optimization, etc)) so we don't re-parse
- // this DIE over and over later...
- GetDIEToVariable()[die.GetDIE()] = var_sp;
- if (spec_die)
- GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+ }
+
+ if (symbol_context_scope) {
+ SymbolFileTypeSP type_sp(
+ new SymbolFileType(*this, DIERef(type_die_form).GetUID(this)));
+
+ if (const_value.Form() && type_sp && type_sp->GetType())
+ location.CopyOpcodeData(const_value.Unsigned(),
+ type_sp->GetType()->GetByteSize(),
+ die.GetCU()->GetAddressByteSize());
+
+ var_sp.reset(new Variable(die.GetID(), name, mangled, type_sp, scope,
+ symbol_context_scope, scope_ranges, &decl,
+ location, is_external, is_artificial,
+ is_static_member));
+
+ var_sp->SetLocationIsConstantValueData(location_is_const_value_data);
+ } else {
+ // Not ready to parse this variable yet. It might be a global
+ // or static variable that is in a function scope and the function
+ // in the symbol context wasn't filled in yet
+ return var_sp;
+ }
}
- return var_sp;
+ // Cache var_sp even if NULL (the variable was just a specification or
+ // was missing vital information to be able to be displayed in the debugger
+ // (missing location due to optimization, etc)) so we don't re-parse
+ // this DIE over and over later...
+ GetDIEToVariable()[die.GetDIE()] = var_sp;
+ if (spec_die)
+ GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+ }
+ return var_sp;
}
+DWARFDIE
+SymbolFileDWARF::FindBlockContainingSpecification(
+ const DIERef &func_die_ref, dw_offset_t spec_block_die_offset) {
+ // Give the concrete function die specified by "func_die_offset", find the
+ // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
+ // to "spec_block_die_offset"
+ return FindBlockContainingSpecification(DebugInfo()->GetDIE(func_die_ref),
+ spec_block_die_offset);
+}
DWARFDIE
-SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
- dw_offset_t spec_block_die_offset)
-{
- // Give the concrete function die specified by "func_die_offset", find the
+SymbolFileDWARF::FindBlockContainingSpecification(
+ const DWARFDIE &die, dw_offset_t spec_block_die_offset) {
+ if (die) {
+ switch (die.Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block: {
+ if (die.GetAttributeValueAsReference(
+ DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
+ return die;
+
+ if (die.GetAttributeValueAsReference(DW_AT_abstract_origin,
+ DW_INVALID_OFFSET) ==
+ spec_block_die_offset)
+ return die;
+ } break;
+ }
+
+ // Give the concrete function die specified by "func_die_offset", find the
// concrete block whose DW_AT_specification or DW_AT_abstract_origin points
// to "spec_block_die_offset"
- return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
-}
+ for (DWARFDIE child_die = die.GetFirstChild(); child_die;
+ child_die = child_die.GetSibling()) {
+ DWARFDIE result_die =
+ FindBlockContainingSpecification(child_die, spec_block_die_offset);
+ if (result_die)
+ return result_die;
+ }
+ }
+
+ return DWARFDIE();
+}
+
+size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
+ const DWARFDIE &orig_die,
+ const lldb::addr_t func_low_pc,
+ bool parse_siblings, bool parse_children,
+ VariableList *cc_variable_list) {
+ if (!orig_die)
+ return 0;
+ VariableListSP variable_list_sp;
-DWARFDIE
-SymbolFileDWARF::FindBlockContainingSpecification(const DWARFDIE &die,
- dw_offset_t spec_block_die_offset)
-{
- if (die)
- {
- switch (die.Tag())
- {
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- {
- if (die.GetAttributeValueAsReference (DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
- return die;
+ size_t vars_added = 0;
+ DWARFDIE die = orig_die;
+ while (die) {
+ dw_tag_t tag = die.Tag();
+
+ // Check to see if we have already parsed this variable or constant?
+ VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
+ if (var_sp) {
+ if (cc_variable_list)
+ cc_variable_list->AddVariableIfUnique(var_sp);
+ } else {
+ // We haven't already parsed it, lets do that now.
+ if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
+ (tag == DW_TAG_formal_parameter && sc.function)) {
+ if (variable_list_sp.get() == NULL) {
+ DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
+ dw_tag_t parent_tag = sc_parent_die.Tag();
+ switch (parent_tag) {
+ case DW_TAG_compile_unit:
+ if (sc.comp_unit != NULL) {
+ variable_list_sp = sc.comp_unit->GetVariableList(false);
+ if (variable_list_sp.get() == NULL) {
+ variable_list_sp.reset(new VariableList());
+ sc.comp_unit->SetVariableList(variable_list_sp);
+ }
+ } else {
+ GetObjectFile()->GetModule()->ReportError(
+ "parent 0x%8.8" PRIx64 " %s with no valid compile unit in "
+ "symbol context for 0x%8.8" PRIx64
+ " %s.\n",
+ sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(),
+ orig_die.GetID(), orig_die.GetTagAsCString());
+ }
+ break;
- if (die.GetAttributeValueAsReference (DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
- return die;
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ if (sc.function != NULL) {
+ // Check to see if we already have parsed the variables for the
+ // given scope
+
+ Block *block = sc.function->GetBlock(true).FindBlockByID(
+ sc_parent_die.GetID());
+ if (block == NULL) {
+ // This must be a specification or abstract origin with
+ // a concrete block counterpart in the current function. We need
+ // to find the concrete block so we can correctly add the
+ // variable to it
+ const DWARFDIE concrete_block_die =
+ FindBlockContainingSpecification(
+ DIERef(sc.function->GetID(), this),
+ sc_parent_die.GetOffset());
+ if (concrete_block_die)
+ block = sc.function->GetBlock(true).FindBlockByID(
+ concrete_block_die.GetID());
+ }
+
+ if (block != NULL) {
+ const bool can_create = false;
+ variable_list_sp = block->GetBlockVariableList(can_create);
+ if (variable_list_sp.get() == NULL) {
+ variable_list_sp.reset(new VariableList());
+ block->SetVariableList(variable_list_sp);
+ }
+ }
}
break;
- }
- // Give the concrete function die specified by "func_die_offset", find the
- // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
- // to "spec_block_die_offset"
- for (DWARFDIE child_die = die.GetFirstChild(); child_die; child_die = child_die.GetSibling())
- {
- DWARFDIE result_die = FindBlockContainingSpecification (child_die, spec_block_die_offset);
- if (result_die)
- return result_die;
+ default:
+ GetObjectFile()->GetModule()->ReportError(
+ "didn't find appropriate parent DIE for variable list for "
+ "0x%8.8" PRIx64 " %s.\n",
+ orig_die.GetID(), orig_die.GetTagAsCString());
+ break;
+ }
}
- }
-
- return DWARFDIE();
-}
-
-size_t
-SymbolFileDWARF::ParseVariables (const SymbolContext& sc,
- const DWARFDIE &orig_die,
- const lldb::addr_t func_low_pc,
- bool parse_siblings,
- bool parse_children,
- VariableList* cc_variable_list)
-{
- if (!orig_die)
- return 0;
-
- VariableListSP variable_list_sp;
- size_t vars_added = 0;
- DWARFDIE die = orig_die;
- while (die)
- {
- dw_tag_t tag = die.Tag();
-
- // Check to see if we have already parsed this variable or constant?
- VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
- if (var_sp)
- {
+ if (variable_list_sp) {
+ VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc));
+ if (var_sp) {
+ variable_list_sp->AddVariableIfUnique(var_sp);
if (cc_variable_list)
- cc_variable_list->AddVariableIfUnique (var_sp);
- }
- else
- {
- // We haven't already parsed it, lets do that now.
- if ((tag == DW_TAG_variable) ||
- (tag == DW_TAG_constant) ||
- (tag == DW_TAG_formal_parameter && sc.function))
- {
- if (variable_list_sp.get() == NULL)
- {
- DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
- dw_tag_t parent_tag = sc_parent_die.Tag();
- switch (parent_tag)
- {
- case DW_TAG_compile_unit:
- if (sc.comp_unit != NULL)
- {
- variable_list_sp = sc.comp_unit->GetVariableList(false);
- if (variable_list_sp.get() == NULL)
- {
- variable_list_sp.reset(new VariableList());
- sc.comp_unit->SetVariableList(variable_list_sp);
- }
- }
- else
- {
- GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
- sc_parent_die.GetID(),
- sc_parent_die.GetTagAsCString(),
- orig_die.GetID(),
- orig_die.GetTagAsCString());
- }
- break;
-
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- if (sc.function != NULL)
- {
- // Check to see if we already have parsed the variables for the given scope
-
- Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (block == NULL)
- {
- // This must be a specification or abstract origin with
- // a concrete block counterpart in the current function. We need
- // to find the concrete block so we can correctly add the
- // variable to it
- const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID(), this),
- sc_parent_die.GetOffset());
- if (concrete_block_die)
- block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
- }
-
- if (block != NULL)
- {
- const bool can_create = false;
- variable_list_sp = block->GetBlockVariableList (can_create);
- if (variable_list_sp.get() == NULL)
- {
- variable_list_sp.reset(new VariableList());
- block->SetVariableList(variable_list_sp);
- }
- }
- }
- break;
-
- default:
- GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
- orig_die.GetID(),
- orig_die.GetTagAsCString());
- break;
- }
- }
-
- if (variable_list_sp)
- {
- VariableSP var_sp (ParseVariableDIE(sc, die, func_low_pc));
- if (var_sp)
- {
- variable_list_sp->AddVariableIfUnique (var_sp);
- if (cc_variable_list)
- cc_variable_list->AddVariableIfUnique (var_sp);
- ++vars_added;
- }
- }
- }
+ cc_variable_list->AddVariableIfUnique(var_sp);
+ ++vars_added;
+ }
}
+ }
+ }
- bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
-
- if (!skip_children && parse_children && die.HasChildren())
- {
- vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, true, cc_variable_list);
- }
+ bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
- if (parse_siblings)
- die = die.GetSibling();
- else
- die.Clear();
+ if (!skip_children && parse_children && die.HasChildren()) {
+ vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true,
+ true, cc_variable_list);
}
- return vars_added;
+
+ if (parse_siblings)
+ die = die.GetSibling();
+ else
+ die.Clear();
+ }
+ return vars_added;
}
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-ConstString
-SymbolFileDWARF::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-SymbolFileDWARF::GetPluginVersion()
-{
- return 1;
-}
+ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); }
-void
-SymbolFileDWARF::DumpIndexes ()
-{
- StreamFile s(stdout, false);
-
- s.Printf ("DWARF index for (%s) '%s':",
- GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
- GetObjectFile()->GetFileSpec().GetPath().c_str());
- s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
- s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
- s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
- s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
- s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
- s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
- s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
- s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
-}
+uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
+void SymbolFileDWARF::DumpIndexes() {
+ StreamFile s(stdout, false);
-SymbolFileDWARFDebugMap *
-SymbolFileDWARF::GetDebugMapSymfile()
-{
- if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
- {
- lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
- if (module_sp)
- {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
- }
+ s.Printf(
+ "DWARF index for (%s) '%s':",
+ GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
+ GetObjectFile()->GetFileSpec().GetPath().c_str());
+ s.Printf("\nFunction basenames:\n");
+ m_function_basename_index.Dump(&s);
+ s.Printf("\nFunction fullnames:\n");
+ m_function_fullname_index.Dump(&s);
+ s.Printf("\nFunction methods:\n");
+ m_function_method_index.Dump(&s);
+ s.Printf("\nFunction selectors:\n");
+ m_function_selector_index.Dump(&s);
+ s.Printf("\nObjective C class selectors:\n");
+ m_objc_class_selectors_index.Dump(&s);
+ s.Printf("\nGlobals and statics:\n");
+ m_global_index.Dump(&s);
+ s.Printf("\nTypes:\n");
+ m_type_index.Dump(&s);
+ s.Printf("\nNamespaces:\n");
+ m_namespace_index.Dump(&s);
+}
+
+SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
+ if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) {
+ lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
+ if (module_sp) {
+ SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+ if (sym_vendor)
+ m_debug_map_symfile =
+ (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
}
- return m_debug_map_symfile;
+ }
+ return m_debug_map_symfile;
}
DWARFExpression::LocationListFormat
-SymbolFileDWARF::GetLocationListFormat() const
-{
- return DWARFExpression::RegularLocationList;
+SymbolFileDWARF::GetLocationListFormat() const {
+ return DWARFExpression::RegularLocationList;
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Tue Sep 6 15:57:50 2016
@@ -22,20 +22,20 @@
// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/dwarf.h"
#include "lldb/Core/Flags.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
+#include "lldb/Core/dwarf.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/DebugMacros.h"
-#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/lldb-private.h"
// Project includes
-#include "DWARFDefines.h"
#include "DWARFDataExtractor.h"
+#include "DWARFDefines.h"
#include "HashedNameToDIE.h"
#include "NameToDIE.h"
#include "UniqueDWARFASTType.h"
@@ -60,544 +60,465 @@ class DWARFFormValue;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
-#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
+#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
-class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID
-{
+class SymbolFileDWARF : public lldb_private::SymbolFile,
+ public lldb_private::UserID {
public:
- friend class SymbolFileDWARFDebugMap;
- friend class SymbolFileDWARFDwo;
- friend class DebugMapModule;
- friend struct DIERef;
- friend class DWARFCompileUnit;
- friend class DWARFDIE;
- friend class DWARFASTParserClang;
- friend class DWARFASTParserGo;
- friend class DWARFASTParserJava;
- friend class DWARFASTParserOCaml;
+ friend class SymbolFileDWARFDebugMap;
+ friend class SymbolFileDWARFDwo;
+ friend class DebugMapModule;
+ friend struct DIERef;
+ friend class DWARFCompileUnit;
+ friend class DWARFDIE;
+ friend class DWARFASTParserClang;
+ friend class DWARFASTParserGo;
+ friend class DWARFASTParserJava;
+ friend class DWARFASTParserOCaml;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static void
- DebuggerInitialize(lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::SymbolFile*
- CreateInstance (lldb_private::ObjectFile* obj_file);
+ static lldb_private::SymbolFile *
+ CreateInstance(lldb_private::ObjectFile *obj_file);
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
- SymbolFileDWARF(lldb_private::ObjectFile* ofile);
+ SymbolFileDWARF(lldb_private::ObjectFile *ofile);
- ~SymbolFileDWARF() override;
+ ~SymbolFileDWARF() override;
- uint32_t
- CalculateAbilities () override;
+ uint32_t CalculateAbilities() override;
- void
- InitializeObject() override;
+ void InitializeObject() override;
- //------------------------------------------------------------------
- // Compile Unit function calls
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
- uint32_t
- GetNumCompileUnits() override;
+ uint32_t GetNumCompileUnits() override;
- lldb::CompUnitSP
- ParseCompileUnitAtIndex(uint32_t index) override;
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- lldb::LanguageType
- ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc) override;
+ lldb::LanguageType
+ ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc) override;
+ size_t
+ ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override;
+ bool
+ ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros (const lldb_private::SymbolContext& sc) override;
+ bool
+ ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc,
- lldb_private::FileSpecList& support_files) override;
+ bool ParseCompileUnitSupportFiles(
+ const lldb_private::SymbolContext &sc,
+ lldb_private::FileSpecList &support_files) override;
- bool
- ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+ bool
+ ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
- bool
- ParseImportedModules(const lldb_private::SymbolContext &sc,
- std::vector<lldb_private::ConstString> &imported_modules) override;
+ bool ParseImportedModules(
+ const lldb_private::SymbolContext &sc,
+ std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t
- ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override;
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseTypes (const lldb_private::SymbolContext& sc) override;
+ size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseVariablesForContext (const lldb_private::SymbolContext& sc) override;
+ size_t
+ ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
- lldb_private::Type *
- ResolveTypeUID(lldb::user_id_t type_uid) override;
+ lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
- bool
- CompleteType (lldb_private::CompilerType& compiler_type) override;
+ bool CompleteType(lldb_private::CompilerType &compiler_type) override;
- lldb_private::Type *
- ResolveType (const DWARFDIE &die,
- bool assert_not_being_parsed = true,
- bool resolve_function_context = false);
+ lldb_private::Type *ResolveType(const DWARFDIE &die,
+ bool assert_not_being_parsed = true,
+ bool resolve_function_context = false);
- SymbolFileDWARF *
- GetDWARFForUID (lldb::user_id_t uid);
+ SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid);
- DWARFDIE
- GetDIEFromUID (lldb::user_id_t uid);
+ DWARFDIE
+ GetDIEFromUID(lldb::user_id_t uid);
- lldb_private::CompilerDecl
- GetDeclForUID (lldb::user_id_t uid) override;
+ lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUID (lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUID(lldb::user_id_t uid) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUID (lldb::user_id_t uid) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUID(lldb::user_id_t uid) override;
- void
- ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
-
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
- uint32_t
- ResolveSymbolContext (const lldb_private::Address& so_addr,
- uint32_t resolve_scope,
- lldb_private::SymbolContext& sc) override;
+ uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
+ uint32_t resolve_scope,
+ lldb_private::SymbolContext &sc) override;
- uint32_t
- ResolveSymbolContext (const lldb_private::FileSpec& file_spec,
- uint32_t line,
- bool check_inlines,
- uint32_t resolve_scope,
- lldb_private::SymbolContextList& sc_list) override;
+ uint32_t
+ ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
+ bool check_inlines, uint32_t resolve_scope,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t
- FindGlobalVariables (const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append,
- uint32_t max_matches,
- lldb_private::VariableList& variables) override;
+ uint32_t
+ FindGlobalVariables(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindGlobalVariables (const lldb_private::RegularExpression& regex,
- bool append,
- uint32_t max_matches,
- lldb_private::VariableList& variables) override;
+ uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex,
+ bool append, uint32_t max_matches,
+ lldb_private::VariableList &variables) override;
- uint32_t
- FindFunctions (const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask,
- bool include_inlines,
- bool append,
- lldb_private::SymbolContextList& sc_list) override;
+ uint32_t
+ FindFunctions(const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
- uint32_t
- FindFunctions (const lldb_private::RegularExpression& regex,
- bool include_inlines,
- bool append,
- lldb_private::SymbolContextList& sc_list) override;
+ uint32_t FindFunctions(const lldb_private::RegularExpression ®ex,
+ bool include_inlines, bool append,
+ lldb_private::SymbolContextList &sc_list) override;
- void
- GetMangledNamesForFunction (const std::string &scope_qualified_name,
- std::vector<lldb_private::ConstString> &mangled_names) override;
+ void GetMangledNamesForFunction(
+ const std::string &scope_qualified_name,
+ std::vector<lldb_private::ConstString> &mangled_names) override;
- uint32_t
- FindTypes (const lldb_private::SymbolContext& sc,
- const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx,
- bool append,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap& types) override;
+ uint32_t
+ FindTypes(const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ lldb_private::TypeMap &types) override;
- size_t
- FindTypes (const std::vector<lldb_private::CompilerContext> &context,
- bool append,
- lldb_private::TypeMap& types) override;
+ size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context,
+ bool append, lldb_private::TypeMap &types) override;
- lldb_private::TypeList *
- GetTypeList () override;
+ lldb_private::TypeList *GetTypeList() override;
- size_t
- GetTypes (lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
- lldb_private::TypeList &type_list) override;
+ size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ uint32_t type_mask,
+ lldb_private::TypeList &type_list) override;
- lldb_private::TypeSystem *
- GetTypeSystemForLanguage (lldb::LanguageType language) override;
+ lldb_private::TypeSystem *
+ GetTypeSystemForLanguage(lldb::LanguageType language) override;
- lldb_private::CompilerDeclContext
- FindNamespace (const lldb_private::SymbolContext& sc,
- const lldb_private::ConstString &name,
- const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ lldb_private::CompilerDeclContext FindNamespace(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::ConstString &name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ uint32_t GetPluginVersion() override;
- uint32_t
- GetPluginVersion() override;
+ const lldb_private::DWARFDataExtractor &get_debug_abbrev_data();
+ const lldb_private::DWARFDataExtractor &get_debug_addr_data();
+ const lldb_private::DWARFDataExtractor &get_debug_aranges_data();
+ const lldb_private::DWARFDataExtractor &get_debug_frame_data();
+ const lldb_private::DWARFDataExtractor &get_debug_info_data();
+ const lldb_private::DWARFDataExtractor &get_debug_line_data();
+ const lldb_private::DWARFDataExtractor &get_debug_macro_data();
+ const lldb_private::DWARFDataExtractor &get_debug_loc_data();
+ const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
+ const lldb_private::DWARFDataExtractor &get_debug_str_data();
+ const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
+ const lldb_private::DWARFDataExtractor &get_apple_names_data();
+ const lldb_private::DWARFDataExtractor &get_apple_types_data();
+ const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
+ const lldb_private::DWARFDataExtractor &get_apple_objc_data();
- const lldb_private::DWARFDataExtractor& get_debug_abbrev_data ();
- const lldb_private::DWARFDataExtractor& get_debug_addr_data ();
- const lldb_private::DWARFDataExtractor& get_debug_aranges_data ();
- const lldb_private::DWARFDataExtractor& get_debug_frame_data ();
- const lldb_private::DWARFDataExtractor& get_debug_info_data ();
- const lldb_private::DWARFDataExtractor& get_debug_line_data ();
- const lldb_private::DWARFDataExtractor& get_debug_macro_data ();
- const lldb_private::DWARFDataExtractor& get_debug_loc_data ();
- const lldb_private::DWARFDataExtractor& get_debug_ranges_data ();
- const lldb_private::DWARFDataExtractor& get_debug_str_data ();
- const lldb_private::DWARFDataExtractor& get_debug_str_offsets_data ();
- const lldb_private::DWARFDataExtractor& get_apple_names_data ();
- const lldb_private::DWARFDataExtractor& get_apple_types_data ();
- const lldb_private::DWARFDataExtractor& get_apple_namespaces_data ();
- const lldb_private::DWARFDataExtractor& get_apple_objc_data ();
+ DWARFDebugAbbrev *DebugAbbrev();
+ const DWARFDebugAbbrev *DebugAbbrev() const;
- DWARFDebugAbbrev*
- DebugAbbrev();
+ DWARFDebugInfo *DebugInfo();
- const DWARFDebugAbbrev*
- DebugAbbrev() const;
+ const DWARFDebugInfo *DebugInfo() const;
- DWARFDebugInfo*
- DebugInfo();
+ DWARFDebugRanges *DebugRanges();
- const DWARFDebugInfo*
- DebugInfo() const;
+ const DWARFDebugRanges *DebugRanges() const;
- DWARFDebugRanges*
- DebugRanges();
+ static bool SupportedVersion(uint16_t version);
- const DWARFDebugRanges*
- DebugRanges() const;
+ DWARFDIE
+ GetDeclContextDIEContainingDIE(const DWARFDIE &die);
- static bool
- SupportedVersion(uint16_t version);
+ bool
+ HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type);
- DWARFDIE
- GetDeclContextDIEContainingDIE (const DWARFDIE &die);
+ lldb_private::CompileUnit *
+ GetCompUnitForDWARFCompUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx = UINT32_MAX);
- bool
- HasForwardDeclForClangType (const lldb_private::CompilerType &compiler_type);
+ size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
+ DIEArray &method_die_offsets);
- lldb_private::CompileUnit*
- GetCompUnitForDWARFCompUnit(DWARFCompileUnit* dwarf_cu,
- uint32_t cu_idx = UINT32_MAX);
+ bool Supports_DW_AT_APPLE_objc_complete_type(DWARFCompileUnit *cu);
- size_t
- GetObjCMethodDIEOffsets (lldb_private::ConstString class_name,
- DIEArray &method_die_offsets);
+ lldb_private::DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset);
- bool
- Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu);
+ static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
- lldb_private::DebugMacrosSP
- ParseDebugMacros(lldb::offset_t *offset);
+ virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit *dwarf_cu,
+ uint32_t cu_idx);
- static DWARFDIE
- GetParentSymbolContextDIE(const DWARFDIE &die);
+ virtual lldb_private::DWARFExpression::LocationListFormat
+ GetLocationListFormat() const;
- virtual lldb::CompUnitSP
- ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx);
+ lldb::ModuleSP GetDWOModule(lldb_private::ConstString name);
- virtual lldb_private::DWARFExpression::LocationListFormat
- GetLocationListFormat() const;
+ virtual DWARFDIE GetDIE(const DIERef &die_ref);
- lldb::ModuleSP
- GetDWOModule (lldb_private::ConstString name);
+ virtual std::unique_ptr<SymbolFileDWARFDwo>
+ GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu,
+ const DWARFDebugInfoEntry &cu_die);
- virtual DWARFDIE
- GetDIE(const DIERef &die_ref);
+protected:
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
+ DIEToTypePtr;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
+ DIEToVariableSP;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
+ lldb::opaque_compiler_type_t>
+ DIEToClangType;
+ typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
- virtual std::unique_ptr<SymbolFileDWARFDwo>
- GetDwoSymbolFileForCompileUnit(DWARFCompileUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die);
+ struct DWARFDataSegment {
+ std::once_flag m_flag;
+ lldb_private::DWARFDataExtractor m_data;
+ };
-protected:
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::opaque_compiler_type_t> DIEToClangType;
- typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
-
- struct DWARFDataSegment
- {
- std::once_flag m_flag;
- lldb_private::DWARFDataExtractor m_data;
- };
-
- DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
-
- const lldb_private::DWARFDataExtractor&
- GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment);
-
- virtual void
- LoadSectionData (lldb::SectionType sect_type, lldb_private::DWARFDataExtractor& data);
-
- bool
- DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx);
-
- bool
- DIEInDeclContext (const lldb_private::CompilerDeclContext *parent_decl_ctx,
- const DWARFDIE &die);
-
- virtual DWARFCompileUnit*
- GetDWARFCompileUnit (lldb_private::CompileUnit *comp_unit);
-
- DWARFCompileUnit*
- GetNextUnparsedDWARFCompileUnit (DWARFCompileUnit* prev_cu);
-
- bool
- GetFunction (const DWARFDIE &die,
- lldb_private::SymbolContext& sc);
-
- lldb_private::Function *
- ParseCompileUnitFunction (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die);
-
- size_t
- ParseFunctionBlocks (const lldb_private::SymbolContext& sc,
- lldb_private::Block *parent_block,
- const DWARFDIE &die,
- lldb::addr_t subprogram_low_pc,
- uint32_t depth);
-
- size_t
- ParseTypes (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- bool parse_siblings,
- bool parse_children);
-
- lldb::TypeSP
- ParseType (const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- bool *type_is_new);
-
- lldb_private::Type *
- ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed);
-
- lldb_private::Type *
- ResolveTypeUID(const DIERef &die_ref);
-
- lldb::VariableSP
- ParseVariableDIE(const lldb_private::SymbolContext& sc,
- const DWARFDIE &die,
- const lldb::addr_t func_low_pc);
-
- size_t
- ParseVariables (const lldb_private::SymbolContext& sc,
- const DWARFDIE &orig_die,
- const lldb::addr_t func_low_pc,
- bool parse_siblings,
- bool parse_children,
- lldb_private::VariableList* cc_variable_list = NULL);
-
- bool
- ClassOrStructIsVirtual (const DWARFDIE &die);
-
- // Given a die_offset, figure out the symbol context representing that die.
- bool
- ResolveFunction (const DIERef& die_ref,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
+ DISALLOW_COPY_AND_ASSIGN(SymbolFileDWARF);
+
+ const lldb_private::DWARFDataExtractor &
+ GetCachedSectionData(lldb::SectionType sect_type,
+ DWARFDataSegment &data_segment);
+
+ virtual void LoadSectionData(lldb::SectionType sect_type,
+ lldb_private::DWARFDataExtractor &data);
+
+ bool DeclContextMatchesThisSymbolFile(
+ const lldb_private::CompilerDeclContext *decl_ctx);
+
+ bool
+ DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ const DWARFDIE &die);
+
+ virtual DWARFCompileUnit *
+ GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
- bool
- ResolveFunction (const DWARFDIE &die,
+ DWARFCompileUnit *GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit *prev_cu);
+
+ bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc);
+
+ lldb_private::Function *
+ ParseCompileUnitFunction(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die);
+
+ size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc,
+ lldb_private::Block *parent_block,
+ const DWARFDIE &die,
+ lldb::addr_t subprogram_low_pc, uint32_t depth);
+
+ size_t ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ bool parse_siblings, bool parse_children);
+
+ lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die, bool *type_is_new);
+
+ lldb_private::Type *ResolveTypeUID(const DWARFDIE &die,
+ bool assert_not_being_parsed);
+
+ lldb_private::Type *ResolveTypeUID(const DIERef &die_ref);
+
+ lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ const lldb::addr_t func_low_pc);
+
+ size_t ParseVariables(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &orig_die,
+ const lldb::addr_t func_low_pc, bool parse_siblings,
+ bool parse_children,
+ lldb_private::VariableList *cc_variable_list = NULL);
+
+ bool ClassOrStructIsVirtual(const DWARFDIE &die);
+
+ // Given a die_offset, figure out the symbol context representing that die.
+ bool ResolveFunction(const DIERef &die_ref, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void FindFunctions(const lldb_private::ConstString &name,
+ const NameToDIE &name_to_die, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void FindFunctions(const lldb_private::RegularExpression ®ex,
+ const NameToDIE &name_to_die, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ void FindFunctions(const lldb_private::RegularExpression ®ex,
+ const DWARFMappedHash::MemoryTable &memory_table,
bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
+ lldb_private::SymbolContextList &sc_list);
+
+ virtual lldb::TypeSP
+ FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx);
- void
- FindFunctions(const lldb_private::ConstString &name,
- const NameToDIE &name_to_die,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- void
- FindFunctions (const lldb_private::RegularExpression ®ex,
- const NameToDIE &name_to_die,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- void
- FindFunctions (const lldb_private::RegularExpression ®ex,
- const DWARFMappedHash::MemoryTable &memory_table,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- virtual lldb::TypeSP
- FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
-
- lldb::TypeSP
- FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
- const lldb_private::ConstString &type_name,
- bool must_be_implementation);
-
- lldb::TypeSP
- FindCompleteObjCDefinitionType (const lldb_private::ConstString &type_name,
- bool header_definition_ok);
-
- lldb_private::Symbol *
- GetObjCClassSymbol (const lldb_private::ConstString &objc_class_name);
-
- void
- ParseFunctions (const DIEArray &die_offsets,
- bool include_inlines,
- lldb_private::SymbolContextList& sc_list);
-
- lldb::TypeSP
- GetTypeForDIE (const DWARFDIE &die, bool resolve_function_context = false);
-
- void
- Index();
-
- void
- DumpIndexes();
-
- void
- SetDebugMapModule (const lldb::ModuleSP &module_sp)
- {
- m_debug_map_module_wp = module_sp;
- }
-
- SymbolFileDWARFDebugMap *
- GetDebugMapSymfile ();
-
- DWARFDIE
- FindBlockContainingSpecification (const DIERef& func_die_ref, dw_offset_t spec_block_die_offset);
-
- DWARFDIE
- FindBlockContainingSpecification (const DWARFDIE &die, dw_offset_t spec_block_die_offset);
-
- virtual UniqueDWARFASTTypeMap &
- GetUniqueDWARFASTTypeMap ();
-
- bool
- DIEDeclContextsMatch (const DWARFDIE &die1,
- const DWARFDIE &die2);
-
- bool
- ClassContainsSelector (const DWARFDIE &class_die,
- const lldb_private::ConstString &selector);
-
- bool
- FixupAddress (lldb_private::Address &addr);
-
- typedef std::set<lldb_private::Type *> TypeSet;
-
- typedef std::map<lldb_private::ConstString, lldb::ModuleSP> ExternalTypeModuleMap;
-
- void
- GetTypes (const DWARFDIE &die,
- dw_offset_t min_die_offset,
- dw_offset_t max_die_offset,
- uint32_t type_mask,
- TypeSet &type_set);
-
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap;
-
- GlobalVariableMap &
- GetGlobalAranges();
-
- void
- UpdateExternalModuleListIfNeeded();
-
- virtual DIEToTypePtr&
- GetDIEToType() { return m_die_to_type; }
-
- virtual DIEToVariableSP&
- GetDIEToVariable() { return m_die_to_variable_sp; }
-
- virtual DIEToClangType&
- GetForwardDeclDieToClangType() { return m_forward_decl_die_to_clang_type; }
-
- virtual ClangTypeToDIE&
- GetForwardDeclClangTypeToDie() { return m_forward_decl_clang_type_to_die; }
-
- lldb::ModuleWP m_debug_map_module_wp;
- SymbolFileDWARFDebugMap * m_debug_map_symfile;
- lldb_private::DWARFDataExtractor m_dwarf_data;
-
- DWARFDataSegment m_data_debug_abbrev;
- DWARFDataSegment m_data_debug_addr;
- DWARFDataSegment m_data_debug_aranges;
- DWARFDataSegment m_data_debug_frame;
- DWARFDataSegment m_data_debug_info;
- DWARFDataSegment m_data_debug_line;
- DWARFDataSegment m_data_debug_macro;
- DWARFDataSegment m_data_debug_loc;
- DWARFDataSegment m_data_debug_ranges;
- DWARFDataSegment m_data_debug_str;
- DWARFDataSegment m_data_debug_str_offsets;
- DWARFDataSegment m_data_apple_names;
- DWARFDataSegment m_data_apple_types;
- DWARFDataSegment m_data_apple_namespaces;
- DWARFDataSegment m_data_apple_objc;
-
- // The unique pointer items below are generated on demand if and when someone accesses
- // them through a non const version of this class.
- std::unique_ptr<DWARFDebugAbbrev> m_abbr;
- std::unique_ptr<DWARFDebugInfo> m_info;
- std::unique_ptr<DWARFDebugLine> m_line;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
- std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
- std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
-
- typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP> DebugMacrosMap;
- DebugMacrosMap m_debug_macros_map;
-
- ExternalTypeModuleMap m_external_type_modules;
- NameToDIE m_function_basename_index; // All concrete functions
- NameToDIE m_function_fullname_index; // All concrete functions
- NameToDIE m_function_method_index; // All inlined functions
- NameToDIE m_function_selector_index; // All method names for functions of classes
- NameToDIE m_objc_class_selectors_index; // Given a class name, find all selectors for the class
- NameToDIE m_global_index; // Global and static variables
- NameToDIE m_type_index; // All type DIE offsets
- NameToDIE m_namespace_index; // All type DIE offsets
- bool m_indexed:1,
- m_using_apple_tables:1,
- m_fetched_external_modules:1;
- lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
-
- typedef std::shared_ptr<std::set<DIERef> > DIERefSetSP;
- typedef std::unordered_map<std::string, DIERefSetSP> NameToOffsetMap;
- NameToOffsetMap m_function_scope_qualified_name_map;
- std::unique_ptr<DWARFDebugRanges> m_ranges;
- UniqueDWARFASTTypeMap m_unique_ast_type_map;
- DIEToTypePtr m_die_to_type;
- DIEToVariableSP m_die_to_variable_sp;
- DIEToClangType m_forward_decl_die_to_clang_type;
- ClangTypeToDIE m_forward_decl_clang_type_to_die;
+ lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
+ const DWARFDIE &die, const lldb_private::ConstString &type_name,
+ bool must_be_implementation);
+
+ lldb::TypeSP
+ FindCompleteObjCDefinitionType(const lldb_private::ConstString &type_name,
+ bool header_definition_ok);
+
+ lldb_private::Symbol *
+ GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
+
+ void ParseFunctions(const DIEArray &die_offsets, bool include_inlines,
+ lldb_private::SymbolContextList &sc_list);
+
+ lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
+ bool resolve_function_context = false);
+
+ void Index();
+
+ void DumpIndexes();
+
+ void SetDebugMapModule(const lldb::ModuleSP &module_sp) {
+ m_debug_map_module_wp = module_sp;
+ }
+
+ SymbolFileDWARFDebugMap *GetDebugMapSymfile();
+
+ DWARFDIE
+ FindBlockContainingSpecification(const DIERef &func_die_ref,
+ dw_offset_t spec_block_die_offset);
+
+ DWARFDIE
+ FindBlockContainingSpecification(const DWARFDIE &die,
+ dw_offset_t spec_block_die_offset);
+
+ virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap();
+
+ bool DIEDeclContextsMatch(const DWARFDIE &die1, const DWARFDIE &die2);
+
+ bool ClassContainsSelector(const DWARFDIE &class_die,
+ const lldb_private::ConstString &selector);
+
+ bool FixupAddress(lldb_private::Address &addr);
+
+ typedef std::set<lldb_private::Type *> TypeSet;
+
+ typedef std::map<lldb_private::ConstString, lldb::ModuleSP>
+ ExternalTypeModuleMap;
+
+ void GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
+ dw_offset_t max_die_offset, uint32_t type_mask,
+ TypeSet &type_set);
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t,
+ lldb_private::Variable *>
+ GlobalVariableMap;
+
+ GlobalVariableMap &GetGlobalAranges();
+
+ void UpdateExternalModuleListIfNeeded();
+
+ virtual DIEToTypePtr &GetDIEToType() { return m_die_to_type; }
+
+ virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; }
+
+ virtual DIEToClangType &GetForwardDeclDieToClangType() {
+ return m_forward_decl_die_to_clang_type;
+ }
+
+ virtual ClangTypeToDIE &GetForwardDeclClangTypeToDie() {
+ return m_forward_decl_clang_type_to_die;
+ }
+
+ lldb::ModuleWP m_debug_map_module_wp;
+ SymbolFileDWARFDebugMap *m_debug_map_symfile;
+ lldb_private::DWARFDataExtractor m_dwarf_data;
+
+ DWARFDataSegment m_data_debug_abbrev;
+ DWARFDataSegment m_data_debug_addr;
+ DWARFDataSegment m_data_debug_aranges;
+ DWARFDataSegment m_data_debug_frame;
+ DWARFDataSegment m_data_debug_info;
+ DWARFDataSegment m_data_debug_line;
+ DWARFDataSegment m_data_debug_macro;
+ DWARFDataSegment m_data_debug_loc;
+ DWARFDataSegment m_data_debug_ranges;
+ DWARFDataSegment m_data_debug_str;
+ DWARFDataSegment m_data_debug_str_offsets;
+ DWARFDataSegment m_data_apple_names;
+ DWARFDataSegment m_data_apple_types;
+ DWARFDataSegment m_data_apple_namespaces;
+ DWARFDataSegment m_data_apple_objc;
+
+ // The unique pointer items below are generated on demand if and when someone
+ // accesses
+ // them through a non const version of this class.
+ std::unique_ptr<DWARFDebugAbbrev> m_abbr;
+ std::unique_ptr<DWARFDebugInfo> m_info;
+ std::unique_ptr<DWARFDebugLine> m_line;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
+ std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
+
+ typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
+ DebugMacrosMap;
+ DebugMacrosMap m_debug_macros_map;
+
+ ExternalTypeModuleMap m_external_type_modules;
+ NameToDIE m_function_basename_index; // All concrete functions
+ NameToDIE m_function_fullname_index; // All concrete functions
+ NameToDIE m_function_method_index; // All inlined functions
+ NameToDIE
+ m_function_selector_index; // All method names for functions of classes
+ NameToDIE m_objc_class_selectors_index; // Given a class name, find all
+ // selectors for the class
+ NameToDIE m_global_index; // Global and static variables
+ NameToDIE m_type_index; // All type DIE offsets
+ NameToDIE m_namespace_index; // All type DIE offsets
+ bool m_indexed : 1, m_using_apple_tables : 1, m_fetched_external_modules : 1;
+ lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+
+ typedef std::shared_ptr<std::set<DIERef>> DIERefSetSP;
+ typedef std::unordered_map<std::string, DIERefSetSP> NameToOffsetMap;
+ NameToOffsetMap m_function_scope_qualified_name_map;
+ std::unique_ptr<DWARFDebugRanges> m_ranges;
+ UniqueDWARFASTTypeMap m_unique_ast_type_map;
+ DIEToTypePtr m_die_to_type;
+ DIEToVariableSP m_die_to_variable_sp;
+ DIEToClangType m_forward_decl_die_to_clang_type;
+ ClangTypeToDIE m_forward_decl_clang_type_to_die;
};
-#endif // SymbolFileDWARF_SymbolFileDWARF_h_
+#endif // SymbolFileDWARF_SymbolFileDWARF_h_
More information about the lldb-commits
mailing list