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; }
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) { #if TODO_REQUIRES_LLVM_ORG_SYNC // This code can go back in once llvm.org macros support is in the relevant // GitHub llvm branch. 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)); } #endif }
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; }