DWARFDebugMacro.cpp revision 341825
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,
21                                   lldb::offset_t *offset) {
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    if (header.m_offset_is_64_bit)
32      header.m_debug_line_offset = debug_macro_data.GetU64(offset);
33    else
34      header.m_debug_line_offset = debug_macro_data.GetU32(offset);
35  }
36
37  // Skip over the operands table if it is present.
38  if (flags & OPCODE_OPERANDS_TABLE_MASK)
39    SkipOperandTable(debug_macro_data, offset);
40
41  return header;
42}
43
44void DWARFDebugMacroHeader::SkipOperandTable(
45    const DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset) {
46  uint8_t entry_count = debug_macro_data.GetU8(offset);
47  for (uint8_t i = 0; i < entry_count; i++) {
48    // Skip over the opcode number.
49    debug_macro_data.GetU8(offset);
50
51    uint64_t operand_count = debug_macro_data.GetULEB128(offset);
52
53    for (uint64_t j = 0; j < operand_count; j++) {
54      // Skip over the operand form
55      debug_macro_data.GetU8(offset);
56    }
57  }
58}
59
60void DWARFDebugMacroEntry::ReadMacroEntries(
61    const DWARFDataExtractor &debug_macro_data,
62    const DWARFDataExtractor &debug_str_data, const bool offset_is_64_bit,
63    lldb::offset_t *offset, SymbolFileDWARF *sym_file_dwarf,
64    DebugMacrosSP &debug_macros_sp) {
65  llvm::dwarf::MacroEntryType type =
66      static_cast<llvm::dwarf::MacroEntryType>(debug_macro_data.GetU8(offset));
67  while (type != 0) {
68    lldb::offset_t new_offset = 0, str_offset = 0;
69    uint32_t line = 0;
70    const char *macro_str = nullptr;
71    uint32_t debug_line_file_idx = 0;
72
73    switch (type) {
74    case DW_MACRO_define:
75    case DW_MACRO_undef:
76      line = debug_macro_data.GetULEB128(offset);
77      macro_str = debug_macro_data.GetCStr(offset);
78      if (type == DW_MACRO_define)
79        debug_macros_sp->AddMacroEntry(
80            DebugMacroEntry::CreateDefineEntry(line, macro_str));
81      else
82        debug_macros_sp->AddMacroEntry(
83            DebugMacroEntry::CreateUndefEntry(line, macro_str));
84      break;
85    case DW_MACRO_define_strp:
86    case DW_MACRO_undef_strp:
87      line = debug_macro_data.GetULEB128(offset);
88      if (offset_is_64_bit)
89        str_offset = debug_macro_data.GetU64(offset);
90      else
91        str_offset = debug_macro_data.GetU32(offset);
92      macro_str = debug_str_data.GetCStr(&str_offset);
93      if (type == DW_MACRO_define_strp)
94        debug_macros_sp->AddMacroEntry(
95            DebugMacroEntry::CreateDefineEntry(line, macro_str));
96      else
97        debug_macros_sp->AddMacroEntry(
98            DebugMacroEntry::CreateUndefEntry(line, macro_str));
99      break;
100    case DW_MACRO_start_file:
101      line = debug_macro_data.GetULEB128(offset);
102      debug_line_file_idx = debug_macro_data.GetULEB128(offset);
103      debug_macros_sp->AddMacroEntry(
104          DebugMacroEntry::CreateStartFileEntry(line, debug_line_file_idx));
105      break;
106    case DW_MACRO_end_file:
107      // This operation has no operands.
108      debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateEndFileEntry());
109      break;
110    case DW_MACRO_import:
111      if (offset_is_64_bit)
112        new_offset = debug_macro_data.GetU64(offset);
113      else
114        new_offset = debug_macro_data.GetU32(offset);
115      debug_macros_sp->AddMacroEntry(DebugMacroEntry::CreateIndirectEntry(
116          sym_file_dwarf->ParseDebugMacros(&new_offset)));
117      break;
118    default:
119      // TODO: Add support for other standard operations.
120      // TODO: Provide mechanism to hook handling of non-standard/extension
121      // operands.
122      return;
123    }
124    type = static_cast<llvm::dwarf::MacroEntryType>(
125        debug_macro_data.GetU8(offset));
126  }
127}
128