xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
181ad6265SDimitry Andric //===-- DWARFASTParser.cpp ------------------------------------------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric 
981ad6265SDimitry Andric #include "DWARFASTParser.h"
1081ad6265SDimitry Andric #include "DWARFAttribute.h"
1181ad6265SDimitry Andric #include "DWARFDIE.h"
12*5f757f3fSDimitry Andric #include "SymbolFileDWARF.h"
1381ad6265SDimitry Andric 
1481ad6265SDimitry Andric #include "lldb/Core/ValueObject.h"
1581ad6265SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
1681ad6265SDimitry Andric #include "lldb/Target/StackFrame.h"
17bdd1243dSDimitry Andric #include <optional>
1881ad6265SDimitry Andric 
1981ad6265SDimitry Andric using namespace lldb;
2081ad6265SDimitry Andric using namespace lldb_private;
2181ad6265SDimitry Andric using namespace lldb_private::dwarf;
22*5f757f3fSDimitry Andric using namespace lldb_private::plugin::dwarf;
2381ad6265SDimitry Andric 
24bdd1243dSDimitry Andric std::optional<SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE & parent_die,const ExecutionContext * exe_ctx)2581ad6265SDimitry Andric DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
2681ad6265SDimitry Andric                                     const ExecutionContext *exe_ctx) {
2781ad6265SDimitry Andric   SymbolFile::ArrayInfo array_info;
2881ad6265SDimitry Andric   if (!parent_die)
29bdd1243dSDimitry Andric     return std::nullopt;
3081ad6265SDimitry Andric 
3181ad6265SDimitry Andric   for (DWARFDIE die : parent_die.children()) {
3281ad6265SDimitry Andric     const dw_tag_t tag = die.Tag();
3381ad6265SDimitry Andric     if (tag != DW_TAG_subrange_type)
3481ad6265SDimitry Andric       continue;
3581ad6265SDimitry Andric 
3606c3fb27SDimitry Andric     DWARFAttributes attributes = die.GetAttributes();
3706c3fb27SDimitry Andric     if (attributes.Size() == 0)
3806c3fb27SDimitry Andric       continue;
3906c3fb27SDimitry Andric 
4081ad6265SDimitry Andric     uint64_t num_elements = 0;
4181ad6265SDimitry Andric     uint64_t lower_bound = 0;
4281ad6265SDimitry Andric     uint64_t upper_bound = 0;
4381ad6265SDimitry Andric     bool upper_bound_valid = false;
4406c3fb27SDimitry Andric     for (size_t i = 0; i < attributes.Size(); ++i) {
4581ad6265SDimitry Andric       const dw_attr_t attr = attributes.AttributeAtIndex(i);
4681ad6265SDimitry Andric       DWARFFormValue form_value;
4781ad6265SDimitry Andric       if (attributes.ExtractFormValueAtIndex(i, form_value)) {
4881ad6265SDimitry Andric         switch (attr) {
4981ad6265SDimitry Andric         case DW_AT_name:
5081ad6265SDimitry Andric           break;
5181ad6265SDimitry Andric 
5281ad6265SDimitry Andric         case DW_AT_count:
5381ad6265SDimitry Andric           if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
5481ad6265SDimitry Andric             if (var_die.Tag() == DW_TAG_variable)
5581ad6265SDimitry Andric               if (exe_ctx) {
5681ad6265SDimitry Andric                 if (auto frame = exe_ctx->GetFrameSP()) {
5781ad6265SDimitry Andric                   Status error;
5881ad6265SDimitry Andric                   lldb::VariableSP var_sp;
5981ad6265SDimitry Andric                   auto valobj_sp = frame->GetValueForVariableExpressionPath(
6081ad6265SDimitry Andric                       var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
6181ad6265SDimitry Andric                   if (valobj_sp) {
6281ad6265SDimitry Andric                     num_elements = valobj_sp->GetValueAsUnsigned(0);
6381ad6265SDimitry Andric                     break;
6481ad6265SDimitry Andric                   }
6581ad6265SDimitry Andric                 }
6681ad6265SDimitry Andric               }
6781ad6265SDimitry Andric           } else
6881ad6265SDimitry Andric             num_elements = form_value.Unsigned();
6981ad6265SDimitry Andric           break;
7081ad6265SDimitry Andric 
7181ad6265SDimitry Andric         case DW_AT_bit_stride:
7281ad6265SDimitry Andric           array_info.bit_stride = form_value.Unsigned();
7381ad6265SDimitry Andric           break;
7481ad6265SDimitry Andric 
7581ad6265SDimitry Andric         case DW_AT_byte_stride:
7681ad6265SDimitry Andric           array_info.byte_stride = form_value.Unsigned();
7781ad6265SDimitry Andric           break;
7881ad6265SDimitry Andric 
7981ad6265SDimitry Andric         case DW_AT_lower_bound:
8081ad6265SDimitry Andric           lower_bound = form_value.Unsigned();
8181ad6265SDimitry Andric           break;
8281ad6265SDimitry Andric 
8381ad6265SDimitry Andric         case DW_AT_upper_bound:
8481ad6265SDimitry Andric           upper_bound_valid = true;
8581ad6265SDimitry Andric           upper_bound = form_value.Unsigned();
8681ad6265SDimitry Andric           break;
8781ad6265SDimitry Andric 
8881ad6265SDimitry Andric         default:
8981ad6265SDimitry Andric           break;
9081ad6265SDimitry Andric         }
9181ad6265SDimitry Andric       }
9281ad6265SDimitry Andric     }
9381ad6265SDimitry Andric 
9481ad6265SDimitry Andric     if (num_elements == 0) {
9581ad6265SDimitry Andric       if (upper_bound_valid && upper_bound >= lower_bound)
9681ad6265SDimitry Andric         num_elements = upper_bound - lower_bound + 1;
9781ad6265SDimitry Andric     }
9881ad6265SDimitry Andric 
9981ad6265SDimitry Andric     array_info.element_orders.push_back(num_elements);
10081ad6265SDimitry Andric   }
10181ad6265SDimitry Andric   return array_info;
10281ad6265SDimitry Andric }
10381ad6265SDimitry Andric 
GetTypeForDIE(const DWARFDIE & die)104*5f757f3fSDimitry Andric Type *DWARFASTParser::GetTypeForDIE(const DWARFDIE &die) {
105*5f757f3fSDimitry Andric   if (!die)
106*5f757f3fSDimitry Andric     return nullptr;
107*5f757f3fSDimitry Andric 
108*5f757f3fSDimitry Andric   SymbolFileDWARF *dwarf = die.GetDWARF();
109*5f757f3fSDimitry Andric   if (!dwarf)
110*5f757f3fSDimitry Andric     return nullptr;
111*5f757f3fSDimitry Andric 
112*5f757f3fSDimitry Andric   DWARFAttributes attributes = die.GetAttributes();
113*5f757f3fSDimitry Andric   if (attributes.Size() == 0)
114*5f757f3fSDimitry Andric     return nullptr;
115*5f757f3fSDimitry Andric 
116*5f757f3fSDimitry Andric   DWARFFormValue type_die_form;
117*5f757f3fSDimitry Andric   for (size_t i = 0; i < attributes.Size(); ++i) {
118*5f757f3fSDimitry Andric     dw_attr_t attr = attributes.AttributeAtIndex(i);
119*5f757f3fSDimitry Andric     DWARFFormValue form_value;
120*5f757f3fSDimitry Andric 
121*5f757f3fSDimitry Andric     if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
122*5f757f3fSDimitry Andric       return dwarf->ResolveTypeUID(form_value.Reference(), true);
123*5f757f3fSDimitry Andric   }
124*5f757f3fSDimitry Andric 
125*5f757f3fSDimitry Andric   return nullptr;
126*5f757f3fSDimitry Andric }
127*5f757f3fSDimitry Andric 
12881ad6265SDimitry Andric AccessType
GetAccessTypeFromDWARF(uint32_t dwarf_accessibility)12981ad6265SDimitry Andric DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) {
13081ad6265SDimitry Andric   switch (dwarf_accessibility) {
13181ad6265SDimitry Andric   case DW_ACCESS_public:
13281ad6265SDimitry Andric     return eAccessPublic;
13381ad6265SDimitry Andric   case DW_ACCESS_private:
13481ad6265SDimitry Andric     return eAccessPrivate;
13581ad6265SDimitry Andric   case DW_ACCESS_protected:
13681ad6265SDimitry Andric     return eAccessProtected;
13781ad6265SDimitry Andric   default:
13881ad6265SDimitry Andric     break;
13981ad6265SDimitry Andric   }
14081ad6265SDimitry Andric   return eAccessNone;
14181ad6265SDimitry Andric }
142