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" 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric #include "lldb/Core/ValueObject.h" 1481ad6265SDimitry Andric #include "lldb/Symbol/SymbolFile.h" 1581ad6265SDimitry Andric #include "lldb/Target/StackFrame.h" 16*bdd1243dSDimitry Andric #include <optional> 1781ad6265SDimitry Andric 1881ad6265SDimitry Andric using namespace lldb; 1981ad6265SDimitry Andric using namespace lldb_private; 2081ad6265SDimitry Andric using namespace lldb_private::dwarf; 2181ad6265SDimitry Andric 22*bdd1243dSDimitry Andric std::optional<SymbolFile::ArrayInfo> 2381ad6265SDimitry Andric DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, 2481ad6265SDimitry Andric const ExecutionContext *exe_ctx) { 2581ad6265SDimitry Andric SymbolFile::ArrayInfo array_info; 2681ad6265SDimitry Andric if (!parent_die) 27*bdd1243dSDimitry Andric return std::nullopt; 2881ad6265SDimitry Andric 2981ad6265SDimitry Andric for (DWARFDIE die : parent_die.children()) { 3081ad6265SDimitry Andric const dw_tag_t tag = die.Tag(); 3181ad6265SDimitry Andric if (tag != DW_TAG_subrange_type) 3281ad6265SDimitry Andric continue; 3381ad6265SDimitry Andric 3481ad6265SDimitry Andric DWARFAttributes attributes; 3581ad6265SDimitry Andric const size_t num_child_attributes = die.GetAttributes(attributes); 3681ad6265SDimitry Andric if (num_child_attributes > 0) { 3781ad6265SDimitry Andric uint64_t num_elements = 0; 3881ad6265SDimitry Andric uint64_t lower_bound = 0; 3981ad6265SDimitry Andric uint64_t upper_bound = 0; 4081ad6265SDimitry Andric bool upper_bound_valid = false; 4181ad6265SDimitry Andric uint32_t i; 4281ad6265SDimitry Andric for (i = 0; i < num_child_attributes; ++i) { 4381ad6265SDimitry Andric const dw_attr_t attr = attributes.AttributeAtIndex(i); 4481ad6265SDimitry Andric DWARFFormValue form_value; 4581ad6265SDimitry Andric if (attributes.ExtractFormValueAtIndex(i, form_value)) { 4681ad6265SDimitry Andric switch (attr) { 4781ad6265SDimitry Andric case DW_AT_name: 4881ad6265SDimitry Andric break; 4981ad6265SDimitry Andric 5081ad6265SDimitry Andric case DW_AT_count: 5181ad6265SDimitry Andric if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { 5281ad6265SDimitry Andric if (var_die.Tag() == DW_TAG_variable) 5381ad6265SDimitry Andric if (exe_ctx) { 5481ad6265SDimitry Andric if (auto frame = exe_ctx->GetFrameSP()) { 5581ad6265SDimitry Andric Status error; 5681ad6265SDimitry Andric lldb::VariableSP var_sp; 5781ad6265SDimitry Andric auto valobj_sp = frame->GetValueForVariableExpressionPath( 5881ad6265SDimitry Andric var_die.GetName(), eNoDynamicValues, 0, var_sp, error); 5981ad6265SDimitry Andric if (valobj_sp) { 6081ad6265SDimitry Andric num_elements = valobj_sp->GetValueAsUnsigned(0); 6181ad6265SDimitry Andric break; 6281ad6265SDimitry Andric } 6381ad6265SDimitry Andric } 6481ad6265SDimitry Andric } 6581ad6265SDimitry Andric } else 6681ad6265SDimitry Andric num_elements = form_value.Unsigned(); 6781ad6265SDimitry Andric break; 6881ad6265SDimitry Andric 6981ad6265SDimitry Andric case DW_AT_bit_stride: 7081ad6265SDimitry Andric array_info.bit_stride = form_value.Unsigned(); 7181ad6265SDimitry Andric break; 7281ad6265SDimitry Andric 7381ad6265SDimitry Andric case DW_AT_byte_stride: 7481ad6265SDimitry Andric array_info.byte_stride = form_value.Unsigned(); 7581ad6265SDimitry Andric break; 7681ad6265SDimitry Andric 7781ad6265SDimitry Andric case DW_AT_lower_bound: 7881ad6265SDimitry Andric lower_bound = form_value.Unsigned(); 7981ad6265SDimitry Andric break; 8081ad6265SDimitry Andric 8181ad6265SDimitry Andric case DW_AT_upper_bound: 8281ad6265SDimitry Andric upper_bound_valid = true; 8381ad6265SDimitry Andric upper_bound = form_value.Unsigned(); 8481ad6265SDimitry Andric break; 8581ad6265SDimitry Andric 8681ad6265SDimitry Andric default: 8781ad6265SDimitry Andric break; 8881ad6265SDimitry Andric } 8981ad6265SDimitry Andric } 9081ad6265SDimitry Andric } 9181ad6265SDimitry Andric 9281ad6265SDimitry Andric if (num_elements == 0) { 9381ad6265SDimitry Andric if (upper_bound_valid && upper_bound >= lower_bound) 9481ad6265SDimitry Andric num_elements = upper_bound - lower_bound + 1; 9581ad6265SDimitry Andric } 9681ad6265SDimitry Andric 9781ad6265SDimitry Andric array_info.element_orders.push_back(num_elements); 9881ad6265SDimitry Andric } 9981ad6265SDimitry Andric } 10081ad6265SDimitry Andric return array_info; 10181ad6265SDimitry Andric } 10281ad6265SDimitry Andric 10381ad6265SDimitry Andric AccessType 10481ad6265SDimitry Andric DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) { 10581ad6265SDimitry Andric switch (dwarf_accessibility) { 10681ad6265SDimitry Andric case DW_ACCESS_public: 10781ad6265SDimitry Andric return eAccessPublic; 10881ad6265SDimitry Andric case DW_ACCESS_private: 10981ad6265SDimitry Andric return eAccessPrivate; 11081ad6265SDimitry Andric case DW_ACCESS_protected: 11181ad6265SDimitry Andric return eAccessProtected; 11281ad6265SDimitry Andric default: 11381ad6265SDimitry Andric break; 11481ad6265SDimitry Andric } 11581ad6265SDimitry Andric return eAccessNone; 11681ad6265SDimitry Andric } 117