]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
Vendor import of stripped lldb trunk r256633:
[FreeBSD/FreeBSD.git] / source / Plugins / SymbolFile / DWARF / DWARFDebugMacro.cpp
1 //===-- DWARFDebugMacro.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "DWARFDebugMacro.h"
11 #include "SymbolFileDWARF.h"
12
13 #include "lldb/Symbol/DebugMacros.h"
14
15 #include "DWARFDataExtractor.h"
16
17 using namespace lldb_private;
18
19 DWARFDebugMacroHeader
20 DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
21 {
22     DWARFDebugMacroHeader header;
23
24     // Skip over the version field in header.
25     header.m_version = debug_macro_data.GetU16(offset);
26
27     uint8_t flags = debug_macro_data.GetU8(offset);
28     header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false;
29
30     if (flags & DEBUG_LINE_OFFSET_MASK)
31     {
32         if (header.m_offset_is_64_bit)
33             header.m_debug_line_offset = debug_macro_data.GetU64(offset);
34         else
35             header.m_debug_line_offset = debug_macro_data.GetU32(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
46 DWARFDebugMacroHeader::SkipOperandTable(const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset)
47 {
48     uint8_t entry_count = debug_macro_data.GetU8(offset);
49     for (uint8_t i = 0; i < entry_count; i++)
50     {
51         // Skip over the opcode number.
52         debug_macro_data.GetU8(offset);
53
54         uint64_t operand_count = debug_macro_data.GetULEB128(offset);
55
56         for (uint64_t j = 0; j < operand_count; j++)
57         {
58             // Skip over the operand form
59             debug_macro_data.GetU8(offset);
60         }
61     }
62 }
63
64 void
65 DWARFDebugMacroEntry::ReadMacroEntries(const DWARFDataExtractor &debug_macro_data,
66                                        const DWARFDataExtractor &debug_str_data,
67                                        const bool offset_is_64_bit,
68                                        lldb::offset_t *offset,
69                                        SymbolFileDWARF *sym_file_dwarf,
70                                        DebugMacrosSP &debug_macros_sp)
71 {
72     llvm::dwarf::MacroEntryType type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
73     while (type != 0)
74     {
75         lldb::offset_t new_offset = 0, str_offset = 0;
76         uint32_t line = 0;
77         const char *macro_str = nullptr;
78         uint32_t debug_line_file_idx = 0;
79
80         switch (type)
81         {
82             case DW_MACRO_define:
83             case DW_MACRO_undef:
84                 line = debug_macro_data.GetULEB128(offset);
85                 macro_str = debug_macro_data.GetCStr(offset);
86                 if (type == DW_MACRO_define)
87                     debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str));
88                 else
89                     debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str));
90                 break;
91             case DW_MACRO_define_indirect:
92             case DW_MACRO_undef_indirect:
93                 line = debug_macro_data.GetULEB128(offset);
94                 if (offset_is_64_bit)
95                     str_offset = debug_macro_data.GetU64(offset);
96                 else
97                     str_offset = debug_macro_data.GetU32(offset);
98                 macro_str = debug_str_data.GetCStr(&str_offset);
99                 if (type == DW_MACRO_define_indirect)
100                     debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateDefineEntry(line, macro_str));
101                 else
102                     debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateUndefEntry(line, macro_str));
103                 break;
104             case DW_MACRO_start_file:
105                 line = debug_macro_data.GetULEB128(offset);
106                 debug_line_file_idx = debug_macro_data.GetULEB128(offset);
107                 debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
108                 break;
109             case DW_MACRO_end_file:
110                 // This operation has no operands.
111                 debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
112                 break;
113             case DW_MACRO_transparent_include:
114                 if (offset_is_64_bit)
115                     new_offset = debug_macro_data.GetU64(offset);
116                 else
117                     new_offset = debug_macro_data.GetU32(offset);
118                 debug_macros_sp->AddMacroEntry(
119                     DebugMacroEntry::CreateIndirectEntry(sym_file_dwarf->ParseDebugMacros(&new_offset)));
120                 break;
121             default:
122                 // TODO: Add support for other standard operations.
123                 // TODO: Provide mechanism to hook handling of non-standard/extension operands.
124                 return;
125         }
126         type = static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
127     }
128 }