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
16using namespace lldb_private;
17using namespace lldb_private::dwarf;
18using namespace lldb_private::plugin::dwarf;
19
20DWARFDebugMacroHeader
21DWARFDebugMacroHeader::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_ptr: offset);
27
28 uint8_t flags = debug_macro_data.GetU8(offset_ptr: 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_ptr: offset);
34 else
35 header.m_debug_line_offset = debug_macro_data.GetU32(offset_ptr: 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
45void DWARFDebugMacroHeader::SkipOperandTable(
46 const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
47 uint8_t entry_count = debug_macro_data.GetU8(offset_ptr: offset);
48 for (uint8_t i = 0; i < entry_count; i++) {
49 // Skip over the opcode number.
50 debug_macro_data.GetU8(offset_ptr: offset);
51
52 uint64_t operand_count = debug_macro_data.GetULEB128(offset_ptr: offset);
53
54 for (uint64_t j = 0; j < operand_count; j++) {
55 // Skip over the operand form
56 debug_macro_data.GetU8(offset_ptr: offset);
57 }
58 }
59}
60
61void 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_ptr: 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_ptr: offset);
78 macro_str = debug_macro_data.GetCStr(offset_ptr: offset);
79 if (type == DW_MACRO_define)
80 debug_macros_sp->AddMacroEntry(
81 entry: DebugMacroEntry::CreateDefineEntry(line, str: macro_str));
82 else
83 debug_macros_sp->AddMacroEntry(
84 entry: DebugMacroEntry::CreateUndefEntry(line, str: macro_str));
85 break;
86 case DW_MACRO_define_strp:
87 case DW_MACRO_undef_strp:
88 line = debug_macro_data.GetULEB128(offset_ptr: offset);
89 if (offset_is_64_bit)
90 str_offset = debug_macro_data.GetU64(offset_ptr: offset);
91 else
92 str_offset = debug_macro_data.GetU32(offset_ptr: offset);
93 macro_str = debug_str_data.GetCStr(offset_ptr: &str_offset);
94 if (type == DW_MACRO_define_strp)
95 debug_macros_sp->AddMacroEntry(
96 entry: DebugMacroEntry::CreateDefineEntry(line, str: macro_str));
97 else
98 debug_macros_sp->AddMacroEntry(
99 entry: DebugMacroEntry::CreateUndefEntry(line, str: macro_str));
100 break;
101 case DW_MACRO_start_file:
102 line = debug_macro_data.GetULEB128(offset_ptr: offset);
103 debug_line_file_idx = debug_macro_data.GetULEB128(offset_ptr: offset);
104 debug_macros_sp->AddMacroEntry(
105 entry: 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(entry: DebugMacroEntry::CreateEndFileEntry());
110 break;
111 case DW_MACRO_import:
112 if (offset_is_64_bit)
113 new_offset = debug_macro_data.GetU64(offset_ptr: offset);
114 else
115 new_offset = debug_macro_data.GetU32(offset_ptr: offset);
116 debug_macros_sp->AddMacroEntry(entry: DebugMacroEntry::CreateIndirectEntry(
117 debug_macros_sp: sym_file_dwarf->ParseDebugMacros(offset: &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_ptr: offset));
127 }
128}
129

source code of lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp