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