bool DWARFCompileUnit::Extract(const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr) { Clear(); m_offset = *offset_ptr; if (debug_info.ValidOffset(*offset_ptr)) { dw_offset_t abbr_offset; const DWARFDebugAbbrev *abbr = m_dwarf2Data->DebugAbbrev(); m_length = debug_info.GetDWARFInitialLength(offset_ptr); m_is_dwarf64 = debug_info.IsDWARF64(); m_version = debug_info.GetU16(offset_ptr); abbr_offset = debug_info.GetDWARFOffset(offset_ptr); m_addr_size = debug_info.GetU8 (offset_ptr); bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset()-1); bool version_OK = SymbolFileDWARF::SupportedVersion(m_version); bool abbr_offset_OK = m_dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset); bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8)); if (length_OK && version_OK && addr_size_OK && abbr_offset_OK && abbr != NULL) { m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset); return true; } // reset the offset to where we tried to parse from if anything went wrong *offset_ptr = m_offset; } return false; }
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); return header; }
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 case DW_FORM_addr: *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); return true; case DW_FORM_ref_addr: ref_addr_size = 4; if (cu) { 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 case DW_FORM_data1: case DW_FORM_flag: case DW_FORM_ref1: *offset_ptr += 1; return true; // 2 byte values case DW_FORM_data2: case DW_FORM_ref2: *offset_ptr += 2; return true; // 32 bit for DWARF 32, 64 for DWARF 64 case DW_FORM_sec_offset: case DW_FORM_strp: *offset_ptr += (cu->IsDWARF64() ? 8 : 4); return true; // 4 byte values case DW_FORM_data4: case DW_FORM_ref4: *offset_ptr += 4; return true; // 8 byte values case DW_FORM_data8: 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: case DW_FORM_ref_udata: debug_info_data.Skip_LEB128(offset_ptr); return true; 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; }
bool DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) { 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: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break; case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break; case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); // Set the string value to also be the data for inlined cstr form values only // so we can tell the difference between DW_FORM_string and DW_FORM_strp form // values; m_value.data = (uint8_t*)m_value.value.cstr; 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: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(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: ref_addr_size = 4; if (cu) { if (cu->GetVersion() <= 2) ref_addr_size = cu->GetAddressByteSize(); else ref_addr_size = 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: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(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; 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::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; }