Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: chrome/browser/conflicts/module_database_win.h

Issue 2576843002: [win] Create ModuleDatabase and ModuleEventSinkImpl. (Closed)
Patch Set: Fix small bug. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/conflicts/OWNERS ('k') | chrome/browser/conflicts/module_database_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CHROME_BROWSER_CONFLICTS_MODULE_DATABASE_WIN_H_
6 #define CHROME_BROWSER_CONFLICTS_MODULE_DATABASE_WIN_H_
7
8 #include <map>
9 #include <utility>
10 #include <vector>
11
12 #include "base/files/file_path.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/sequenced_task_runner.h"
15 #include "content/public/common/process_type.h"
16
17 // A class that keeps track of all modules loaded across Chrome processes.
18 // Drives the chrome://conflicts UI.
19 class ModuleDatabase {
20 public:
21 // A ModuleDatabase is by default bound to a provided sequenced task runner.
22 // All calls must be made in the context of this task runner, unless
23 // otherwise noted. For calls from other contexts this task runner is used to
24 // bounce the call when appropriate.
25 explicit ModuleDatabase(scoped_refptr<base::SequencedTaskRunner> task_runner);
26 ~ModuleDatabase();
27
28 // Indicates that process with the given type has started. This must be called
29 // before any calls to OnModuleEvent or OnModuleUnload. Must be called in the
30 // same sequence as |task_runner_|.
31 void OnProcessStarted(uint32_t process_id,
32 uint64_t creation_time,
33 content::ProcessType process_type);
34
35 // Indicates that a module has been loaded. The data passed to this function
36 // is taken as gospel, so if it originates from a remote process it should be
37 // independently validated first. (In practice, see ModuleEventSinkImpl for
38 // details of where this happens.)
39 void OnModuleLoad(uint32_t process_id,
40 uint64_t creation_time,
41 const base::FilePath& module_path,
42 uint32_t module_size,
43 uint32_t module_time_date_stamp,
44 uintptr_t module_load_address);
45
46 // Indicates that the module at the given |load_address| in the specified
47 // process is being unloaded. This need not be trusted data, as it will be
48 // validated by the ModuleDatabase directly.
49 void OnModuleUnload(uint32_t process_id,
50 uint64_t creation_time,
51 uintptr_t module_load_address);
52
53 // Indicates that the given process has ended. This can be called from any
54 // thread and will be bounced to the |task_runner_|. In practice it will be
55 // invoked from the UI thread as the Mojo channel is torn down.
56 void OnProcessEnded(uint32_t process_id, uint64_t creation_time);
57
58 // TODO(chrisha): Module analysis code, and various accessors for use by
59 // chrome://conflicts.
60
61 private:
62 friend class TestModuleDatabase;
63 friend class ModuleDatabaseTest;
64 friend class ModuleEventSinkImplTest;
65
66 // Used by the FindLoadAddress* functions to indicate a load address has not
67 // been found.
68 static constexpr size_t kInvalidIndex = ~0u;
69
70 // Used as a unique identifier for a module in a ModuleSet.
71 using ModuleId = int;
72
73 // Structures for maintaining information about modules.
74 struct ModuleInfoKey;
75 struct ModuleInfoData;
76 using ModuleMap = std::map<ModuleInfoKey, ModuleInfoData>;
77 using ModuleInfo = ModuleMap::value_type;
78
79 // Used for maintaing a list of modules loaded in a process. Maps module IDs
80 // to load addresses.
81 using ModuleLoadAddresses = std::vector<std::pair<ModuleId, uintptr_t>>;
82
83 // Structures for maintaining information about running processes.
84 struct ProcessInfoKey;
85 struct ProcessInfoData;
86 using ProcessMap = std::map<ProcessInfoKey, ProcessInfoData>;
87 using ProcessInfo = ProcessMap::value_type;
88
89 // Converts a valid |process_type| to a bit for use in a bitmask of process
90 // values. Exposed in the header for testing.
91 static uint32_t ProcessTypeToBit(content::ProcessType process_type);
92
93 // Converts a |bit_index| (which maps to the bit 1 << bit_index) to the
94 // corresponding process type. Exposed in the header for testing.
95 static content::ProcessType BitIndexToProcessType(uint32_t bit_index);
96
97 // Performs a linear scan to find the index of a |module_id| or |load_address|
98 // in a collection of modules. Returns kInvalidIndex if the index is not
99 // found.
100 static size_t FindLoadAddressIndexById(
101 ModuleId module_id,
102 const ModuleLoadAddresses& load_addresses);
103 static size_t FindLoadAddressIndexByAddress(
104 uintptr_t load_address,
105 const ModuleLoadAddresses& load_addresses);
106
107 // Inserts a module into a ModuleLoadAddress object.
108 static void InsertLoadAddress(ModuleId module_id,
109 uintptr_t load_address,
110 ModuleLoadAddresses* load_addresses);
111
112 // Removes a module from a ModuleLoadAddress object, either by the
113 // |module_id| or the |index| in the collection.
114 static void RemoveLoadAddressById(ModuleId module_id,
115 ModuleLoadAddresses* load_addresses);
116 static void RemoveLoadAddressByIndex(size_t index,
117 ModuleLoadAddresses* load_addresses);
118
119 // Finds or creates a mutable ModuleInfo entry.
120 ModuleInfo* FindOrCreateModuleInfo(const base::FilePath& module_path,
121 uint32_t module_size,
122 uint32_t module_time_date_stamp);
123
124 // Finds a process info entry. Returns nullptr if none is found.
125 ProcessInfo* GetProcessInfo(uint32_t process_id, uint64_t creation_time);
126
127 // Creates a process info entry.
128 void CreateProcessInfo(uint32_t process_id,
129 uint64_t creation_time,
130 content::ProcessType process_type);
131
132 // Deletes a process info entry.
133 void DeleteProcessInfo(uint32_t process_id, uint64_t creation_time);
134
135 // The task runner to which this object is bound.
136 scoped_refptr<base::SequencedTaskRunner> task_runner_;
137
138 // A map of all known modules.
139 ModuleMap modules_;
140
141 // A map of all known running processes, and modules loaded/unloaded in
142 // them.
143 ProcessMap processes_;
144
145 // Weak pointer factory for this object. This is used when bouncing
146 // incoming events to |task_runner_|.
147 base::WeakPtrFactory<ModuleDatabase> weak_ptr_factory_;
148
149 DISALLOW_COPY_AND_ASSIGN(ModuleDatabase);
150 };
151
152 // Maintains information about a module. Modules are permanent once added to
153 // the ModuleSet, so this structure grows monotonically. In practice this is
154 // not an issue as the modules themselves are vastly bigger than the minor
155 // amount of metadata tracked here.
156
157 // This is the constant portion of the module information, and acts as the key
158 // in a std::map.
159 struct ModuleDatabase::ModuleInfoKey {
160 ModuleInfoKey(const base::FilePath& module_path,
161 uint32_t module_size,
162 uint32_t module_time_date_stamp,
163 uint32_t module_id);
164
165 // Less-than operator allowing this object to be used in std::map.
166 bool operator<(const ModuleInfoKey& mi) const;
167
168 // Full path to the module on disk. Part of the key for a ModuleInfo.
169 base::FilePath module_path;
170
171 // The module size. Part of the key for a ModuleInfo. This is taken from
172 // SizeOfImage from the module's IMAGE_OPTIONAL_HEADER.
173 uint32_t module_size;
174
175 // The module time date stamp. Part of the key for a ModuleInfo. Taken from
176 // TimeDateStamp from the module's IMAGE_FILE_HEADER.
177 uint32_t module_time_date_stamp;
178
179 // The ID of this module. This is a strictly incrementing value, and is used
180 // to tie a module to the list of running processes in which it is found.
181 // It is not part of the key for the module, but it is immutable. This is
182 // simply the index of the module in the insertion order.
183 ModuleId module_id;
184 };
185
186 // This is the mutable portion of the module information, and is the storage
187 // type in a std::map.
188 struct ModuleDatabase::ModuleInfoData {
189 ModuleInfoData();
190
191 // Set of all process types in which this module has been seen (may not be
192 // currently present in a process of that type). This is a conversion of
193 // ProcessType enumeration to a bitfield. See "ProcessTypeToBit" and
194 // "BitIndexToProcessType" for details.
195 uint32_t process_types;
196 };
197
198 // Information about a running process. This ties modules in a ModuleSet to
199 // processes in which they are (or have been) loaded.
200
201 // This is the constant portion of the process information, and acts as the key
202 // in a std::map.
203 struct ModuleDatabase::ProcessInfoKey {
204 ProcessInfoKey(uint32_t process_id,
205 uint64_t creation_time,
206 content::ProcessType process_type);
207 ~ProcessInfoKey();
208
209 // Less-than operator allowing this object to be used in std::map.
210 bool operator<(const ProcessInfoKey& pi) const;
211
212 // The process ID.
213 uint32_t process_id;
214
215 // The process creation time. A raw FILETIME value with full precision.
216 // Combined with |process_id| this uniquely identifies a process on a Windows
217 // system.
218 uint64_t creation_time;
219
220 // The type of the process.
221 content::ProcessType process_type;
222 };
223
224 // This is the mutable portion of the process information, and is the storage
225 // type in a std::map.
226 struct ModuleDatabase::ProcessInfoData {
227 ProcessInfoData();
228 ProcessInfoData(const ProcessInfoData& other);
229 ~ProcessInfoData();
230
231 // The sets of modules that are loaded/unloaded in this process, by ID. This
232 // is typically a small list so a linear cost is okay to pay for
233 // lookup/deletion (storage is backed by a vector).
234 //
235 // These are modified by the various static *LoadAddress* helper functions in
236 // ModuleDatabase. The vector maintains the invariant the element with maximum
237 // module ID is always last. This ensures that the usual operation of loading
238 // a module is O(1).
239 ModuleLoadAddresses loaded_modules;
240 ModuleLoadAddresses unloaded_modules;
241 };
242
243 #endif // CHROME_BROWSER_CONFLICTS_MODULE_DATABASE_WIN_H_
OLDNEW
« no previous file with comments | « chrome/browser/conflicts/OWNERS ('k') | chrome/browser/conflicts/module_database_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698