1//===-- ProcessInfo.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-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef LLDB_UTILITY_PROCESSINFO_H 10#define LLDB_UTILITY_PROCESSINFO_H 11 12// LLDB headers 13#include "lldb/Utility/ArchSpec.h" 14#include "lldb/Utility/Args.h" 15#include "lldb/Utility/Environment.h" 16#include "lldb/Utility/FileSpec.h" 17#include "lldb/Utility/NameMatches.h" 18 19#include <vector> 20 21namespace lldb_private { 22 23class UserIDResolver; 24 25// ProcessInfo 26// 27// A base class for information for a process. This can be used to fill 28// out information for a process prior to launching it, or it can be used for 29// an instance of a process and can be filled in with the existing values for 30// that process. 31class ProcessInfo { 32public: 33 ProcessInfo(); 34 35 ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid); 36 37 void Clear(); 38 39 const char *GetName() const; 40 41 llvm::StringRef GetNameAsStringRef() const; 42 43 FileSpec &GetExecutableFile() { return m_executable; } 44 45 void SetExecutableFile(const FileSpec &exe_file, 46 bool add_exe_file_as_first_arg); 47 48 const FileSpec &GetExecutableFile() const { return m_executable; } 49 50 uint32_t GetUserID() const { return m_uid; } 51 52 uint32_t GetGroupID() const { return m_gid; } 53 54 bool UserIDIsValid() const { return m_uid != UINT32_MAX; } 55 56 bool GroupIDIsValid() const { return m_gid != UINT32_MAX; } 57 58 void SetUserID(uint32_t uid) { m_uid = uid; } 59 60 void SetGroupID(uint32_t gid) { m_gid = gid; } 61 62 ArchSpec &GetArchitecture() { return m_arch; } 63 64 const ArchSpec &GetArchitecture() const { return m_arch; } 65 66 void SetArchitecture(const ArchSpec &arch) { m_arch = arch; } 67 68 lldb::pid_t GetProcessID() const { return m_pid; } 69 70 void SetProcessID(lldb::pid_t pid) { m_pid = pid; } 71 72 bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; } 73 74 void Dump(Stream &s, Platform *platform) const; 75 76 Args &GetArguments() { return m_arguments; } 77 78 const Args &GetArguments() const { return m_arguments; } 79 80 llvm::StringRef GetArg0() const; 81 82 void SetArg0(llvm::StringRef arg); 83 84 void SetArguments(const Args &args, bool first_arg_is_executable); 85 86 void SetArguments(char const **argv, bool first_arg_is_executable); 87 88 Environment &GetEnvironment() { return m_environment; } 89 const Environment &GetEnvironment() const { return m_environment; } 90 91protected: 92 FileSpec m_executable; 93 std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. 94 // Not all process plug-ins support specifying an argv[0] that differs from 95 // the resolved platform executable (which is in m_executable) 96 Args m_arguments; // All program arguments except argv[0] 97 Environment m_environment; 98 uint32_t m_uid; 99 uint32_t m_gid; 100 ArchSpec m_arch; 101 lldb::pid_t m_pid; 102}; 103 104// ProcessInstanceInfo 105// 106// Describes an existing process and any discoverable information that pertains 107// to that process. 108class ProcessInstanceInfo : public ProcessInfo { 109public: 110 ProcessInstanceInfo() 111 : ProcessInfo(), m_euid(UINT32_MAX), m_egid(UINT32_MAX), 112 m_parent_pid(LLDB_INVALID_PROCESS_ID) {} 113 114 ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) 115 : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), 116 m_parent_pid(LLDB_INVALID_PROCESS_ID) {} 117 118 void Clear() { 119 ProcessInfo::Clear(); 120 m_euid = UINT32_MAX; 121 m_egid = UINT32_MAX; 122 m_parent_pid = LLDB_INVALID_PROCESS_ID; 123 } 124 125 uint32_t GetEffectiveUserID() const { return m_euid; } 126 127 uint32_t GetEffectiveGroupID() const { return m_egid; } 128 129 bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; } 130 131 bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; } 132 133 void SetEffectiveUserID(uint32_t uid) { m_euid = uid; } 134 135 void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; } 136 137 lldb::pid_t GetParentProcessID() const { return m_parent_pid; } 138 139 void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } 140 141 bool ParentProcessIDIsValid() const { 142 return m_parent_pid != LLDB_INVALID_PROCESS_ID; 143 } 144 145 void Dump(Stream &s, UserIDResolver &resolver) const; 146 147 static void DumpTableHeader(Stream &s, bool show_args, bool verbose); 148 149 void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args, 150 bool verbose) const; 151 152protected: 153 uint32_t m_euid; 154 uint32_t m_egid; 155 lldb::pid_t m_parent_pid; 156}; 157 158class ProcessInstanceInfoList { 159public: 160 ProcessInstanceInfoList() = default; 161 162 void Clear() { m_infos.clear(); } 163 164 size_t GetSize() { return m_infos.size(); } 165 166 void Append(const ProcessInstanceInfo &info) { m_infos.push_back(info); } 167 168 llvm::StringRef GetProcessNameAtIndex(size_t idx) { 169 return ((idx < m_infos.size()) ? m_infos[idx].GetNameAsStringRef() : ""); 170 } 171 172 lldb::pid_t GetProcessIDAtIndex(size_t idx) { 173 return ((idx < m_infos.size()) ? m_infos[idx].GetProcessID() : 0); 174 } 175 176 bool GetInfoAtIndex(size_t idx, ProcessInstanceInfo &info) { 177 if (idx < m_infos.size()) { 178 info = m_infos[idx]; 179 return true; 180 } 181 return false; 182 } 183 184 // You must ensure "idx" is valid before calling this function 185 const ProcessInstanceInfo &GetProcessInfoAtIndex(size_t idx) const { 186 assert(idx < m_infos.size()); 187 return m_infos[idx]; 188 } 189 190protected: 191 std::vector<ProcessInstanceInfo> m_infos; 192}; 193 194// ProcessInstanceInfoMatch 195// 196// A class to help matching one ProcessInstanceInfo to another. 197 198class ProcessInstanceInfoMatch { 199public: 200 ProcessInstanceInfoMatch() 201 : m_match_info(), m_name_match_type(NameMatch::Ignore), 202 m_match_all_users(false) {} 203 204 ProcessInstanceInfoMatch(const char *process_name, 205 NameMatch process_name_match_type) 206 : m_match_info(), m_name_match_type(process_name_match_type), 207 m_match_all_users(false) { 208 m_match_info.GetExecutableFile().SetFile(process_name, 209 FileSpec::Style::native); 210 } 211 212 ProcessInstanceInfo &GetProcessInfo() { return m_match_info; } 213 214 const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; } 215 216 bool GetMatchAllUsers() const { return m_match_all_users; } 217 218 void SetMatchAllUsers(bool b) { m_match_all_users = b; } 219 220 NameMatch GetNameMatchType() const { return m_name_match_type; } 221 222 void SetNameMatchType(NameMatch name_match_type) { 223 m_name_match_type = name_match_type; 224 } 225 226 /// Return true iff the architecture in this object matches arch_spec. 227 bool ArchitectureMatches(const ArchSpec &arch_spec) const; 228 229 /// Return true iff the process name in this object matches process_name. 230 bool NameMatches(const char *process_name) const; 231 232 /// Return true iff the process ID and parent process IDs in this object match 233 /// the ones in proc_info. 234 bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const; 235 236 /// Return true iff the (both effective and real) user and group IDs in this 237 /// object match the ones in proc_info. 238 bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const; 239 240 bool Matches(const ProcessInstanceInfo &proc_info) const; 241 242 bool MatchAllProcesses() const; 243 void Clear(); 244 245protected: 246 ProcessInstanceInfo m_match_info; 247 NameMatch m_name_match_type; 248 bool m_match_all_users; 249}; 250 251} // namespace lldb_private 252 253#endif // #ifndef LLDB_UTILITY_PROCESSINFO_H 254