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