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 #include "lldb/Utility/ArchSpec.h"
13 #include "lldb/Utility/Args.h"
14 #include "lldb/Utility/Environment.h"
15 #include "lldb/Utility/FileSpec.h"
16 #include "lldb/Utility/NameMatches.h"
17 #include "llvm/Support/YAMLTraits.h"
18 #include <vector>
19 
20 namespace lldb_private {
21 
22 class UserIDResolver;
23 
24 // ProcessInfo
25 //
26 // A base class for information for a process. This can be used to fill
27 // out information for a process prior to launching it, or it can be used for
28 // an instance of a process and can be filled in with the existing values for
29 // that process.
30 class ProcessInfo {
31 public:
32   ProcessInfo();
33 
34   ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid);
35 
36   void Clear();
37 
38   const char *GetName() const;
39 
40   llvm::StringRef GetNameAsStringRef() const;
41 
42   FileSpec &GetExecutableFile() { return m_executable; }
43 
44   void SetExecutableFile(const FileSpec &exe_file,
45                          bool add_exe_file_as_first_arg);
46 
47   const FileSpec &GetExecutableFile() const { return m_executable; }
48 
49   uint32_t GetUserID() const { return m_uid; }
50 
51   uint32_t GetGroupID() const { return m_gid; }
52 
53   bool UserIDIsValid() const { return m_uid != UINT32_MAX; }
54 
55   bool GroupIDIsValid() const { return m_gid != UINT32_MAX; }
56 
57   void SetUserID(uint32_t uid) { m_uid = uid; }
58 
59   void SetGroupID(uint32_t gid) { m_gid = gid; }
60 
61   ArchSpec &GetArchitecture() { return m_arch; }
62 
63   const ArchSpec &GetArchitecture() const { return m_arch; }
64 
65   void SetArchitecture(const ArchSpec &arch) { m_arch = arch; }
66 
67   lldb::pid_t GetProcessID() const { return m_pid; }
68 
69   void SetProcessID(lldb::pid_t pid) { m_pid = pid; }
70 
71   bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; }
72 
73   void Dump(Stream &s, Platform *platform) const;
74 
75   Args &GetArguments() { return m_arguments; }
76 
77   const Args &GetArguments() const { return m_arguments; }
78 
79   llvm::StringRef GetArg0() const;
80 
81   void SetArg0(llvm::StringRef arg);
82 
83   void SetArguments(const Args &args, bool first_arg_is_executable);
84 
85   void SetArguments(char const **argv, bool first_arg_is_executable);
86 
87   Environment &GetEnvironment() { return m_environment; }
88   const Environment &GetEnvironment() const { return m_environment; }
89 
90 protected:
91   template <class T> friend struct llvm::yaml::MappingTraits;
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   friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>;
154   uint32_t m_euid;
155   uint32_t m_egid;
156   lldb::pid_t m_parent_pid;
157 };
158 
159 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
160 
161 // ProcessInstanceInfoMatch
162 //
163 // A class to help matching one ProcessInstanceInfo to another.
164 
165 class ProcessInstanceInfoMatch {
166 public:
167   ProcessInstanceInfoMatch()
168       : m_match_info(), m_name_match_type(NameMatch::Ignore),
169         m_match_all_users(false) {}
170 
171   ProcessInstanceInfoMatch(const char *process_name,
172                            NameMatch process_name_match_type)
173       : m_match_info(), m_name_match_type(process_name_match_type),
174         m_match_all_users(false) {
175     m_match_info.GetExecutableFile().SetFile(process_name,
176                                              FileSpec::Style::native);
177   }
178 
179   ProcessInstanceInfo &GetProcessInfo() { return m_match_info; }
180 
181   const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; }
182 
183   bool GetMatchAllUsers() const { return m_match_all_users; }
184 
185   void SetMatchAllUsers(bool b) { m_match_all_users = b; }
186 
187   NameMatch GetNameMatchType() const { return m_name_match_type; }
188 
189   void SetNameMatchType(NameMatch name_match_type) {
190     m_name_match_type = name_match_type;
191   }
192 
193   /// Return true iff the architecture in this object matches arch_spec.
194   bool ArchitectureMatches(const ArchSpec &arch_spec) const;
195 
196   /// Return true iff the process name in this object matches process_name.
197   bool NameMatches(const char *process_name) const;
198 
199   /// Return true iff the process ID and parent process IDs in this object match
200   /// the ones in proc_info.
201   bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const;
202 
203   /// Return true iff the (both effective and real) user and group IDs in this
204   /// object match the ones in proc_info.
205   bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const;
206 
207   bool Matches(const ProcessInstanceInfo &proc_info) const;
208 
209   bool MatchAllProcesses() const;
210   void Clear();
211 
212 protected:
213   ProcessInstanceInfo m_match_info;
214   NameMatch m_name_match_type;
215   bool m_match_all_users;
216 };
217 
218 namespace repro {
219 llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList();
220 } // namespace repro
221 } // namespace lldb_private
222 
223 LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ProcessInstanceInfo)
224 
225 namespace llvm {
226 namespace yaml {
227 template <> struct MappingTraits<lldb_private::ProcessInstanceInfo> {
228   static void mapping(IO &io, lldb_private::ProcessInstanceInfo &PII);
229 };
230 } // namespace yaml
231 } // namespace llvm
232 
233 #endif // LLDB_UTILITY_PROCESSINFO_H
234