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