reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
//===-- GDBRemoteRegisterContext.h ------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef lldb_GDBRemoteRegisterContext_h_
#define lldb_GDBRemoteRegisterContext_h_

#include <vector>

#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private.h"

#include "GDBRemoteCommunicationClient.h"

class StringExtractor;

namespace lldb_private {
namespace process_gdb_remote {

class ThreadGDBRemote;
class ProcessGDBRemote;

class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
public:
  GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}

  ~GDBRemoteDynamicRegisterInfo() override = default;

  void HardcodeARMRegisters(bool from_scratch);
};

class GDBRemoteRegisterContext : public RegisterContext {
public:
  GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
                           GDBRemoteDynamicRegisterInfo &reg_info,
                           bool read_all_at_once);

  ~GDBRemoteRegisterContext() override;

  void InvalidateAllRegisters() override;

  size_t GetRegisterCount() override;

  const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;

  size_t GetRegisterSetCount() override;

  const RegisterSet *GetRegisterSet(size_t reg_set) override;

  bool ReadRegister(const RegisterInfo *reg_info,
                    RegisterValue &value) override;

  bool WriteRegister(const RegisterInfo *reg_info,
                     const RegisterValue &value) override;

  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;

  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;

  bool ReadAllRegisterValues(RegisterCheckpoint &reg_checkpoint) override;

  bool
  WriteAllRegisterValues(const RegisterCheckpoint &reg_checkpoint) override;

  uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
                                               uint32_t num) override;

protected:
  friend class ThreadGDBRemote;

  bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data);

  bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data,
                          uint32_t data_offset);

  bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);

  bool PrivateSetRegisterValue(uint32_t reg, uint64_t val);

  void SetAllRegisterValid(bool b);

  bool GetRegisterIsValid(uint32_t reg) const {
#if defined(LLDB_CONFIGURATION_DEBUG)
    assert(reg < m_reg_valid.size());
#endif
    if (reg < m_reg_valid.size())
      return m_reg_valid[reg];
    return false;
  }

  void SetRegisterIsValid(const RegisterInfo *reg_info, bool valid) {
    if (reg_info)
      return SetRegisterIsValid(reg_info->kinds[lldb::eRegisterKindLLDB],
                                valid);
  }

  void SetRegisterIsValid(uint32_t reg, bool valid) {
#if defined(LLDB_CONFIGURATION_DEBUG)
    assert(reg < m_reg_valid.size());
#endif
    if (reg < m_reg_valid.size())
      m_reg_valid[reg] = valid;
  }

  GDBRemoteDynamicRegisterInfo &m_reg_info;
  std::vector<bool> m_reg_valid;
  DataExtractor m_reg_data;
  bool m_read_all_at_once;

private:
  // Helper function for ReadRegisterBytes().
  bool GetPrimordialRegister(const RegisterInfo *reg_info,
                             GDBRemoteCommunicationClient &gdb_comm);
  // Helper function for WriteRegisterBytes().
  bool SetPrimordialRegister(const RegisterInfo *reg_info,
                             GDBRemoteCommunicationClient &gdb_comm);

  DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
};

} // namespace process_gdb_remote
} // namespace lldb_private

#endif // lldb_GDBRemoteRegisterContext_h_