1dda28197Spatrick //===-- DWARFDebugMacro.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "DWARFDebugMacro.h"
10061da546Spatrick #include "SymbolFileDWARF.h"
11061da546Spatrick
12061da546Spatrick #include "lldb/Symbol/DebugMacros.h"
13061da546Spatrick
14061da546Spatrick #include "DWARFDataExtractor.h"
15061da546Spatrick
16061da546Spatrick using namespace lldb_private;
17*f6aab3d8Srobert using namespace lldb_private::dwarf;
18061da546Spatrick
19061da546Spatrick DWARFDebugMacroHeader
ParseHeader(const DWARFDataExtractor & debug_macro_data,lldb::offset_t * offset)20061da546Spatrick DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
21061da546Spatrick lldb::offset_t *offset) {
22061da546Spatrick DWARFDebugMacroHeader header;
23061da546Spatrick
24061da546Spatrick // Skip over the version field in header.
25061da546Spatrick header.m_version = debug_macro_data.GetU16(offset);
26061da546Spatrick
27061da546Spatrick uint8_t flags = debug_macro_data.GetU8(offset);
28061da546Spatrick header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0;
29061da546Spatrick
30061da546Spatrick if (flags & DEBUG_LINE_OFFSET_MASK) {
31061da546Spatrick if (header.m_offset_is_64_bit)
32061da546Spatrick header.m_debug_line_offset = debug_macro_data.GetU64(offset);
33061da546Spatrick else
34061da546Spatrick header.m_debug_line_offset = debug_macro_data.GetU32(offset);
35061da546Spatrick }
36061da546Spatrick
37061da546Spatrick // Skip over the operands table if it is present.
38061da546Spatrick if (flags & OPCODE_OPERANDS_TABLE_MASK)
39061da546Spatrick SkipOperandTable(debug_macro_data, offset);
40061da546Spatrick
41061da546Spatrick return header;
42061da546Spatrick }
43061da546Spatrick
SkipOperandTable(const DWARFDataExtractor & debug_macro_data,lldb::offset_t * offset)44061da546Spatrick void DWARFDebugMacroHeader::SkipOperandTable(
45061da546Spatrick const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
46061da546Spatrick uint8_t entry_count = debug_macro_data.GetU8(offset);
47061da546Spatrick for (uint8_t i = 0; i < entry_count; i++) {
48061da546Spatrick // Skip over the opcode number.
49061da546Spatrick debug_macro_data.GetU8(offset);
50061da546Spatrick
51061da546Spatrick uint64_t operand_count = debug_macro_data.GetULEB128(offset);
52061da546Spatrick
53061da546Spatrick for (uint64_t j = 0; j < operand_count; j++) {
54061da546Spatrick // Skip over the operand form
55061da546Spatrick debug_macro_data.GetU8(offset);
56061da546Spatrick }
57061da546Spatrick }
58061da546Spatrick }
59061da546Spatrick
ReadMacroEntries(const DWARFDataExtractor & debug_macro_data,const DWARFDataExtractor & debug_str_data,const bool offset_is_64_bit,lldb::offset_t * offset,SymbolFileDWARF * sym_file_dwarf,DebugMacrosSP & debug_macros_sp)60061da546Spatrick void DWARFDebugMacroEntry::ReadMacroEntries(
61061da546Spatrick const DWARFDataExtractor &debug_macro_data,
62061da546Spatrick const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
63061da546Spatrick lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
64061da546Spatrick DebugMacrosSP &debug_macros_sp) {
65061da546Spatrick llvm::dwarf::MacroEntryType type =
66061da546Spatrick static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
67061da546Spatrick while (type != 0) {
68061da546Spatrick lldb::offset_t new_offset = 0, str_offset = 0;
69061da546Spatrick uint32_t line = 0;
70061da546Spatrick const char *macro_str = nullptr;
71061da546Spatrick uint32_t debug_line_file_idx = 0;
72061da546Spatrick
73061da546Spatrick switch (type) {
74061da546Spatrick case DW_MACRO_define:
75061da546Spatrick case DW_MACRO_undef:
76061da546Spatrick line = debug_macro_data.GetULEB128(offset);
77061da546Spatrick macro_str = debug_macro_data.GetCStr(offset);
78061da546Spatrick if (type == DW_MACRO_define)
79061da546Spatrick debug_macros_sp->AddMacroEntry(
80061da546Spatrick DebugMacroEntry::CreateDefineEntry(line, macro_str));
81061da546Spatrick else
82061da546Spatrick debug_macros_sp->AddMacroEntry(
83061da546Spatrick DebugMacroEntry::CreateUndefEntry(line, macro_str));
84061da546Spatrick break;
85061da546Spatrick case DW_MACRO_define_strp:
86061da546Spatrick case DW_MACRO_undef_strp:
87061da546Spatrick line = debug_macro_data.GetULEB128(offset);
88061da546Spatrick if (offset_is_64_bit)
89061da546Spatrick str_offset = debug_macro_data.GetU64(offset);
90061da546Spatrick else
91061da546Spatrick str_offset = debug_macro_data.GetU32(offset);
92061da546Spatrick macro_str = debug_str_data.GetCStr(&str_offset);
93061da546Spatrick if (type == DW_MACRO_define_strp)
94061da546Spatrick debug_macros_sp->AddMacroEntry(
95061da546Spatrick DebugMacroEntry::CreateDefineEntry(line, macro_str));
96061da546Spatrick else
97061da546Spatrick debug_macros_sp->AddMacroEntry(
98061da546Spatrick DebugMacroEntry::CreateUndefEntry(line, macro_str));
99061da546Spatrick break;
100061da546Spatrick case DW_MACRO_start_file:
101061da546Spatrick line = debug_macro_data.GetULEB128(offset);
102061da546Spatrick debug_line_file_idx = debug_macro_data.GetULEB128(offset);
103061da546Spatrick debug_macros_sp->AddMacroEntry(
104061da546Spatrick DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
105061da546Spatrick break;
106061da546Spatrick case DW_MACRO_end_file:
107061da546Spatrick // This operation has no operands.
108061da546Spatrick debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
109061da546Spatrick break;
110061da546Spatrick case DW_MACRO_import:
111061da546Spatrick if (offset_is_64_bit)
112061da546Spatrick new_offset = debug_macro_data.GetU64(offset);
113061da546Spatrick else
114061da546Spatrick new_offset = debug_macro_data.GetU32(offset);
115061da546Spatrick debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
116061da546Spatrick sym_file_dwarf->ParseDebugMacros(&new_offset)));
117061da546Spatrick break;
118061da546Spatrick default:
119061da546Spatrick // TODO: Add support for other standard operations.
120061da546Spatrick // TODO: Provide mechanism to hook handling of non-standard/extension
121061da546Spatrick // operands.
122061da546Spatrick return;
123061da546Spatrick }
124061da546Spatrick type = static_cast<llvm::dwarf::MacroEntryType>(
125061da546Spatrick debug_macro_data.GetU8(offset));
126061da546Spatrick }
127061da546Spatrick }
128