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