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 
21 namespace lldb_private {
22 
23 class 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.
31 class ProcessInfo {
32 public:
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 
91 protected:
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.
108 class ProcessInstanceInfo : public ProcessInfo {
109 public:
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 
152 protected:
153   uint32_t m_euid;
154   uint32_t m_egid;
155   lldb::pid_t m_parent_pid;
156 };
157 
158 class ProcessInstanceInfoList {
159 public:
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 
190 protected:
191   std::vector<ProcessInstanceInfo> m_infos;
192 };
193 
194 // ProcessInstanceInfoMatch
195 //
196 // A class to help matching one ProcessInstanceInfo to another.
197 
198 class ProcessInstanceInfoMatch {
199 public:
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 
245 protected:
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