brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · 42cda01 Raw
115 lines · cpp
1#include "CFBasicHash.h"2 3#include "lldb/Utility/Endian.h"4 5using namespace lldb;6using namespace lldb_private;7 8bool 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    else15      return false;16  }17  return false;18}19 20bool 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 40template <typename T>41bool 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 75size_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_buckets81                             : m_ht_64->bits.used_buckets;82 83  //  FIXME: Add support for multi84  return 0;85}86 87size_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 96addr_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 106addr_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