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