1 //===-- DWARFDebugMacro.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DWARFDebugMacro.h" 10 #include "SymbolFileDWARF.h" 11 12 #include "lldb/Symbol/DebugMacros.h" 13 14 #include "DWARFDataExtractor.h" 15 16 using namespace lldb_private; 17 using namespace lldb_private::dwarf; 18 19 DWARFDebugMacroHeader 20 DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, 21 lldb::offset_t *offset) { 22 DWARFDebugMacroHeader header; 23 24 // Skip over the version field in header. 25 header.m_version = debug_macro_data.GetU16(offset); 26 27 uint8_t flags = debug_macro_data.GetU8(offset); 28 header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0; 29 30 if (flags & DEBUG_LINE_OFFSET_MASK) { 31 if (header.m_offset_is_64_bit) 32 header.m_debug_line_offset = debug_macro_data.GetU64(offset); 33 else 34 header.m_debug_line_offset = debug_macro_data.GetU32(offset); 35 } 36 37 // Skip over the operands table if it is present. 38 if (flags & OPCODE_OPERANDS_TABLE_MASK) 39 SkipOperandTable(debug_macro_data, offset); 40 41 return header; 42 } 43 44 void DWARFDebugMacroHeader::SkipOperandTable( 45 const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) { 46 uint8_t entry_count = debug_macro_data.GetU8(offset); 47 for (uint8_t i = 0; i < entry_count; i++) { 48 // Skip over the opcode number. 49 debug_macro_data.GetU8(offset); 50 51 uint64_t operand_count = debug_macro_data.GetULEB128(offset); 52 53 for (uint64_t j = 0; j < operand_count; j++) { 54 // Skip over the operand form 55 debug_macro_data.GetU8(offset); 56 } 57 } 58 } 59 60 void DWARFDebugMacroEntry::ReadMacroEntries( 61 const DWARFDataExtractor &debug_macro_data, 62 const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit, 63 lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf, 64 DebugMacrosSP &debug_macros_sp) { 65 llvm::dwarf::MacroEntryType type = 66 static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset)); 67 while (type != 0) { 68 lldb::offset_t new_offset = 0, str_offset = 0; 69 uint32_t line = 0; 70 const char *macro_str = nullptr; 71 uint32_t debug_line_file_idx = 0; 72 73 switch (type) { 74 case DW_MACRO_define: 75 case DW_MACRO_undef: 76 line = debug_macro_data.GetULEB128(offset); 77 macro_str = debug_macro_data.GetCStr(offset); 78 if (type == DW_MACRO_define) 79 debug_macros_sp->AddMacroEntry( 80 DebugMacroEntry::CreateDefineEntry(line, macro_str)); 81 else 82 debug_macros_sp->AddMacroEntry( 83 DebugMacroEntry::CreateUndefEntry(line, macro_str)); 84 break; 85 case DW_MACRO_define_strp: 86 case DW_MACRO_undef_strp: 87 line = debug_macro_data.GetULEB128(offset); 88 if (offset_is_64_bit) 89 str_offset = debug_macro_data.GetU64(offset); 90 else 91 str_offset = debug_macro_data.GetU32(offset); 92 macro_str = debug_str_data.GetCStr(&str_offset); 93 if (type == DW_MACRO_define_strp) 94 debug_macros_sp->AddMacroEntry( 95 DebugMacroEntry::CreateDefineEntry(line, macro_str)); 96 else 97 debug_macros_sp->AddMacroEntry( 98 DebugMacroEntry::CreateUndefEntry(line, macro_str)); 99 break; 100 case DW_MACRO_start_file: 101 line = debug_macro_data.GetULEB128(offset); 102 debug_line_file_idx = debug_macro_data.GetULEB128(offset); 103 debug_macros_sp->AddMacroEntry( 104 DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx)); 105 break; 106 case DW_MACRO_end_file: 107 // This operation has no operands. 108 debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry()); 109 break; 110 case DW_MACRO_import: 111 if (offset_is_64_bit) 112 new_offset = debug_macro_data.GetU64(offset); 113 else 114 new_offset = debug_macro_data.GetU32(offset); 115 debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry( 116 sym_file_dwarf->ParseDebugMacros(&new_offset))); 117 break; 118 default: 119 // TODO: Add support for other standard operations. 120 // TODO: Provide mechanism to hook handling of non-standard/extension 121 // operands. 122 return; 123 } 124 type = static_cast<llvm::dwarf::MacroEntryType>( 125 debug_macro_data.GetU8(offset)); 126 } 127 } 128