brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 08f19d3 Raw
146 lines · c
1//===-- NativeRegisterContextLinux.h ----------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef lldb_NativeRegisterContextLinux_h10#define lldb_NativeRegisterContextLinux_h11 12#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"13#include "lldb/Host/common/NativeThreadProtocol.h"14#include "lldb/Target/MemoryTagManager.h"15#include "llvm/Support/Error.h"16#include <optional>17 18namespace lldb_private {19namespace process_linux {20 21class NativeThreadLinux;22 23class NativeRegisterContextLinux24    : public virtual NativeRegisterContextRegisterInfo {25public:26  // These static methods are implemented individual27  // NativeRegisterContextLinux_* subclasses.  The implementations can't collide28  // as only one NativeRegisterContextLinux_* variant should be compiled into29  // the final executable.30 31  // Return a NativeRegisterContextLinux instance suitable for debugging the32  // given thread.33  static std::unique_ptr<NativeRegisterContextLinux>34  CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,35                                       NativeThreadLinux &native_thread);36 37  // Determine the architecture of the thread given by its ID.38  static llvm::Expected<ArchSpec> DetermineArchitecture(lldb::tid_t tid);39 40  // Invalidates cached values in register context data structures41  virtual void InvalidateAllRegisters(){}42 43  struct SyscallData {44    /// The syscall instruction. If the architecture uses software45    /// single-stepping, the instruction should also be followed by a trap to46    /// ensure the process is stopped after the syscall.47    llvm::ArrayRef<uint8_t> Insn;48 49    /// Registers used for syscall arguments. The first register is used to50    /// store the syscall number.51    llvm::ArrayRef<uint32_t> Args;52 53    uint32_t Result; ///< Register containing the syscall result.54  };55  /// Return architecture-specific data needed to make inferior syscalls, if56  /// they are supported.57  virtual std::optional<SyscallData> GetSyscallData() { return std::nullopt; }58 59  struct MmapData {60    // Syscall numbers can be found (e.g.) in /usr/include/asm/unistd.h for the61    // relevant architecture.62    unsigned SysMmap;   ///< mmap syscall number.63    unsigned SysMunmap; ///< munmap syscall number64  };65  /// Return the architecture-specific data needed to make mmap syscalls, if66  /// they are supported.67  virtual std::optional<MmapData> GetMmapData() { return std::nullopt; }68 69  struct MemoryTaggingDetails {70    /// Object with tag handling utilities. If the function below returns71    /// a valid structure, you can assume that this pointer is valid.72    std::unique_ptr<MemoryTagManager> manager;73    int ptrace_read_req;  /// ptrace operation number for memory tag read74    int ptrace_write_req; /// ptrace operation number for memory tag write75  };76  /// Return architecture specific data needed to use memory tags,77  /// if they are supported.78  virtual llvm::Expected<MemoryTaggingDetails>79  GetMemoryTaggingDetails(int32_t type) {80    return llvm::createStringError(81        llvm::inconvertibleErrorCode(),82        "Architecture does not support memory tagging");83  }84 85protected:86  // NB: This constructor is here only because gcc<=6.5 requires a virtual base87  // class initializer on abstract class (even though it is never used). It can88  // be deleted once we move to gcc>=7.0.89  NativeRegisterContextLinux(NativeThreadProtocol &thread)90      : NativeRegisterContextRegisterInfo(thread, nullptr) {}91 92  lldb::ByteOrder GetByteOrder() const;93 94  virtual Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);95 96  virtual Status WriteRegisterRaw(uint32_t reg_index,97                                  const RegisterValue &reg_value);98 99  virtual Status ReadRegisterSet(void *buf, size_t buf_size,100                                 unsigned int regset);101 102  virtual Status WriteRegisterSet(void *buf, size_t buf_size,103                                  unsigned int regset);104 105  virtual Status ReadGPR();106 107  virtual Status WriteGPR();108 109  virtual Status ReadFPR();110 111  virtual Status WriteFPR();112 113  virtual void *GetGPRBuffer() = 0;114 115  virtual size_t GetGPRSize() const {116    return GetRegisterInfoInterface().GetGPRSize();117  }118 119  virtual void *GetFPRBuffer() = 0;120 121  virtual size_t GetFPRSize() = 0;122 123  virtual uint32_t GetPtraceOffset(uint32_t reg_index) {124    return GetRegisterInfoAtIndex(reg_index)->byte_offset;125  }126 127  // The Do*** functions are executed on the privileged thread and can perform128  // ptrace129  // operations directly.130  virtual Status DoReadRegisterValue(uint32_t offset, const char *reg_name,131                                     uint32_t size, RegisterValue &value);132 133  virtual Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,134                                      const RegisterValue &value);135 136  // Determine the architecture via GPR size, as reported by137  // PTRACE_GETREGSET(NT_PRSTATUS).138  static llvm::Expected<ArchSpec>139  DetermineArchitectureViaGPR(lldb::tid_t tid, size_t gpr64_size);140};141 142} // namespace process_linux143} // namespace lldb_private144 145#endif // #ifndef lldb_NativeRegisterContextLinux_h146