Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp
39644 views
1
#include "CFBasicHash.h"
2
3
#include "lldb/Utility/Endian.h"
4
5
using namespace lldb;
6
using namespace lldb_private;
7
8
bool CFBasicHash::IsValid() const {
9
if (m_address != LLDB_INVALID_ADDRESS) {
10
if (m_ptr_size == 4 && m_ht_32)
11
return true;
12
else if (m_ptr_size == 8 && m_ht_64)
13
return true;
14
else
15
return false;
16
}
17
return false;
18
}
19
20
bool CFBasicHash::Update(addr_t addr, ExecutionContextRef exe_ctx_rf) {
21
if (addr == LLDB_INVALID_ADDRESS || !addr)
22
return false;
23
24
m_address = addr;
25
m_exe_ctx_ref = exe_ctx_rf;
26
m_ptr_size =
27
m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetAddressByteSize();
28
m_byte_order = m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetByteOrder();
29
30
if (m_ptr_size == 4)
31
return UpdateFor(m_ht_32);
32
else if (m_ptr_size == 8)
33
return UpdateFor(m_ht_64);
34
return false;
35
36
llvm_unreachable(
37
"Unsupported architecture. Only 32bits and 64bits supported.");
38
}
39
40
template <typename T>
41
bool CFBasicHash::UpdateFor(std::unique_ptr<__CFBasicHash<T>> &m_ht) {
42
if (m_byte_order != endian::InlHostByteOrder())
43
return false;
44
45
Status error;
46
Target *target = m_exe_ctx_ref.GetTargetSP().get();
47
addr_t addr = m_address.GetLoadAddress(target);
48
size_t size = sizeof(typename __CFBasicHash<T>::RuntimeBase) +
49
sizeof(typename __CFBasicHash<T>::Bits);
50
51
m_ht = std::make_unique<__CFBasicHash<T>>();
52
m_exe_ctx_ref.GetProcessSP()->ReadMemory(addr, m_ht.get(),
53
size, error);
54
if (error.Fail())
55
return false;
56
57
m_mutable = !(m_ht->base.cfinfoa & (1 << 6));
58
m_multi = m_ht->bits.counts_offset;
59
m_type = static_cast<HashType>(m_ht->bits.keys_offset);
60
addr_t ptr_offset = addr + size;
61
size_t ptr_count = GetPointerCount();
62
size = ptr_count * sizeof(T);
63
64
m_exe_ctx_ref.GetProcessSP()->ReadMemory(ptr_offset, m_ht->pointers, size,
65
error);
66
67
if (error.Fail()) {
68
m_ht = nullptr;
69
return false;
70
}
71
72
return true;
73
}
74
75
size_t CFBasicHash::GetCount() const {
76
if (!IsValid())
77
return 0;
78
79
if (!m_multi)
80
return (m_ptr_size == 4) ? m_ht_32->bits.used_buckets
81
: m_ht_64->bits.used_buckets;
82
83
// FIXME: Add support for multi
84
return 0;
85
}
86
87
size_t CFBasicHash::GetPointerCount() const {
88
if (!IsValid())
89
return 0;
90
91
if (m_multi)
92
return 3; // Bits::counts_offset;
93
return (m_type == HashType::dict) + 1;
94
}
95
96
addr_t CFBasicHash::GetKeyPointer() const {
97
if (!IsValid())
98
return LLDB_INVALID_ADDRESS;
99
100
if (m_ptr_size == 4)
101
return m_ht_32->pointers[m_ht_32->bits.keys_offset];
102
103
return m_ht_64->pointers[m_ht_64->bits.keys_offset];
104
}
105
106
addr_t CFBasicHash::GetValuePointer() const {
107
if (!IsValid())
108
return LLDB_INVALID_ADDRESS;
109
110
if (m_ptr_size == 4)
111
return m_ht_32->pointers[0];
112
113
return m_ht_64->pointers[0];
114
}
115
116