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