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 ®_value); 88068f8a7eSTamas Berghammer 8997206d57SZachary Turner virtual Status WriteRegisterRaw(uint32_t reg_index, 90b9c1b51eSKate Stone const RegisterValue ®_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