DWARFDebugMacro.cpp revision 292932
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
17using namespace lldb_private;
18
19DWARFDebugMacroHeader
20DWARFDebugMacroHeader::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
45void
46DWARFDebugMacroHeader::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
64void
65DWARFDebugMacroEntry::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}
129