xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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