187 lines · c
1//===-- MessageObjects.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_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H10#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H11 12#include "lldb/Host/Host.h"13#include "lldb/Utility/RegisterValue.h"14#include "lldb/Utility/StructuredData.h"15#include "lldb/lldb-types.h"16#include "llvm/ADT/DenseMap.h"17#include "llvm/ADT/SmallString.h"18#include "llvm/Support/Endian.h"19#include "llvm/Support/Error.h"20#include "llvm/Support/FormatVariadic.h"21#include <string>22 23namespace llgs_tests {24class ThreadInfo;25typedef llvm::DenseMap<uint64_t, ThreadInfo> ThreadInfoMap;26typedef llvm::DenseMap<unsigned int, lldb_private::RegisterValue> RegisterMap;27 28template <typename T> struct Parser { using result_type = T; };29 30class ProcessInfo : public Parser<ProcessInfo> {31public:32 static llvm::Expected<ProcessInfo> create(llvm::StringRef response);33 lldb::pid_t GetPid() const;34 llvm::endianness GetEndian() const;35 36private:37 ProcessInfo() = default;38 lldb::pid_t m_pid;39 lldb::pid_t m_parent_pid;40 uint32_t m_real_uid;41 uint32_t m_real_gid;42 uint32_t m_effective_uid;43 uint32_t m_effective_gid;44 std::string m_triple;45 llvm::SmallString<16> m_ostype;46 llvm::endianness m_endian;47 unsigned int m_ptrsize;48};49 50class ThreadInfo {51public:52 ThreadInfo() = default;53 ThreadInfo(llvm::StringRef name, llvm::StringRef reason,54 RegisterMap registers, unsigned int signal);55 56 const lldb_private::RegisterValue *ReadRegister(unsigned int Id) const;57 58private:59 std::string m_name;60 std::string m_reason;61 RegisterMap m_registers;62};63 64class JThreadsInfo : public Parser<JThreadsInfo> {65public:66 static llvm::Expected<JThreadsInfo>67 create(llvm::StringRef Response,68 llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);69 70 const ThreadInfoMap &GetThreadInfos() const;71 72private:73 static llvm::Expected<RegisterMap>74 parseRegisters(const lldb_private::StructuredData::Dictionary &Dict,75 llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);76 77 JThreadsInfo() = default;78 ThreadInfoMap m_thread_infos;79};80 81struct RegisterInfoParser : public Parser<lldb_private::RegisterInfo> {82 static llvm::Expected<lldb_private::RegisterInfo>83 create(llvm::StringRef Response);84};85 86llvm::Expected<lldb_private::RegisterValue>87parseRegisterValue(const lldb_private::RegisterInfo &Info,88 llvm::StringRef HexValue, llvm::endianness Endian,89 bool ZeroPad = false);90 91class StopReply : public Parser<std::unique_ptr<StopReply>> {92public:93 StopReply() = default;94 virtual ~StopReply() = default;95 96 static llvm::Expected<std::unique_ptr<StopReply>>97 create(llvm::StringRef Response, llvm::endianness Endian,98 llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);99 100 // for llvm::cast<>101 virtual lldb_private::WaitStatus getKind() const = 0;102 103 StopReply(const StopReply &) = delete;104 void operator=(const StopReply &) = delete;105};106 107class StopReplyStop : public StopReply {108public:109 StopReplyStop(uint8_t Signal, lldb::tid_t ThreadId, llvm::StringRef Name,110 RegisterMap ThreadPcs, RegisterMap Registers,111 llvm::StringRef Reason)112 : Signal(Signal), ThreadId(ThreadId), Name(Name),113 ThreadPcs(std::move(ThreadPcs)), Registers(std::move(Registers)),114 Reason(Reason) {}115 116 static llvm::Expected<std::unique_ptr<StopReplyStop>>117 create(llvm::StringRef Response, llvm::endianness Endian,118 llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);119 120 const RegisterMap &getThreadPcs() const { return ThreadPcs; }121 lldb::tid_t getThreadId() const { return ThreadId; }122 123 // for llvm::cast<>124 lldb_private::WaitStatus getKind() const override {125 return lldb_private::WaitStatus{lldb_private::WaitStatus::Stop, Signal};126 }127 static bool classof(const StopReply *R) {128 return R->getKind().type == lldb_private::WaitStatus::Stop;129 }130 131private:132 static llvm::Expected<RegisterMap> parseRegisters(133 const llvm::StringMap<llvm::SmallVector<llvm::StringRef, 2>> &Elements,134 llvm::endianness Endian,135 llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);136 137 uint8_t Signal;138 lldb::tid_t ThreadId;139 std::string Name;140 RegisterMap ThreadPcs;141 RegisterMap Registers;142 std::string Reason;143};144 145class StopReplyExit : public StopReply {146public:147 explicit StopReplyExit(uint8_t Status) : Status(Status) {}148 149 static llvm::Expected<std::unique_ptr<StopReplyExit>>150 create(llvm::StringRef response);151 152 // for llvm::cast<>153 lldb_private::WaitStatus getKind() const override {154 return lldb_private::WaitStatus{lldb_private::WaitStatus::Exit, Status};155 }156 static bool classof(const StopReply *R) {157 return R->getKind().type == lldb_private::WaitStatus::Exit;158 }159 160private:161 uint8_t Status;162};163 164// Common functions for parsing packet data.165llvm::Expected<llvm::StringMap<llvm::StringRef>>166SplitUniquePairList(llvm::StringRef caller, llvm::StringRef s);167 168llvm::StringMap<llvm::SmallVector<llvm::StringRef, 2>>169SplitPairList(llvm::StringRef s);170 171template <typename... Args>172llvm::Error make_parsing_error(llvm::StringRef format, Args &&... args) {173 std::string error =174 "Unable to parse " +175 llvm::formatv(format.data(), std::forward<Args>(args)...).str();176 return llvm::make_error<llvm::StringError>(error,177 llvm::inconvertibleErrorCode());178}179 180} // namespace llgs_tests181 182namespace lldb_private {183std::ostream &operator<<(std::ostream &OS, const RegisterValue &RegVal);184}185 186#endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H187