1 //===-- DWARFDebugMacro.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "DWARFDebugMacro.h"
10 #include "SymbolFileDWARF.h"
12 #include "lldb/Symbol/DebugMacros.h"
14 #include "DWARFDataExtractor.h"
16 using namespace lldb_private
;
17 using namespace lldb_private::dwarf
;
18 using namespace lldb_private::plugin::dwarf
;
21 DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor
&debug_macro_data
,
22 lldb::offset_t
*offset
) {
23 DWARFDebugMacroHeader header
;
25 // Skip over the version field in header.
26 header
.m_version
= debug_macro_data
.GetU16(offset
);
28 uint8_t flags
= debug_macro_data
.GetU8(offset
);
29 header
.m_offset_is_64_bit
= (flags
& OFFSET_SIZE_MASK
) != 0;
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
);
35 header
.m_debug_line_offset
= debug_macro_data
.GetU32(offset
);
38 // Skip over the operands table if it is present.
39 if (flags
& OPCODE_OPERANDS_TABLE_MASK
)
40 SkipOperandTable(debug_macro_data
, offset
);
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
);
52 uint64_t operand_count
= debug_macro_data
.GetULEB128(offset
);
54 for (uint64_t j
= 0; j
< operand_count
; j
++) {
55 // Skip over the operand form
56 debug_macro_data
.GetU8(offset
);
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
));
69 lldb::offset_t new_offset
= 0, str_offset
= 0;
71 const char *macro_str
= nullptr;
72 uint32_t debug_line_file_idx
= 0;
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
));
83 debug_macros_sp
->AddMacroEntry(
84 DebugMacroEntry::CreateUndefEntry(line
, macro_str
));
86 case DW_MACRO_define_strp
:
87 case DW_MACRO_undef_strp
:
88 line
= debug_macro_data
.GetULEB128(offset
);
90 str_offset
= debug_macro_data
.GetU64(offset
);
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
));
98 debug_macros_sp
->AddMacroEntry(
99 DebugMacroEntry::CreateUndefEntry(line
, macro_str
));
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
));
107 case DW_MACRO_end_file
:
108 // This operation has no operands.
109 debug_macros_sp
->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
111 case DW_MACRO_import
:
112 if (offset_is_64_bit
)
113 new_offset
= debug_macro_data
.GetU64(offset
);
115 new_offset
= debug_macro_data
.GetU32(offset
);
116 debug_macros_sp
->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
117 sym_file_dwarf
->ParseDebugMacros(&new_offset
)));
120 // TODO: Add support for other standard operations.
121 // TODO: Provide mechanism to hook handling of non-standard/extension
125 type
= static_cast<llvm::dwarf::MacroEntryType
>(
126 debug_macro_data
.GetU8(offset
));