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 = UINT32_MAX;
99   uint32_t m_gid = UINT32_MAX;
100   ArchSpec m_arch;
101   lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID;
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() = default;
111 
112   ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid)
113       : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX),
114         m_parent_pid(LLDB_INVALID_PROCESS_ID) {}
115 
116   void Clear() {
117     ProcessInfo::Clear();
118     m_euid = UINT32_MAX;
119     m_egid = UINT32_MAX;
120     m_parent_pid = LLDB_INVALID_PROCESS_ID;
121   }
122 
123   uint32_t GetEffectiveUserID() const { return m_euid; }
124 
125   uint32_t GetEffectiveGroupID() const { return m_egid; }
126 
127   bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; }
128 
129   bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; }
130 
131   void SetEffectiveUserID(uint32_t uid) { m_euid = uid; }
132 
133   void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; }
134 
135   lldb::pid_t GetParentProcessID() const { return m_parent_pid; }
136 
137   void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; }
138 
139   bool ParentProcessIDIsValid() const {
140     return m_parent_pid != LLDB_INVALID_PROCESS_ID;
141   }
142 
143   void Dump(Stream &s, UserIDResolver &resolver) const;
144 
145   static void DumpTableHeader(Stream &s, bool show_args, bool verbose);
146 
147   void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args,
148                       bool verbose) const;
149 
150 protected:
151   friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>;
152   uint32_t m_euid = UINT32_MAX;
153   uint32_t m_egid = UINT32_MAX;
154   lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID;
155 };
156 
157 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
158 
159 // ProcessInstanceInfoMatch
160 //
161 // A class to help matching one ProcessInstanceInfo to another.
162 
163 class ProcessInstanceInfoMatch {
164 public:
165   ProcessInstanceInfoMatch() = default;
166 
167   ProcessInstanceInfoMatch(const char *process_name,
168                            NameMatch process_name_match_type)
169       : m_name_match_type(process_name_match_type), m_match_all_users(false) {
170     m_match_info.GetExecutableFile().SetFile(process_name,
171                                              FileSpec::Style::native);
172   }
173 
174   ProcessInstanceInfo &GetProcessInfo() { return m_match_info; }
175 
176   const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; }
177 
178   bool GetMatchAllUsers() const { return m_match_all_users; }
179 
180   void SetMatchAllUsers(bool b) { m_match_all_users = b; }
181 
182   NameMatch GetNameMatchType() const { return m_name_match_type; }
183 
184   void SetNameMatchType(NameMatch name_match_type) {
185     m_name_match_type = name_match_type;
186   }
187 
188   /// Return true iff the architecture in this object matches arch_spec.
189   bool ArchitectureMatches(const ArchSpec &arch_spec) const;
190 
191   /// Return true iff the process name in this object matches process_name.
192   bool NameMatches(const char *process_name) const;
193 
194   /// Return true iff the process ID and parent process IDs in this object match
195   /// the ones in proc_info.
196   bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const;
197 
198   /// Return true iff the (both effective and real) user and group IDs in this
199   /// object match the ones in proc_info.
200   bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const;
201 
202   bool Matches(const ProcessInstanceInfo &proc_info) const;
203 
204   bool MatchAllProcesses() const;
205   void Clear();
206 
207 protected:
208   ProcessInstanceInfo m_match_info;
209   NameMatch m_name_match_type = NameMatch::Ignore;
210   bool m_match_all_users = false;
211 };
212 
213 namespace repro {
214 llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList();
215 } // namespace repro
216 } // namespace lldb_private
217 
218 LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ProcessInstanceInfo)
219 
220 namespace llvm {
221 namespace yaml {
222 template <> struct MappingTraits<lldb_private::ProcessInstanceInfo> {
223   static void mapping(IO &io, lldb_private::ProcessInstanceInfo &PII);
224 };
225 } // namespace yaml
226 } // namespace llvm
227 
228 #endif // LLDB_UTILITY_PROCESSINFO_H
229