15ffd83dbSDimitry Andric //===-- DWARFDebugMacro.cpp -----------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "DWARFDebugMacro.h" 100b57cec5SDimitry Andric #include "SymbolFileDWARF.h" 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "lldb/Symbol/DebugMacros.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "DWARFDataExtractor.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric using namespace lldb_private; 1781ad6265SDimitry Andric using namespace lldb_private::dwarf; 18*5f757f3fSDimitry Andric using namespace lldb_private::plugin::dwarf; 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric DWARFDebugMacroHeader 210b57cec5SDimitry Andric DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, 220b57cec5SDimitry Andric lldb::offset_t *offset) { 230b57cec5SDimitry Andric DWARFDebugMacroHeader header; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric // Skip over the version field in header. 260b57cec5SDimitry Andric header.m_version = debug_macro_data.GetU16(offset); 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric uint8_t flags = debug_macro_data.GetU8(offset); 290b57cec5SDimitry Andric header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric if (flags & DEBUG_LINE_OFFSET_MASK) { 320b57cec5SDimitry Andric if (header.m_offset_is_64_bit) 330b57cec5SDimitry Andric header.m_debug_line_offset = debug_macro_data.GetU64(offset); 340b57cec5SDimitry Andric else 350b57cec5SDimitry Andric header.m_debug_line_offset = debug_macro_data.GetU32(offset); 360b57cec5SDimitry Andric } 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric // Skip over the operands table if it is present. 390b57cec5SDimitry Andric if (flags & OPCODE_OPERANDS_TABLE_MASK) 400b57cec5SDimitry Andric SkipOperandTable(debug_macro_data, offset); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric return header; 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void DWARFDebugMacroHeader::SkipOperandTable( 460b57cec5SDimitry Andric const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) { 470b57cec5SDimitry Andric uint8_t entry_count = debug_macro_data.GetU8(offset); 480b57cec5SDimitry Andric for (uint8_t i = 0; i < entry_count; i++) { 490b57cec5SDimitry Andric // Skip over the opcode number. 500b57cec5SDimitry Andric debug_macro_data.GetU8(offset); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric uint64_t operand_count = debug_macro_data.GetULEB128(offset); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric for (uint64_t j = 0; j < operand_count; j++) { 550b57cec5SDimitry Andric // Skip over the operand form 560b57cec5SDimitry Andric debug_macro_data.GetU8(offset); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric void DWARFDebugMacroEntry::ReadMacroEntries( 620b57cec5SDimitry Andric const DWARFDataExtractor &debug_macro_data, 630b57cec5SDimitry Andric const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, 640b57cec5SDimitry Andric lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf, 650b57cec5SDimitry Andric DebugMacrosSP &debug_macros_sp) { 660b57cec5SDimitry Andric llvm::dwarf::MacroEntryType type = 670b57cec5SDimitry Andric static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset)); 680b57cec5SDimitry Andric while (type != 0) { 690b57cec5SDimitry Andric lldb::offset_t new_offset = 0, str_offset = 0; 700b57cec5SDimitry Andric uint32_t line = 0; 710b57cec5SDimitry Andric const char *macro_str = nullptr; 720b57cec5SDimitry Andric uint32_t debug_line_file_idx = 0; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric switch (type) { 750b57cec5SDimitry Andric case DW_MACRO_define: 760b57cec5SDimitry Andric case DW_MACRO_undef: 770b57cec5SDimitry Andric line = debug_macro_data.GetULEB128(offset); 780b57cec5SDimitry Andric macro_str = debug_macro_data.GetCStr(offset); 790b57cec5SDimitry Andric if (type == DW_MACRO_define) 800b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry( 810b57cec5SDimitry Andric DebugMacroEntry::CreateDefineEntry(line, macro_str)); 820b57cec5SDimitry Andric else 830b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry( 840b57cec5SDimitry Andric DebugMacroEntry::CreateUndefEntry(line, macro_str)); 850b57cec5SDimitry Andric break; 860b57cec5SDimitry Andric case DW_MACRO_define_strp: 870b57cec5SDimitry Andric case DW_MACRO_undef_strp: 880b57cec5SDimitry Andric line = debug_macro_data.GetULEB128(offset); 890b57cec5SDimitry Andric if (offset_is_64_bit) 900b57cec5SDimitry Andric str_offset = debug_macro_data.GetU64(offset); 910b57cec5SDimitry Andric else 920b57cec5SDimitry Andric str_offset = debug_macro_data.GetU32(offset); 930b57cec5SDimitry Andric macro_str = debug_str_data.GetCStr(&str_offset); 940b57cec5SDimitry Andric if (type == DW_MACRO_define_strp) 950b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry( 960b57cec5SDimitry Andric DebugMacroEntry::CreateDefineEntry(line, macro_str)); 970b57cec5SDimitry Andric else 980b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry( 990b57cec5SDimitry Andric DebugMacroEntry::CreateUndefEntry(line, macro_str)); 1000b57cec5SDimitry Andric break; 1010b57cec5SDimitry Andric case DW_MACRO_start_file: 1020b57cec5SDimitry Andric line = debug_macro_data.GetULEB128(offset); 1030b57cec5SDimitry Andric debug_line_file_idx = debug_macro_data.GetULEB128(offset); 1040b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry( 1050b57cec5SDimitry Andric DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx)); 1060b57cec5SDimitry Andric break; 1070b57cec5SDimitry Andric case DW_MACRO_end_file: 1080b57cec5SDimitry Andric // This operation has no operands. 1090b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry()); 1100b57cec5SDimitry Andric break; 1110b57cec5SDimitry Andric case DW_MACRO_import: 1120b57cec5SDimitry Andric if (offset_is_64_bit) 1130b57cec5SDimitry Andric new_offset = debug_macro_data.GetU64(offset); 1140b57cec5SDimitry Andric else 1150b57cec5SDimitry Andric new_offset = debug_macro_data.GetU32(offset); 1160b57cec5SDimitry Andric debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry( 1170b57cec5SDimitry Andric sym_file_dwarf->ParseDebugMacros(&new_offset))); 1180b57cec5SDimitry Andric break; 1190b57cec5SDimitry Andric default: 1200b57cec5SDimitry Andric // TODO: Add support for other standard operations. 1210b57cec5SDimitry Andric // TODO: Provide mechanism to hook handling of non-standard/extension 1220b57cec5SDimitry Andric // operands. 1230b57cec5SDimitry Andric return; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric type = static_cast<llvm::dwarf::MacroEntryType>( 1260b57cec5SDimitry Andric debug_macro_data.GetU8(offset)); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric } 129