The fix form sizes use to have two arrays: one for 4 byte addresses and in for 8 byte addresses. The table had an issue where DW_FORM_flag_present wasn't being represented as a fixed size form because its actual size _is_ zero and zero was used to indicate the form isn't fixed in size. Any code that needed to quickly access the DWARF had to get a FixedFormSizes instance using the address byte size.
This fix cleans things up by adding a DWARFFormValue::GetFixedSize() both as a static method and as a member function on DWARFFormValue. It correctly can indicate if a form size is zero. This cleanup is a precursor to a follow up patch where I hope to speed up DWARF parsing.
I verified performance doesn't regress by loading hundreds of DWARF files and setting a breakpoint by file and line and by name in files that do not have DWARF indexes. Performance remained consistent between the two approaches.
Differential Revision: https://reviews.llvm.org/D62416
llvm-svn: 361675
buildConfiguration = "DebugClang"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "1"
+ launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
ReferencedContainer = "container:lldb.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
+ <CommandLineArguments>
+ <CommandLineArgument
+ argument = "~/Documents/src/args/a.out "
+ isEnabled = "YES">
+ </CommandLineArgument>
+ </CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes,
uint32_t depth) const {
- if (IsValid()) {
- return m_die->GetAttributes(m_cu, m_cu->GetFixedFormSizes(), attributes,
- depth);
- }
+ if (IsValid())
+ return m_die->GetAttributes(m_cu, attributes, depth);
if (depth == 0)
attributes.Clear();
return 0;
bool DWARFDebugInfoEntry::FastExtract(
const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
lldb::offset_t *offset_ptr) {
m_offset = *offset_ptr;
m_parent_idx = 0;
for (i = 0; i < numAttributes; ++i) {
form = abbrevDecl->GetFormByIndexUnchecked(i);
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
if (fixed_skip_size)
- offset += fixed_skip_size;
+ offset += *fixed_skip_size;
else {
bool form_is_indirect = false;
do {
// results. Any duplicate attributes will have the first instance take
// precedence (this can happen for declaration attributes).
size_t DWARFDebugInfoEntry::GetAttributes(
- const DWARFUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
- DWARFAttributes &attributes, uint32_t curr_depth) const {
+ const DWARFUnit *cu, DWARFAttributes &attributes,
+ uint32_t curr_depth) const {
const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
lldb::offset_t offset = 0;
if (cu)
if (abbrevDecl) {
const DWARFDataExtractor &debug_info_data = cu->GetData();
- if (fixed_form_sizes.Empty())
- fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
- cu->GetAddressByteSize());
-
const uint32_t num_attributes = abbrevDecl->NumAttributes();
for (uint32_t i = 0; i < num_attributes; ++i) {
DWARFFormValue form_value(cu);
spec_die.GetAttributes(attributes, curr_depth + 1);
}
} else {
- const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
+ llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu);
if (fixed_skip_size)
- offset += fixed_skip_size;
+ offset += *fixed_skip_size;
else
DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
}
DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+ GetAttributes(cu, attributes);
return GetParentDeclContextDIE(cu, attributes);
}
const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
std::string &storage) const {
DWARFAttributes attributes;
- GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
+ GetAttributes(cu, attributes);
return GetQualifiedName(cu, attributes, storage);
}
bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data,
const DWARFUnit *cu,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
lldb::offset_t *offset_ptr);
bool Extract(const DWARFUnit *cu, lldb::offset_t *offset_ptr);
DWARFDebugInfoEntry **block_die);
size_t GetAttributes(const DWARFUnit *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!!!
using namespace lldb_private;
-static uint8_t g_form_sizes_addr4[] = {
- 0, // 0x00 unused
- 4, // 0x01 DW_FORM_addr
- 0, // 0x02 unused
- 0, // 0x03 DW_FORM_block2
- 0, // 0x04 DW_FORM_block4
- 2, // 0x05 DW_FORM_data2
- 4, // 0x06 DW_FORM_data4
- 8, // 0x07 DW_FORM_data8
- 0, // 0x08 DW_FORM_string
- 0, // 0x09 DW_FORM_block
- 0, // 0x0a DW_FORM_block1
- 1, // 0x0b DW_FORM_data1
- 1, // 0x0c DW_FORM_flag
- 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
- 1, // 0x11 DW_FORM_ref1
- 2, // 0x12 DW_FORM_ref2
- 4, // 0x13 DW_FORM_ref4
- 8, // 0x14 DW_FORM_ref8
- 0, // 0x15 DW_FORM_ref_udata
- 0, // 0x16 DW_FORM_indirect
- 4, // 0x17 DW_FORM_sec_offset
- 0, // 0x18 DW_FORM_exprloc
- 0, // 0x19 DW_FORM_flag_present
- 0, // 0x1a
- 0, // 0x1b
- 0, // 0x1c
- 0, // 0x1d
- 0, // 0x1e
- 0, // 0x1f
- 8, // 0x20 DW_FORM_ref_sig8
-
-};
-
-static uint8_t g_form_sizes_addr8[] = {
- 0, // 0x00 unused
- 8, // 0x01 DW_FORM_addr
- 0, // 0x02 unused
- 0, // 0x03 DW_FORM_block2
- 0, // 0x04 DW_FORM_block4
- 2, // 0x05 DW_FORM_data2
- 4, // 0x06 DW_FORM_data4
- 8, // 0x07 DW_FORM_data8
- 0, // 0x08 DW_FORM_string
- 0, // 0x09 DW_FORM_block
- 0, // 0x0a DW_FORM_block1
- 1, // 0x0b DW_FORM_data1
- 1, // 0x0c DW_FORM_flag
- 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
- 1, // 0x11 DW_FORM_ref1
- 2, // 0x12 DW_FORM_ref2
- 4, // 0x13 DW_FORM_ref4
- 8, // 0x14 DW_FORM_ref8
- 0, // 0x15 DW_FORM_ref_udata
- 0, // 0x16 DW_FORM_indirect
- 4, // 0x17 DW_FORM_sec_offset
- 0, // 0x18 DW_FORM_exprloc
- 0, // 0x19 DW_FORM_flag_present
- 0, // 0x1a
- 0, // 0x1b
- 0, // 0x1c
- 0, // 0x1d
- 0, // 0x1e
- 0, // 0x1f
- 8, // 0x20 DW_FORM_ref_sig8
-};
-
-DWARFFormValue::FixedFormSizes
-DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size) {
- 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));
- }
- return FixedFormSizes();
-}
-
void DWARFFormValue::Clear() {
m_unit = nullptr;
m_form = 0;
return true;
}
+struct FormSize {
+ uint8_t valid:1, size:7;
+};
+static FormSize g_form_sizes[] = {
+ {0,0}, // 0x00 unused
+ {0,0}, // 0x01 DW_FORM_addr
+ {0,0}, // 0x02 unused
+ {0,0}, // 0x03 DW_FORM_block2
+ {0,0}, // 0x04 DW_FORM_block4
+ {1,2}, // 0x05 DW_FORM_data2
+ {1,4}, // 0x06 DW_FORM_data4
+ {1,8}, // 0x07 DW_FORM_data8
+ {0,0}, // 0x08 DW_FORM_string
+ {0,0}, // 0x09 DW_FORM_block
+ {0,0}, // 0x0a DW_FORM_block1
+ {1,1}, // 0x0b DW_FORM_data1
+ {1,1}, // 0x0c DW_FORM_flag
+ {0,0}, // 0x0d DW_FORM_sdata
+ {1,4}, // 0x0e DW_FORM_strp
+ {0,0}, // 0x0f DW_FORM_udata
+ {0,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,1}, // 0x11 DW_FORM_ref1
+ {1,2}, // 0x12 DW_FORM_ref2
+ {1,4}, // 0x13 DW_FORM_ref4
+ {1,8}, // 0x14 DW_FORM_ref8
+ {0,0}, // 0x15 DW_FORM_ref_udata
+ {0,0}, // 0x16 DW_FORM_indirect
+ {1,4}, // 0x17 DW_FORM_sec_offset
+ {0,0}, // 0x18 DW_FORM_exprloc
+ {1,0}, // 0x19 DW_FORM_flag_present
+ {0,0}, // 0x1a
+ {0,0}, // 0x1b
+ {0,0}, // 0x1c
+ {0,0}, // 0x1d
+ {0,0}, // 0x1e
+ {0,0}, // 0x1f
+ {1,8}, // 0x20 DW_FORM_ref_sig8
+};
+
+llvm::Optional<uint8_t>
+DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) {
+ if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid)
+ return g_form_sizes[form].size;
+ if (form == DW_FORM_addr && u)
+ return u->GetAddressByteSize();
+ return llvm::None;
+}
+
+llvm::Optional<uint8_t> DWARFFormValue::GetFixedSize() const {
+ return GetFixedSize(m_form, m_unit);
+}
+
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_unit);
#include "DWARFDataExtractor.h"
#include <stddef.h>
+#include "llvm/ADT/Optional.h"
class DWARFUnit;
class SymbolFileDWARF;
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,
bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
const uint8_t *BlockData() const;
+ static llvm::Optional<uint8_t> GetFixedSize(dw_form_t form,
+ const DWARFUnit *u);
+ llvm::Optional<uint8_t> GetFixedSize() const;
DWARFDIE Reference() const;
uint64_t Reference(dw_offset_t offset) const;
bool Boolean() const { return m_value.value.uval != 0; }
lldb::offset_t *offset_ptr, const DWARFUnit *unit);
static bool IsBlockForm(const dw_form_t form);
static bool IsDataForm(const dw_form_t form);
- static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size);
static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
void Clear();
static bool FormIsSupported(dw_form_t form);
// We are in our compile unit, parse starting at the offset we were told to
// parse
const DWARFDataExtractor &data = GetData();
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize());
if (offset < GetNextUnitOffset() &&
- m_first_die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+ m_first_die.FastExtract(data, this, &offset)) {
AddUnitDIE(m_first_die);
return;
}
die_index_stack.reserve(32);
die_index_stack.push_back(0);
bool prev_die_had_children = false;
- DWARFFormValue::FixedFormSizes fixed_form_sizes =
- DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize());
- while (offset < next_cu_offset &&
- die.FastExtract(data, this, fixed_form_sizes, &offset)) {
+ while (offset < next_cu_offset && die.FastExtract(data, this, &offset)) {
const bool null_die = die.IsNULL();
if (depth == 0) {
assert(m_die_array.empty() && "Compile unit DIE already added");
return nullptr;
}
-DWARFFormValue::FixedFormSizes DWARFUnit::GetFixedFormSizes() {
- return DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize());
-}
-
void DWARFUnit::SetBaseAddress(dw_addr_t base_addr) { m_base_addr = base_addr; }
// Compare function DWARFDebugAranges::Range structures
const DWARFDebugAranges &GetFunctionAranges();
- DWARFFormValue::FixedFormSizes GetFixedFormSizes();
-
void SetBaseAddress(dw_addr_t base_addr);
DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); }
}
const LanguageType cu_language = unit.GetLanguageType();
- DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes();
- IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(), set);
+ IndexUnitImpl(unit, cu_language, unit.GetOffset(), set);
SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile();
if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) {
IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language,
- fixed_form_sizes, unit.GetOffset(), set);
+ unit.GetOffset(), set);
}
}
void ManualDWARFIndex::IndexUnitImpl(
DWARFUnit &unit, const LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
const dw_offset_t cu_offset, IndexSet &set) {
for (const DWARFDebugInfoEntry &die : unit.dies()) {
const dw_tag_t tag = die.Tag();
bool is_global_or_static_variable = false;
DWARFFormValue specification_die_form;
- const size_t num_attributes =
- die.GetAttributes(&unit, fixed_form_sizes, attributes);
+ const size_t num_attributes = die.GetAttributes(&unit, attributes);
if (num_attributes > 0) {
for (uint32_t i = 0; i < num_attributes; ++i) {
dw_attr_t attr = attributes.AttributeAtIndex(i);
static void
IndexUnitImpl(DWARFUnit &unit, const lldb::LanguageType cu_language,
- const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
const dw_offset_t cu_offset, IndexSet &set);
/// Non-null value means we haven't built the index yet.
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());
uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- uint32_t data_length =
- fixed_form_sizes.GetSize(form_value.Form());
- if (data_length == 0) {
+ if (auto data_length = form_value.GetFixedSize())
+ location.CopyOpcodeData(module, debug_info_data, data_offset,
+ *data_length);
+ else {
const uint8_t *data_pointer = form_value.BlockData();
if (data_pointer) {
form_value.Unsigned();
// 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());
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);
+ if (auto data_length = form_value.GetFixedSize())
+ location.CopyOpcodeData(module, debug_info_data,
+ data_offset, *data_length);
} else {
const char *str = form_value.AsCString();
uint32_t string_offset =