180814287SRaphael Isemann //===-- DWARFDebugMacro.cpp -----------------------------------------------===//
2d8335e9aSSiva Chandra //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d8335e9aSSiva Chandra //
7d8335e9aSSiva Chandra //===----------------------------------------------------------------------===//
8d8335e9aSSiva Chandra
9d8335e9aSSiva Chandra #include "DWARFDebugMacro.h"
10d8335e9aSSiva Chandra #include "SymbolFileDWARF.h"
11d8335e9aSSiva Chandra
12d8335e9aSSiva Chandra #include "lldb/Symbol/DebugMacros.h"
13d8335e9aSSiva Chandra
14d8335e9aSSiva Chandra #include "DWARFDataExtractor.h"
15d8335e9aSSiva Chandra
16d8335e9aSSiva Chandra using namespace lldb_private;
17*ae869d44SShafik Yaghmour using namespace lldb_private::dwarf;
18d8335e9aSSiva Chandra
19d8335e9aSSiva Chandra DWARFDebugMacroHeader
ParseHeader(const DWARFDataExtractor & debug_macro_data,lldb::offset_t * offset)20b9c1b51eSKate Stone DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
21b9c1b51eSKate Stone lldb::offset_t *offset) {
22d8335e9aSSiva Chandra DWARFDebugMacroHeader header;
23d8335e9aSSiva Chandra
24d8335e9aSSiva Chandra // Skip over the version field in header.
25d8335e9aSSiva Chandra header.m_version = debug_macro_data.GetU16(offset);
26d8335e9aSSiva Chandra
27d8335e9aSSiva Chandra uint8_t flags = debug_macro_data.GetU8(offset);
28a6682a41SJonas Devlieghere header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0;
29d8335e9aSSiva Chandra
30b9c1b51eSKate Stone if (flags & DEBUG_LINE_OFFSET_MASK) {
31d8335e9aSSiva Chandra if (header.m_offset_is_64_bit)
32d8335e9aSSiva Chandra header.m_debug_line_offset = debug_macro_data.GetU64(offset);
33d8335e9aSSiva Chandra else
34d8335e9aSSiva Chandra header.m_debug_line_offset = debug_macro_data.GetU32(offset);
35d8335e9aSSiva Chandra }
36d8335e9aSSiva Chandra
37d8335e9aSSiva Chandra // Skip over the operands table if it is present.
38d8335e9aSSiva Chandra if (flags & OPCODE_OPERANDS_TABLE_MASK)
39d8335e9aSSiva Chandra SkipOperandTable(debug_macro_data, offset);
40d8335e9aSSiva Chandra
41d8335e9aSSiva Chandra return header;
42d8335e9aSSiva Chandra }
43d8335e9aSSiva Chandra
SkipOperandTable(const DWARFDataExtractor & debug_macro_data,lldb::offset_t * offset)44b9c1b51eSKate Stone void DWARFDebugMacroHeader::SkipOperandTable(
45b9c1b51eSKate Stone const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
46d8335e9aSSiva Chandra uint8_t entry_count = debug_macro_data.GetU8(offset);
47b9c1b51eSKate Stone for (uint8_t i = 0; i < entry_count; i++) {
48d8335e9aSSiva Chandra // Skip over the opcode number.
49d8335e9aSSiva Chandra debug_macro_data.GetU8(offset);
50d8335e9aSSiva Chandra
51d8335e9aSSiva Chandra uint64_t operand_count = debug_macro_data.GetULEB128(offset);
52d8335e9aSSiva Chandra
53b9c1b51eSKate Stone for (uint64_t j = 0; j < operand_count; j++) {
54d8335e9aSSiva Chandra // Skip over the operand form
55d8335e9aSSiva Chandra debug_macro_data.GetU8(offset);
56d8335e9aSSiva Chandra }
57d8335e9aSSiva Chandra }
58d8335e9aSSiva Chandra }
59d8335e9aSSiva Chandra
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)60b9c1b51eSKate Stone void DWARFDebugMacroEntry::ReadMacroEntries(
61b9c1b51eSKate Stone const DWARFDataExtractor &debug_macro_data,
62b9c1b51eSKate Stone const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
63b9c1b51eSKate Stone lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
64b9c1b51eSKate Stone DebugMacrosSP &debug_macros_sp) {
65b9c1b51eSKate Stone llvm::dwarf::MacroEntryType type =
66b9c1b51eSKate Stone static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
67b9c1b51eSKate Stone while (type != 0) {
68d8335e9aSSiva Chandra lldb::offset_t new_offset = 0, str_offset = 0;
69d8335e9aSSiva Chandra uint32_t line = 0;
70d8335e9aSSiva Chandra const char *macro_str = nullptr;
71d8335e9aSSiva Chandra uint32_t debug_line_file_idx = 0;
72d8335e9aSSiva Chandra
73b9c1b51eSKate Stone switch (type) {
74d8335e9aSSiva Chandra case DW_MACRO_define:
75d8335e9aSSiva Chandra case DW_MACRO_undef:
76d8335e9aSSiva Chandra line = debug_macro_data.GetULEB128(offset);
77d8335e9aSSiva Chandra macro_str = debug_macro_data.GetCStr(offset);
78d8335e9aSSiva Chandra if (type == DW_MACRO_define)
79b9c1b51eSKate Stone debug_macros_sp->AddMacroEntry(
80b9c1b51eSKate Stone DebugMacroEntry::CreateDefineEntry(line, macro_str));
81d8335e9aSSiva Chandra else
82b9c1b51eSKate Stone debug_macros_sp->AddMacroEntry(
83b9c1b51eSKate Stone DebugMacroEntry::CreateUndefEntry(line, macro_str));
84d8335e9aSSiva Chandra break;
851c0bf1baSAdrian Prantl case DW_MACRO_define_strp:
861c0bf1baSAdrian Prantl case DW_MACRO_undef_strp:
87d8335e9aSSiva Chandra line = debug_macro_data.GetULEB128(offset);
88d8335e9aSSiva Chandra if (offset_is_64_bit)
89d8335e9aSSiva Chandra str_offset = debug_macro_data.GetU64(offset);
90d8335e9aSSiva Chandra else
91d8335e9aSSiva Chandra str_offset = debug_macro_data.GetU32(offset);
92d8335e9aSSiva Chandra macro_str = debug_str_data.GetCStr(&str_offset);
931c0bf1baSAdrian Prantl if (type == DW_MACRO_define_strp)
94b9c1b51eSKate Stone debug_macros_sp->AddMacroEntry(
95b9c1b51eSKate Stone DebugMacroEntry::CreateDefineEntry(line, macro_str));
96d8335e9aSSiva Chandra else
97b9c1b51eSKate Stone debug_macros_sp->AddMacroEntry(
98b9c1b51eSKate Stone DebugMacroEntry::CreateUndefEntry(line, macro_str));
99d8335e9aSSiva Chandra break;
100d8335e9aSSiva Chandra case DW_MACRO_start_file:
101d8335e9aSSiva Chandra line = debug_macro_data.GetULEB128(offset);
102d8335e9aSSiva Chandra debug_line_file_idx = debug_macro_data.GetULEB128(offset);
103b9c1b51eSKate Stone debug_macros_sp->AddMacroEntry(
104b9c1b51eSKate Stone DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
105d8335e9aSSiva Chandra break;
106d8335e9aSSiva Chandra case DW_MACRO_end_file:
107d8335e9aSSiva Chandra // This operation has no operands.
108d8335e9aSSiva Chandra debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
109d8335e9aSSiva Chandra break;
1101c0bf1baSAdrian Prantl case DW_MACRO_import:
111d8335e9aSSiva Chandra if (offset_is_64_bit)
112d8335e9aSSiva Chandra new_offset = debug_macro_data.GetU64(offset);
113d8335e9aSSiva Chandra else
114d8335e9aSSiva Chandra new_offset = debug_macro_data.GetU32(offset);
115b9c1b51eSKate Stone debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
116b9c1b51eSKate Stone sym_file_dwarf->ParseDebugMacros(&new_offset)));
117d8335e9aSSiva Chandra break;
118d8335e9aSSiva Chandra default:
119d8335e9aSSiva Chandra // TODO: Add support for other standard operations.
120b9c1b51eSKate Stone // TODO: Provide mechanism to hook handling of non-standard/extension
121b9c1b51eSKate Stone // operands.
122d8335e9aSSiva Chandra return;
123d8335e9aSSiva Chandra }
124b9c1b51eSKate Stone type = static_cast<llvm::dwarf::MacroEntryType>(
125b9c1b51eSKate Stone debug_macro_data.GetU8(offset));
126d8335e9aSSiva Chandra }
127d8335e9aSSiva Chandra }
128