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