1068f8a7eSTamas Berghammer //===-- NativeRegisterContextLinux.h ----------------------------*- C++ -*-===//
2068f8a7eSTamas Berghammer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6068f8a7eSTamas Berghammer //
7068f8a7eSTamas Berghammer //===----------------------------------------------------------------------===//
8068f8a7eSTamas Berghammer 
9068f8a7eSTamas Berghammer #ifndef lldb_NativeRegisterContextLinux_h
10068f8a7eSTamas Berghammer #define lldb_NativeRegisterContextLinux_h
11068f8a7eSTamas Berghammer 
1290bf36f9SZachary Turner #include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
13d37349f3SPavel Labath #include "lldb/Host/common/NativeThreadProtocol.h"
14*da2e614fSDavid Spickett #include "lldb/Target/MemoryTagManager.h"
15*da2e614fSDavid Spickett #include "llvm/Support/Error.h"
16068f8a7eSTamas Berghammer 
17068f8a7eSTamas Berghammer namespace lldb_private {
18068f8a7eSTamas Berghammer namespace process_linux {
19068f8a7eSTamas Berghammer 
20d1486e65SPavel Labath class NativeThreadLinux;
21d1486e65SPavel Labath 
22f5ca2756SMichał Górny class NativeRegisterContextLinux
23f5ca2756SMichał Górny     : public virtual NativeRegisterContextRegisterInfo {
24068f8a7eSTamas Berghammer public:
25b9c1b51eSKate Stone   // This function is implemented in the NativeRegisterContextLinux_* subclasses
26d37349f3SPavel Labath   // to create a new instance of the host specific NativeRegisterContextLinux.
27d37349f3SPavel Labath   // The implementations can't collide as only one NativeRegisterContextLinux_*
28d37349f3SPavel Labath   // variant should be compiled into the final executable.
29d37349f3SPavel Labath   static std::unique_ptr<NativeRegisterContextLinux>
30068f8a7eSTamas Berghammer   CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
31d1486e65SPavel Labath                                        NativeThreadLinux &native_thread);
32068f8a7eSTamas Berghammer 
33b6f9d7b8SMuhammad Omair Javaid   // Invalidates cached values in register context data structures
InvalidateAllRegisters()34b6f9d7b8SMuhammad Omair Javaid   virtual void InvalidateAllRegisters(){}
35b6f9d7b8SMuhammad Omair Javaid 
362c4226f8SPavel Labath   struct SyscallData {
372c4226f8SPavel Labath     /// The syscall instruction. If the architecture uses software
382c4226f8SPavel Labath     /// single-stepping, the instruction should also be followed by a trap to
392c4226f8SPavel Labath     /// ensure the process is stopped after the syscall.
402c4226f8SPavel Labath     llvm::ArrayRef<uint8_t> Insn;
412c4226f8SPavel Labath 
422c4226f8SPavel Labath     /// Registers used for syscall arguments. The first register is used to
432c4226f8SPavel Labath     /// store the syscall number.
442c4226f8SPavel Labath     llvm::ArrayRef<uint32_t> Args;
452c4226f8SPavel Labath 
462c4226f8SPavel Labath     uint32_t Result; ///< Register containing the syscall result.
472c4226f8SPavel Labath   };
482c4226f8SPavel Labath   /// Return architecture-specific data needed to make inferior syscalls, if
492c4226f8SPavel Labath   /// they are supported.
GetSyscallData()502c4226f8SPavel Labath   virtual llvm::Optional<SyscallData> GetSyscallData() { return llvm::None; }
512c4226f8SPavel Labath 
522c4226f8SPavel Labath   struct MmapData {
532c4226f8SPavel Labath     // Syscall numbers can be found (e.g.) in /usr/include/asm/unistd.h for the
542c4226f8SPavel Labath     // relevant architecture.
552c4226f8SPavel Labath     unsigned SysMmap;   ///< mmap syscall number.
562c4226f8SPavel Labath     unsigned SysMunmap; ///< munmap syscall number
572c4226f8SPavel Labath   };
582c4226f8SPavel Labath   /// Return the architecture-specific data needed to make mmap syscalls, if
592c4226f8SPavel Labath   /// they are supported.
GetMmapData()602c4226f8SPavel Labath   virtual llvm::Optional<MmapData> GetMmapData() { return llvm::None; }
612c4226f8SPavel Labath 
62*da2e614fSDavid Spickett   struct MemoryTaggingDetails {
63*da2e614fSDavid Spickett     /// Object with tag handling utilities. If the function below returns
64*da2e614fSDavid Spickett     /// a valid structure, you can assume that this pointer is valid.
65*da2e614fSDavid Spickett     std::unique_ptr<MemoryTagManager> manager;
66*da2e614fSDavid Spickett     int ptrace_read_req;  /// ptrace operation number for memory tag read
67*da2e614fSDavid Spickett     int ptrace_write_req; /// ptrace operation number for memory tag write
68*da2e614fSDavid Spickett   };
69*da2e614fSDavid Spickett   /// Return architecture specific data needed to use memory tags,
70*da2e614fSDavid Spickett   /// if they are supported.
71*da2e614fSDavid Spickett   virtual llvm::Expected<MemoryTaggingDetails>
GetMemoryTaggingDetails(int32_t type)72*da2e614fSDavid Spickett   GetMemoryTaggingDetails(int32_t type) {
73*da2e614fSDavid Spickett     return llvm::createStringError(
74*da2e614fSDavid Spickett         llvm::inconvertibleErrorCode(),
75*da2e614fSDavid Spickett         "Architecture does not support memory tagging");
76*da2e614fSDavid Spickett   }
77*da2e614fSDavid Spickett 
78068f8a7eSTamas Berghammer protected:
793bea7306SPavel Labath   // NB: This constructor is here only because gcc<=6.5 requires a virtual base
803bea7306SPavel Labath   // class initializer on abstract class (even though it is never used). It can
813bea7306SPavel Labath   // be deleted once we move to gcc>=7.0.
NativeRegisterContextLinux(NativeThreadProtocol & thread)823bea7306SPavel Labath   NativeRegisterContextLinux(NativeThreadProtocol &thread)
833bea7306SPavel Labath       : NativeRegisterContextRegisterInfo(thread, nullptr) {}
843bea7306SPavel Labath 
85b9c1b51eSKate Stone   lldb::ByteOrder GetByteOrder() const;
86068f8a7eSTamas Berghammer 
8797206d57SZachary Turner   virtual Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);
88068f8a7eSTamas Berghammer 
8997206d57SZachary Turner   virtual Status WriteRegisterRaw(uint32_t reg_index,
90b9c1b51eSKate Stone                                   const RegisterValue &reg_value);
91068f8a7eSTamas Berghammer 
9297206d57SZachary Turner   virtual Status ReadRegisterSet(void *buf, size_t buf_size,
93b9c1b51eSKate Stone                                  unsigned int regset);
94068f8a7eSTamas Berghammer 
9597206d57SZachary Turner   virtual Status WriteRegisterSet(void *buf, size_t buf_size,
96b9c1b51eSKate Stone                                   unsigned int regset);
97068f8a7eSTamas Berghammer 
9897206d57SZachary Turner   virtual Status ReadGPR();
99068f8a7eSTamas Berghammer 
10097206d57SZachary Turner   virtual Status WriteGPR();
101068f8a7eSTamas Berghammer 
10297206d57SZachary Turner   virtual Status ReadFPR();
103068f8a7eSTamas Berghammer 
10497206d57SZachary Turner   virtual Status WriteFPR();
105068f8a7eSTamas Berghammer 
1063f3673eaSPavel Labath   virtual void *GetGPRBuffer() = 0;
107068f8a7eSTamas Berghammer 
GetGPRSize()1087fa7b81bSMuhammad Omair Javaid   virtual size_t GetGPRSize() const {
109b9c1b51eSKate Stone     return GetRegisterInfoInterface().GetGPRSize();
110b9c1b51eSKate Stone   }
111068f8a7eSTamas Berghammer 
1123f3673eaSPavel Labath   virtual void *GetFPRBuffer() = 0;
113068f8a7eSTamas Berghammer 
1143f3673eaSPavel Labath   virtual size_t GetFPRSize() = 0;
115068f8a7eSTamas Berghammer 
GetPtraceOffset(uint32_t reg_index)116e46c6644SGuilherme Andrade   virtual uint32_t GetPtraceOffset(uint32_t reg_index) {
117e46c6644SGuilherme Andrade     return GetRegisterInfoAtIndex(reg_index)->byte_offset;
118e46c6644SGuilherme Andrade   }
119e46c6644SGuilherme Andrade 
120b9c1b51eSKate Stone   // The Do*** functions are executed on the privileged thread and can perform
121b9c1b51eSKate Stone   // ptrace
122c7512fdcSPavel Labath   // operations directly.
12397206d57SZachary Turner   virtual Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
124b9c1b51eSKate Stone                                      uint32_t size, RegisterValue &value);
125068f8a7eSTamas Berghammer 
12697206d57SZachary Turner   virtual Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
127068f8a7eSTamas Berghammer                                       const RegisterValue &value);
128068f8a7eSTamas Berghammer };
129068f8a7eSTamas Berghammer 
130068f8a7eSTamas Berghammer } // namespace process_linux
131068f8a7eSTamas Berghammer } // namespace lldb_private
132068f8a7eSTamas Berghammer 
133068f8a7eSTamas Berghammer #endif // #ifndef lldb_NativeRegisterContextLinux_h
134