xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1  //===-- DWARFASTParser.cpp ------------------------------------------------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  
9  #include "DWARFASTParser.h"
10  #include "DWARFAttribute.h"
11  #include "DWARFDIE.h"
12  #include "SymbolFileDWARF.h"
13  
14  #include "lldb/Core/ValueObject.h"
15  #include "lldb/Symbol/SymbolFile.h"
16  #include "lldb/Target/StackFrame.h"
17  #include <optional>
18  
19  using namespace lldb;
20  using namespace lldb_private;
21  using namespace lldb_private::dwarf;
22  using namespace lldb_private::plugin::dwarf;
23  
24  std::optional<SymbolFile::ArrayInfo>
25  DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
26                                      const ExecutionContext *exe_ctx) {
27    SymbolFile::ArrayInfo array_info;
28    if (!parent_die)
29      return std::nullopt;
30  
31    for (DWARFDIE die : parent_die.children()) {
32      const dw_tag_t tag = die.Tag();
33      if (tag != DW_TAG_subrange_type)
34        continue;
35  
36      DWARFAttributes attributes = die.GetAttributes();
37      if (attributes.Size() == 0)
38        continue;
39  
40      uint64_t num_elements = 0;
41      uint64_t lower_bound = 0;
42      uint64_t upper_bound = 0;
43      bool upper_bound_valid = false;
44      for (size_t i = 0; i < attributes.Size(); ++i) {
45        const dw_attr_t attr = attributes.AttributeAtIndex(i);
46        DWARFFormValue form_value;
47        if (attributes.ExtractFormValueAtIndex(i, form_value)) {
48          switch (attr) {
49          case DW_AT_name:
50            break;
51  
52          case DW_AT_count:
53            if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
54              if (var_die.Tag() == DW_TAG_variable)
55                if (exe_ctx) {
56                  if (auto frame = exe_ctx->GetFrameSP()) {
57                    Status error;
58                    lldb::VariableSP var_sp;
59                    auto valobj_sp = frame->GetValueForVariableExpressionPath(
60                        var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
61                    if (valobj_sp) {
62                      num_elements = valobj_sp->GetValueAsUnsigned(0);
63                      break;
64                    }
65                  }
66                }
67            } else
68              num_elements = form_value.Unsigned();
69            break;
70  
71          case DW_AT_bit_stride:
72            array_info.bit_stride = form_value.Unsigned();
73            break;
74  
75          case DW_AT_byte_stride:
76            array_info.byte_stride = form_value.Unsigned();
77            break;
78  
79          case DW_AT_lower_bound:
80            lower_bound = form_value.Unsigned();
81            break;
82  
83          case DW_AT_upper_bound:
84            upper_bound_valid = true;
85            upper_bound = form_value.Unsigned();
86            break;
87  
88          default:
89            break;
90          }
91        }
92      }
93  
94      if (num_elements == 0) {
95        if (upper_bound_valid && upper_bound >= lower_bound)
96          num_elements = upper_bound - lower_bound + 1;
97      }
98  
99      array_info.element_orders.push_back(num_elements);
100    }
101    return array_info;
102  }
103  
104  Type *DWARFASTParser::GetTypeForDIE(const DWARFDIE &die) {
105    if (!die)
106      return nullptr;
107  
108    SymbolFileDWARF *dwarf = die.GetDWARF();
109    if (!dwarf)
110      return nullptr;
111  
112    DWARFAttributes attributes = die.GetAttributes();
113    if (attributes.Size() == 0)
114      return nullptr;
115  
116    DWARFFormValue type_die_form;
117    for (size_t i = 0; i < attributes.Size(); ++i) {
118      dw_attr_t attr = attributes.AttributeAtIndex(i);
119      DWARFFormValue form_value;
120  
121      if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
122        return dwarf->ResolveTypeUID(form_value.Reference(), true);
123    }
124  
125    return nullptr;
126  }
127  
128  AccessType
129  DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) {
130    switch (dwarf_accessibility) {
131    case DW_ACCESS_public:
132      return eAccessPublic;
133    case DW_ACCESS_private:
134      return eAccessPrivate;
135    case DW_ACCESS_protected:
136      return eAccessProtected;
137    default:
138      break;
139    }
140    return eAccessNone;
141  }
142