//===-- MessageObjects.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_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H #define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H #include "lldb/Host/Host.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-types.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include namespace llgs_tests { class ThreadInfo; typedef llvm::DenseMap ThreadInfoMap; typedef llvm::DenseMap RegisterMap; template struct Parser { using result_type = T; }; class ProcessInfo : public Parser { public: static llvm::Expected create(llvm::StringRef response); lldb::pid_t GetPid() const; llvm::support::endianness GetEndian() const; private: ProcessInfo() = default; lldb::pid_t m_pid; lldb::pid_t m_parent_pid; uint32_t m_real_uid; uint32_t m_real_gid; uint32_t m_effective_uid; uint32_t m_effective_gid; std::string m_triple; llvm::SmallString<16> m_ostype; llvm::support::endianness m_endian; unsigned int m_ptrsize; }; class ThreadInfo { public: ThreadInfo() = default; ThreadInfo(llvm::StringRef name, llvm::StringRef reason, RegisterMap registers, unsigned int signal); const lldb_private::RegisterValue *ReadRegister(unsigned int Id) const; private: std::string m_name; std::string m_reason; RegisterMap m_registers; }; class JThreadsInfo : public Parser { public: static llvm::Expected create(llvm::StringRef Response, llvm::ArrayRef RegInfos); const ThreadInfoMap &GetThreadInfos() const; private: static llvm::Expected parseRegisters(const lldb_private::StructuredData::Dictionary &Dict, llvm::ArrayRef RegInfos); JThreadsInfo() = default; ThreadInfoMap m_thread_infos; }; struct RegisterInfoParser : public Parser { static llvm::Expected create(llvm::StringRef Response); }; llvm::Expected parseRegisterValue(const lldb_private::RegisterInfo &Info, llvm::StringRef HexValue, llvm::support::endianness Endian, bool ZeroPad = false); class StopReply : public Parser> { public: StopReply() = default; virtual ~StopReply() = default; static llvm::Expected> create(llvm::StringRef Response, llvm::support::endianness Endian, llvm::ArrayRef RegInfos); // for llvm::cast<> virtual lldb_private::WaitStatus getKind() const = 0; StopReply(const StopReply &) = delete; void operator=(const StopReply &) = delete; }; class StopReplyStop : public StopReply { public: StopReplyStop(uint8_t Signal, lldb::tid_t ThreadId, llvm::StringRef Name, RegisterMap ThreadPcs, RegisterMap Registers, llvm::StringRef Reason) : Signal(Signal), ThreadId(ThreadId), Name(Name), ThreadPcs(std::move(ThreadPcs)), Registers(std::move(Registers)), Reason(Reason) {} static llvm::Expected> create(llvm::StringRef Response, llvm::support::endianness Endian, llvm::ArrayRef RegInfos); const RegisterMap &getThreadPcs() const { return ThreadPcs; } lldb::tid_t getThreadId() const { return ThreadId; } // for llvm::cast<> lldb_private::WaitStatus getKind() const override { return lldb_private::WaitStatus{lldb_private::WaitStatus::Stop, Signal}; } static bool classof(const StopReply *R) { return R->getKind().type == lldb_private::WaitStatus::Stop; } private: static llvm::Expected parseRegisters( const llvm::StringMap> &Elements, llvm::support::endianness Endian, llvm::ArrayRef RegInfos); uint8_t Signal; lldb::tid_t ThreadId; std::string Name; RegisterMap ThreadPcs; RegisterMap Registers; std::string Reason; }; class StopReplyExit : public StopReply { public: explicit StopReplyExit(uint8_t Status) : Status(Status) {} static llvm::Expected> create(llvm::StringRef response); // for llvm::cast<> lldb_private::WaitStatus getKind() const override { return lldb_private::WaitStatus{lldb_private::WaitStatus::Exit, Status}; } static bool classof(const StopReply *R) { return R->getKind().type == lldb_private::WaitStatus::Exit; } private: uint8_t Status; }; // Common functions for parsing packet data. llvm::Expected> SplitUniquePairList(llvm::StringRef caller, llvm::StringRef s); llvm::StringMap> SplitPairList(llvm::StringRef s); template llvm::Error make_parsing_error(llvm::StringRef format, Args &&... args) { std::string error = "Unable to parse " + llvm::formatv(format.data(), std::forward(args)...).str(); return llvm::make_error(error, llvm::inconvertibleErrorCode()); } } // namespace llgs_tests namespace lldb_private { std::ostream &operator<<(std::ostream &OS, const RegisterValue &RegVal); } #endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H