summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-04-08 14:37:16 +0000
committerAlexey Samsonov <samsonov@google.com>2013-04-08 14:37:16 +0000
commitd6b89ef0fa17cf77677358a797934fa061564f5b (patch)
treefbacfbddd01c1605411a6da1c61df35aa2b8ed72
parent9d55c099d628d7835dd1b502cb29c96cae350099 (diff)
downloadllvm-d6b89ef0fa17cf77677358a797934fa061564f5b.tar.gz
llvm-d6b89ef0fa17cf77677358a797934fa061564f5b.tar.bz2
llvm-d6b89ef0fa17cf77677358a797934fa061564f5b.tar.xz
DWARF parser: remove duplicated code and fix code style in DIE extractors.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179023 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp338
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.h11
2 files changed, 81 insertions, 268 deletions
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index 02b15d6904..0fd5d488ae 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -94,279 +94,87 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
OS << ")\n";
}
-bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu,
- const uint8_t *fixed_form_sizes,
- uint32_t *offset_ptr) {
- Offset = *offset_ptr;
-
- DataExtractor debug_info_data = cu->getDebugInfoExtractor();
- uint64_t abbrCode = debug_info_data.getULEB128(offset_ptr);
-
- assert(fixed_form_sizes); // For best performance this should be specified!
-
- if (abbrCode) {
- uint32_t offset = *offset_ptr;
-
- AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
-
- // Skip all data in the .debug_info for the attributes
- const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
- uint32_t i;
- uint16_t form;
- for (i=0; i<numAttributes; ++i) {
-
- form = AbbrevDecl->getFormByIndex(i);
-
- // FIXME: Currently we're checking if this is less than the last
- // entry in the fixed_form_sizes table, but this should be changed
- // to use dynamic dispatch.
- const uint8_t fixed_skip_size = (form < DW_FORM_ref_sig8) ?
- fixed_form_sizes[form] : 0;
- 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(&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:
- case DW_FORM_ref_addr:
- form_size = cu->getAddressByteSize();
- 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_strp:
- 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_str_index:
- case DW_FORM_GNU_addr_index:
- debug_info_data.getULEB128(&offset);
- break;
-
- case DW_FORM_indirect:
- form_is_indirect = true;
- form = debug_info_data.getULEB128(&offset);
- break;
-
- // FIXME: 64-bit for DWARF64
- case DW_FORM_sec_offset:
- debug_info_data.getU32(offset_ptr);
- break;
-
- default:
- *offset_ptr = Offset;
- return false;
- }
- offset += form_size;
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
- } else {
+bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *CU,
+ const uint8_t *FixedFormSizes,
+ uint32_t *OffsetPtr) {
+ Offset = *OffsetPtr;
+ DataExtractor DebugInfoData = CU->getDebugInfoExtractor();
+ uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
+ if (0 == AbbrCode) {
+ // NULL debug tag entry.
AbbrevDecl = NULL;
- return true; // NULL debug tag entry
+ return true;
+ }
+ AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
+ assert(AbbrevDecl);
+ assert(FixedFormSizes); // For best performance this should be specified!
+
+ // Skip all data in the .debug_info for the attributes
+ for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) {
+ uint16_t Form = AbbrevDecl->getFormByIndex(i);
+
+ // FIXME: Currently we're checking if this is less than the last
+ // entry in the fixed_form_sizes table, but this should be changed
+ // to use dynamic dispatch.
+ uint8_t FixedFormSize =
+ (Form < DW_FORM_ref_sig8) ? FixedFormSizes[Form] : 0;
+ if (FixedFormSize)
+ *OffsetPtr += FixedFormSize;
+ else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
+ CU)) {
+ // Restore the original offset.
+ *OffsetPtr = Offset;
+ return false;
+ }
}
+ return true;
}
bool
-DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu,
- uint32_t *offset_ptr) {
- DataExtractor debug_info_data = cu->getDebugInfoExtractor();
- const uint32_t cu_end_offset = cu->getNextCompileUnitOffset();
- const uint8_t cu_addr_size = cu->getAddressByteSize();
- uint32_t offset = *offset_ptr;
- if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) {
- Offset = offset;
-
- uint64_t abbrCode = debug_info_data.getULEB128(&offset);
-
- if (abbrCode) {
- AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
-
- if (AbbrevDecl) {
- uint16_t tag = AbbrevDecl->getTag();
-
- bool isCompileUnitTag = 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->getNumAttributes();
- for (uint32_t i = 0; i != numAttributes; ++i) {
- uint16_t attr = AbbrevDecl->getAttrByIndex(i);
- uint16_t form = AbbrevDecl->getFormByIndex(i);
-
- if (isCompileUnitTag &&
- ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
- DWARFFormValue form_value(form);
- if (form_value.extractValue(debug_info_data, &offset, cu)) {
- if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
- const_cast<DWARFCompileUnit*>(cu)
- ->setBaseAddress(form_value.getUnsigned());
- }
- } else {
- bool form_is_indirect = false;
- do {
- form_is_indirect = false;
- register uint32_t form_size = 0;
- switch (form) {
- // Blocks if inlined data that have a length field and the data
- // bytes // inlined in the .debug_info
- case DW_FORM_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:
- case DW_FORM_ref_addr:
- form_size = cu_addr_size;
- break;
-
- // 0 byte value
- 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_strp:
- form_size = 4;
- break;
-
- 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_str_index:
- case DW_FORM_GNU_addr_index:
- debug_info_data.getULEB128(&offset);
- break;
-
- case DW_FORM_indirect:
- form = debug_info_data.getULEB128(&offset);
- form_is_indirect = true;
- break;
-
- // FIXME: 64-bit for DWARF64.
- case DW_FORM_sec_offset:
- debug_info_data.getU32(offset_ptr);
- break;
-
- default:
- *offset_ptr = offset;
- return false;
- }
-
- offset += form_size;
- } while (form_is_indirect);
- }
- }
- *offset_ptr = offset;
- return true;
+DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *CU,
+ uint32_t *OffsetPtr) {
+ DataExtractor DebugInfoData = CU->getDebugInfoExtractor();
+ const uint32_t CUEndOffset = CU->getNextCompileUnitOffset();
+ Offset = *OffsetPtr;
+ if ((Offset >= CUEndOffset) || !DebugInfoData.isValidOffset(Offset))
+ return false;
+ uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
+ if (0 == AbbrCode) {
+ // NULL debug tag entry.
+ AbbrevDecl = NULL;
+ return true;
+ }
+ AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
+ if (0 == AbbrevDecl) {
+ // Restore the original offset.
+ *OffsetPtr = Offset;
+ return false;
+ }
+ bool IsCompileUnitTag = (AbbrevDecl->getTag() == DW_TAG_compile_unit);
+ if (IsCompileUnitTag)
+ const_cast<DWARFCompileUnit*>(CU)->setBaseAddress(0);
+
+ // Skip all data in the .debug_info for the attributes
+ for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) {
+ uint16_t Attr = AbbrevDecl->getAttrByIndex(i);
+ uint16_t Form = AbbrevDecl->getFormByIndex(i);
+
+ if (IsCompileUnitTag &&
+ ((Attr == DW_AT_entry_pc) || (Attr == DW_AT_low_pc))) {
+ DWARFFormValue FormValue(Form);
+ if (FormValue.extractValue(DebugInfoData, OffsetPtr, CU)) {
+ if (Attr == DW_AT_low_pc || Attr == DW_AT_entry_pc)
+ const_cast<DWARFCompileUnit*>(CU)
+ ->setBaseAddress(FormValue.getUnsigned());
}
- } else {
- AbbrevDecl = NULL;
- *offset_ptr = offset;
- return true; // NULL debug tag entry
+ } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
+ CU)) {
+ // Restore the original offset.
+ *OffsetPtr = Offset;
+ return false;
}
}
-
- return false;
+ return true;
}
bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h
index 9c1b2be0a7..9003591cbe 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.h
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.h
@@ -45,12 +45,17 @@ public:
uint32_t *offset_ptr, uint16_t attr, uint16_t form,
unsigned indent = 0) const;
- bool extractFast(const DWARFCompileUnit *cu, const uint8_t *fixed_form_sizes,
- uint32_t *offset_ptr);
+ /// Extracts a debug info entry, which is a child of a given compile unit,
+ /// starting at a given offset. If DIE can't be extracted, returns false and
+ /// doesn't change OffsetPtr.
+ bool extractFast(const DWARFCompileUnit *CU, const uint8_t *FixedFormSizes,
+ uint32_t *OffsetPtr);
/// Extract a debug info entry for a given compile unit from the
/// .debug_info and .debug_abbrev data starting at the given offset.
- bool extract(const DWARFCompileUnit *cu, uint32_t *offset_ptr);
+ /// If compile unit can't be parsed, returns false and doesn't change
+ /// OffsetPtr.
+ bool extract(const DWARFCompileUnit *CU, uint32_t *OffsetPtr);
uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; }
bool isNULL() const { return AbbrevDecl == 0; }