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