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::(const DWARFDataExtractor &debug_macro_data, |
22 | lldb::offset_t *offset) { |
23 | DWARFDebugMacroHeader ; |
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 | |
45 | void 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 | |
61 | void DWARFDebugMacroEntry::( |
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 | |