blob: 9176c9dbb357bfd9535b6063bbe42b5dfabb386f [file] [log] [blame]
Raphael Isemann80814282020-01-24 08:23:27 +01001//===-- ModuleList.cpp ----------------------------------------------------===//
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/ModuleList.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000010#include "lldb/Core/FileSpecList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000012#include "lldb/Core/ModuleSpec.h"
Pavel Labath1408bf72016-11-01 16:11:14 +000013#include "lldb/Host/FileSystem.h"
Adrian Prantl235354be2018-03-02 22:42:44 +000014#include "lldb/Interpreter/OptionValueFileSpec.h"
Pavel Labath27df2d92019-12-20 16:34:55 +010015#include "lldb/Interpreter/OptionValueFileSpecList.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000016#include "lldb/Interpreter/OptionValueProperties.h"
Adrian Prantl235354be2018-03-02 22:42:44 +000017#include "lldb/Interpreter/Property.h"
Zachary Turner80552912019-02-27 21:42:10 +000018#include "lldb/Symbol/LocateSymbolFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Symbol/ObjectFile.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000020#include "lldb/Symbol/SymbolContext.h"
Adrian Prantlbf9d84c2019-10-01 15:40:41 +000021#include "lldb/Symbol/TypeList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Symbol/VariableList.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000023#include "lldb/Utility/ArchSpec.h"
24#include "lldb/Utility/ConstString.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000025#include "lldb/Utility/Log.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000026#include "lldb/Utility/Logging.h"
27#include "lldb/Utility/UUID.h"
28#include "lldb/lldb-defines.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Nico Weberb1cb0b792018-04-10 13:33:45 +000030#if defined(_WIN32)
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000031#include "lldb/Host/windows/PosixApi.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000032#endif
33
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000034#include "clang/Driver/Driver.h"
35#include "llvm/ADT/StringRef.h"
Zachary Turner7d86ee52017-03-08 17:56:08 +000036#include "llvm/Support/FileSystem.h"
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000037#include "llvm/Support/Threading.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000038#include "llvm/Support/raw_ostream.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000039
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000040#include <chrono>
41#include <memory>
Zachary Turner2f3df612017-04-06 21:28:29 +000042#include <mutex>
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000043#include <string>
44#include <utility>
Zachary Turner2f3df612017-04-06 21:28:29 +000045
46namespace lldb_private {
47class Function;
48}
49namespace lldb_private {
50class RegularExpression;
51}
52namespace lldb_private {
53class Stream;
54}
55namespace lldb_private {
56class SymbolFile;
57}
58namespace lldb_private {
59class Target;
60}
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000061
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062using namespace lldb;
63using namespace lldb_private;
64
Adrian Prantl235354be2018-03-02 22:42:44 +000065namespace {
66
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000067#define LLDB_PROPERTIES_modulelist
Jordan Rupprecht6a253d32019-07-29 17:22:10 +000068#include "CoreProperties.inc"
Adrian Prantl235354be2018-03-02 22:42:44 +000069
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000070enum {
71#define LLDB_PROPERTIES_modulelist
Jordan Rupprecht6a253d32019-07-29 17:22:10 +000072#include "CorePropertiesEnum.inc"
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000073};
Adrian Prantl235354be2018-03-02 22:42:44 +000074
75} // namespace
76
77ModuleListProperties::ModuleListProperties() {
Jonas Devlieghere796ac802019-02-11 23:13:08 +000078 m_collection_sp =
79 std::make_shared<OptionValueProperties>(ConstString("symbols"));
Jonas Devliegherea8ea5952019-07-29 16:41:30 +000080 m_collection_sp->Initialize(g_modulelist_properties);
Pavel Labath27df2d92019-12-20 16:34:55 +010081 m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths,
82 [this] { UpdateSymlinkMappings(); });
Adrian Prantl235354be2018-03-02 22:42:44 +000083
84 llvm::SmallString<128> path;
Raphael Isemann208e3f52020-12-10 12:31:29 +010085 if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
86 lldbassert(SetClangModulesCachePath(FileSpec(path)));
87 }
Adrian Prantl235354be2018-03-02 22:42:44 +000088}
89
Adrian Prantl1cc1c5f2018-03-12 20:52:36 +000090bool ModuleListProperties::GetEnableExternalLookup() const {
91 const uint32_t idx = ePropertyEnableExternalLookup;
92 return m_collection_sp->GetPropertyAtIndexAsBoolean(
Jonas Devliegherea8ea5952019-07-29 16:41:30 +000093 nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
Adrian Prantl1cc1c5f2018-03-12 20:52:36 +000094}
95
Jan Kratochvil8c82c412019-06-17 14:46:17 +000096bool ModuleListProperties::SetEnableExternalLookup(bool new_value) {
97 return m_collection_sp->SetPropertyAtIndexAsBoolean(
98 nullptr, ePropertyEnableExternalLookup, new_value);
99}
100
Adrian Prantl235354be2018-03-02 22:42:44 +0000101FileSpec ModuleListProperties::GetClangModulesCachePath() const {
102 return m_collection_sp
103 ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
104 ePropertyClangModulesCachePath)
105 ->GetCurrentValue();
106}
107
Raphael Isemann208e3f52020-12-10 12:31:29 +0100108bool ModuleListProperties::SetClangModulesCachePath(const FileSpec &path) {
109 return m_collection_sp->SetPropertyAtIndexAsFileSpec(
Adrian Prantl235354be2018-03-02 22:42:44 +0000110 nullptr, ePropertyClangModulesCachePath, path);
111}
112
Pavel Labath27df2d92019-12-20 16:34:55 +0100113void ModuleListProperties::UpdateSymlinkMappings() {
114 FileSpecList list = m_collection_sp
115 ->GetPropertyAtIndexAsOptionValueFileSpecList(
116 nullptr, false, ePropertySymLinkPaths)
117 ->GetCurrentValue();
118 llvm::sys::ScopedWriter lock(m_symlink_paths_mutex);
119 const bool notify = false;
120 m_symlink_paths.Clear(notify);
121 for (FileSpec symlink : list) {
122 FileSpec resolved;
123 Status status = FileSystem::Instance().Readlink(symlink, resolved);
124 if (status.Success())
Xu Jundfd499a2021-11-01 22:14:48 -0700125 m_symlink_paths.Append(symlink.GetPath(), resolved.GetPath(), notify);
Pavel Labath27df2d92019-12-20 16:34:55 +0100126 }
127}
128
129PathMappingList ModuleListProperties::GetSymlinkMappings() const {
130 llvm::sys::ScopedReader lock(m_symlink_paths_mutex);
131 return m_symlink_paths;
132}
133
Jonas Devlieghere9494c512021-06-09 09:25:29 -0700134ModuleList::ModuleList() : m_modules(), m_modules_mutex() {}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135
136ModuleList::ModuleList(const ModuleList &rhs)
137 : m_modules(), m_modules_mutex(), m_notifier(nullptr) {
138 std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
139 std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
140 m_modules = rhs.m_modules;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141}
142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143ModuleList::ModuleList(ModuleList::Notifier *notifier)
144 : m_modules(), m_modules_mutex(), m_notifier(notifier) {}
Enrico Granata17598482012-11-08 02:22:02 +0000145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146const ModuleList &ModuleList::operator=(const ModuleList &rhs) {
147 if (this != &rhs) {
Jim Inghamcdd48922019-03-29 17:07:30 +0000148 std::lock(m_modules_mutex, rhs.m_modules_mutex);
Jonas Devlieghered4044aa2019-07-26 20:55:07 +0000149 std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex,
Jim Inghamcdd48922019-03-29 17:07:30 +0000150 std::adopt_lock);
Jonas Devlieghered4044aa2019-07-26 20:55:07 +0000151 std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex,
Jim Inghamcdd48922019-03-29 17:07:30 +0000152 std::adopt_lock);
153 m_modules = rhs.m_modules;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 }
155 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156}
157
Eugene Zelenkoc5dac77a2016-03-11 20:20:38 +0000158ModuleList::~ModuleList() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160void ModuleList::AppendImpl(const ModuleSP &module_sp, bool use_notifier) {
161 if (module_sp) {
162 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
163 m_modules.push_back(module_sp);
164 if (use_notifier && m_notifier)
Jason Molenda1724a172019-04-08 23:03:02 +0000165 m_notifier->NotifyModuleAdded(*this, module_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 }
167}
168
Jonas Devlieghered4044aa2019-07-26 20:55:07 +0000169void ModuleList::Append(const ModuleSP &module_sp, bool notify) {
170 AppendImpl(module_sp, notify);
Jason Molenda1724a172019-04-08 23:03:02 +0000171}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400173void ModuleList::ReplaceEquivalent(
174 const ModuleSP &module_sp,
175 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 if (module_sp) {
177 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
178
179 // First remove any equivalent modules. Equivalent modules are modules
180 // whose path, platform path and architecture match.
181 ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(),
182 module_sp->GetArchitecture());
183 equivalent_module_spec.GetPlatformFileSpec() =
184 module_sp->GetPlatformFileSpec();
185
186 size_t idx = 0;
187 while (idx < m_modules.size()) {
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400188 ModuleSP test_module_sp(m_modules[idx]);
189 if (test_module_sp->MatchesModuleSpec(equivalent_module_spec)) {
190 if (old_modules)
191 old_modules->push_back(test_module_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 RemoveImpl(m_modules.begin() + idx);
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400193 } else {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 ++idx;
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400195 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 }
197 // Now add the new module to the list
198 Append(module_sp);
199 }
200}
201
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200202bool ModuleList::AppendIfNeeded(const ModuleSP &new_module, bool notify) {
203 if (new_module) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200205 for (const ModuleSP &module_sp : m_modules) {
206 if (module_sp.get() == new_module.get())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 return false; // Already in the list
208 }
209 // Only push module_sp on the list if it wasn't already in there.
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200210 Append(new_module, notify);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 return true;
212 }
213 return false;
214}
215
216void ModuleList::Append(const ModuleList &module_list) {
217 for (auto pos : module_list.m_modules)
218 Append(pos);
219}
220
221bool ModuleList::AppendIfNeeded(const ModuleList &module_list) {
222 bool any_in = false;
223 for (auto pos : module_list.m_modules) {
224 if (AppendIfNeeded(pos))
225 any_in = true;
226 }
227 return any_in;
228}
229
230bool ModuleList::RemoveImpl(const ModuleSP &module_sp, bool use_notifier) {
231 if (module_sp) {
232 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
233 collection::iterator pos, end = m_modules.end();
234 for (pos = m_modules.begin(); pos != end; ++pos) {
235 if (pos->get() == module_sp.get()) {
236 m_modules.erase(pos);
Enrico Granata17598482012-11-08 02:22:02 +0000237 if (use_notifier && m_notifier)
Jason Molenda1724a172019-04-08 23:03:02 +0000238 m_notifier->NotifyModuleRemoved(*this, module_sp);
Greg Clayton8b82f082011-04-12 05:54:46 +0000239 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 }
243 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244}
245
Enrico Granata17598482012-11-08 02:22:02 +0000246ModuleList::collection::iterator
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247ModuleList::RemoveImpl(ModuleList::collection::iterator pos,
248 bool use_notifier) {
249 ModuleSP module_sp(*pos);
250 collection::iterator retval = m_modules.erase(pos);
251 if (use_notifier && m_notifier)
Jason Molenda1724a172019-04-08 23:03:02 +0000252 m_notifier->NotifyModuleRemoved(*this, module_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 return retval;
254}
255
Jason Molenda1724a172019-04-08 23:03:02 +0000256bool ModuleList::Remove(const ModuleSP &module_sp, bool notify) {
257 return RemoveImpl(module_sp, notify);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258}
259
260bool ModuleList::ReplaceModule(const lldb::ModuleSP &old_module_sp,
261 const lldb::ModuleSP &new_module_sp) {
262 if (!RemoveImpl(old_module_sp, false))
263 return false;
264 AppendImpl(new_module_sp, false);
265 if (m_notifier)
Jason Molenda1724a172019-04-08 23:03:02 +0000266 m_notifier->NotifyModuleUpdated(*this, old_module_sp, new_module_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 return true;
268}
269
270bool ModuleList::RemoveIfOrphaned(const Module *module_ptr) {
271 if (module_ptr) {
272 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
273 collection::iterator pos, end = m_modules.end();
274 for (pos = m_modules.begin(); pos != end; ++pos) {
275 if (pos->get() == module_ptr) {
276 if (pos->unique()) {
277 pos = RemoveImpl(pos);
278 return true;
279 } else
280 return false;
281 }
282 }
283 }
284 return false;
285}
286
287size_t ModuleList::RemoveOrphans(bool mandatory) {
288 std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
289
290 if (mandatory) {
291 lock.lock();
292 } else {
293 // Not mandatory, remove orphans if we can get the mutex
294 if (!lock.try_lock())
295 return 0;
296 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297 size_t remove_count = 0;
Raphael Isemann139e2a32020-07-20 10:47:21 +0200298 // Modules might hold shared pointers to other modules, so removing one
299 // module might make other other modules orphans. Keep removing modules until
300 // there are no further modules that can be removed.
301 bool made_progress = true;
302 while (made_progress) {
303 // Keep track if we make progress this iteration.
304 made_progress = false;
305 collection::iterator pos = m_modules.begin();
306 while (pos != m_modules.end()) {
307 if (pos->unique()) {
308 pos = RemoveImpl(pos);
309 ++remove_count;
310 // We did make progress.
311 made_progress = true;
312 } else {
313 ++pos;
314 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315 }
316 }
317 return remove_count;
318}
319
320size_t ModuleList::Remove(ModuleList &module_list) {
321 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
322 size_t num_removed = 0;
323 collection::iterator pos, end = module_list.m_modules.end();
324 for (pos = module_list.m_modules.begin(); pos != end; ++pos) {
Jason Molenda1724a172019-04-08 23:03:02 +0000325 if (Remove(*pos, false /* notify */))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 ++num_removed;
327 }
Jason Molenda1724a172019-04-08 23:03:02 +0000328 if (m_notifier)
329 m_notifier->NotifyModulesRemoved(module_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330 return num_removed;
331}
332
333void ModuleList::Clear() { ClearImpl(); }
334
335void ModuleList::Destroy() { ClearImpl(); }
336
337void ModuleList::ClearImpl(bool use_notifier) {
338 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
339 if (use_notifier && m_notifier)
Jason Molenda1724a172019-04-08 23:03:02 +0000340 m_notifier->NotifyWillClearList(*this);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 m_modules.clear();
342}
343
344Module *ModuleList::GetModulePointerAtIndex(size_t idx) const {
345 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 if (idx < m_modules.size())
347 return m_modules[idx].get();
348 return nullptr;
349}
350
351ModuleSP ModuleList::GetModuleAtIndex(size_t idx) const {
352 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
353 return GetModuleAtIndexUnlocked(idx);
354}
355
356ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {
357 ModuleSP module_sp;
358 if (idx < m_modules.size())
359 module_sp = m_modules[idx];
360 return module_sp;
361}
362
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000363void ModuleList::FindFunctions(ConstString name,
364 FunctionNameType name_type_mask,
Jonas Devliegherec020be12021-08-05 09:27:19 -0700365 const ModuleFunctionSearchOptions &options,
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000366 SymbolContextList &sc_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367 const size_t old_size = sc_list.GetSize();
368
369 if (name_type_mask & eFunctionNameTypeAuto) {
370 Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
371
372 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200373 for (const ModuleSP &module_sp : m_modules) {
374 module_sp->FindFunctions(lookup_info.GetLookupName(),
375 CompilerDeclContext(),
376 lookup_info.GetNameTypeMask(), options, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377 }
378
379 const size_t new_size = sc_list.GetSize();
380
381 if (old_size < new_size)
382 lookup_info.Prune(sc_list, old_size);
383 } else {
384 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200385 for (const ModuleSP &module_sp : m_modules) {
386 module_sp->FindFunctions(name, CompilerDeclContext(), name_type_mask,
387 options, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388 }
389 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390}
391
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000392void ModuleList::FindFunctionSymbols(ConstString name,
393 lldb::FunctionNameType name_type_mask,
394 SymbolContextList &sc_list) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 const size_t old_size = sc_list.GetSize();
396
397 if (name_type_mask & eFunctionNameTypeAuto) {
398 Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
399
400 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200401 for (const ModuleSP &module_sp : m_modules) {
402 module_sp->FindFunctionSymbols(lookup_info.GetLookupName(),
403 lookup_info.GetNameTypeMask(), sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404 }
405
406 const size_t new_size = sc_list.GetSize();
407
408 if (old_size < new_size)
409 lookup_info.Prune(sc_list, old_size);
410 } else {
411 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200412 for (const ModuleSP &module_sp : m_modules) {
413 module_sp->FindFunctionSymbols(name, name_type_mask, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 }
415 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416}
417
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000418void ModuleList::FindFunctions(const RegularExpression &name,
Jonas Devliegherec020be12021-08-05 09:27:19 -0700419 const ModuleFunctionSearchOptions &options,
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000420 SymbolContextList &sc_list) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200422 for (const ModuleSP &module_sp : m_modules)
423 module_sp->FindFunctions(name, options, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424}
425
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000426void ModuleList::FindCompileUnits(const FileSpec &path,
427 SymbolContextList &sc_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200429 for (const ModuleSP &module_sp : m_modules)
430 module_sp->FindCompileUnits(path, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000431}
432
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000433void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches,
434 VariableList &variable_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200436 for (const ModuleSP &module_sp : m_modules) {
437 module_sp->FindGlobalVariables(name, CompilerDeclContext(), max_matches,
438 variable_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440}
441
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000442void ModuleList::FindGlobalVariables(const RegularExpression &regex,
443 size_t max_matches,
444 VariableList &variable_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200446 for (const ModuleSP &module_sp : m_modules)
447 module_sp->FindGlobalVariables(regex, max_matches, variable_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448}
449
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000450void ModuleList::FindSymbolsWithNameAndType(ConstString name,
451 SymbolType symbol_type,
452 SymbolContextList &sc_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200454 for (const ModuleSP &module_sp : m_modules)
455 module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456}
457
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000458void ModuleList::FindSymbolsMatchingRegExAndType(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000459 const RegularExpression &regex, lldb::SymbolType symbol_type,
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000460 SymbolContextList &sc_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200462 for (const ModuleSP &module_sp : m_modules)
463 module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464}
465
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000466void ModuleList::FindModules(const ModuleSpec &module_spec,
467 ModuleList &matching_module_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200469 for (const ModuleSP &module_sp : m_modules) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000470 if (module_sp->MatchesModuleSpec(module_spec))
471 matching_module_list.Append(module_sp);
472 }
Enrico Granata17598482012-11-08 02:22:02 +0000473}
474
Kate Stoneb9c1b512016-09-06 20:57:50 +0000475ModuleSP ModuleList::FindModule(const Module *module_ptr) const {
476 ModuleSP module_sp;
Enrico Granata17598482012-11-08 02:22:02 +0000477
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478 // Scope for "locker"
479 {
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000480 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Carlo Kok0fd6fd42014-09-19 19:38:19 +0000481 collection::const_iterator pos, end = m_modules.end();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482
483 for (pos = m_modules.begin(); pos != end; ++pos) {
484 if ((*pos).get() == module_ptr) {
485 module_sp = (*pos);
486 break;
487 }
Carlo Kok0fd6fd42014-09-19 19:38:19 +0000488 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489 }
490 return module_sp;
Carlo Kok0fd6fd42014-09-19 19:38:19 +0000491}
492
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493ModuleSP ModuleList::FindModule(const UUID &uuid) const {
494 ModuleSP module_sp;
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496 if (uuid.IsValid()) {
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000497 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Greg Clayton644247c2011-07-07 01:59:51 +0000498 collection::const_iterator pos, end = m_modules.end();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499
500 for (pos = m_modules.begin(); pos != end; ++pos) {
501 if ((*pos)->GetUUID() == uuid) {
502 module_sp = (*pos);
503 break;
504 }
Greg Clayton644247c2011-07-07 01:59:51 +0000505 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506 }
507 return module_sp;
Greg Clayton644247c2011-07-07 01:59:51 +0000508}
509
Adrian Prantlbf9d84c2019-10-01 15:40:41 +0000510void ModuleList::FindTypes(Module *search_first, ConstString name,
511 bool name_is_fully_qualified, size_t max_matches,
512 llvm::DenseSet<SymbolFile *> &searched_symbol_files,
513 TypeList &types) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
515
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516 collection::const_iterator pos, end = m_modules.end();
Zachary Turner576495e2019-01-14 22:41:21 +0000517 if (search_first) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518 for (pos = m_modules.begin(); pos != end; ++pos) {
Zachary Turner576495e2019-01-14 22:41:21 +0000519 if (search_first == pos->get()) {
Adrian Prantlbf9d84c2019-10-01 15:40:41 +0000520 search_first->FindTypes(name, name_is_fully_qualified, max_matches,
521 searched_symbol_files, types);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522
Adrian Prantlbf9d84c2019-10-01 15:40:41 +0000523 if (types.GetSize() >= max_matches)
524 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528
Adrian Prantlbf9d84c2019-10-01 15:40:41 +0000529 for (pos = m_modules.begin(); pos != end; ++pos) {
530 // Search the module if the module is not equal to the one in the symbol
531 // context "sc". If "sc" contains a empty module shared pointer, then the
532 // comparison will always be true (valid_module_ptr != nullptr).
533 if (search_first != pos->get())
534 (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
535 searched_symbol_files, types);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000536
Adrian Prantlbf9d84c2019-10-01 15:40:41 +0000537 if (types.GetSize() >= max_matches)
538 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540}
541
Kate Stoneb9c1b512016-09-06 20:57:50 +0000542bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
543 FileSpec &new_spec) const {
544 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200545 for (const ModuleSP &module_sp : m_modules) {
546 if (module_sp->FindSourceFile(orig_spec, new_spec))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 return true;
548 }
549 return false;
Jim Ingham9683ff12011-11-19 00:19:25 +0000550}
551
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp,
553 const FileSpec &file, uint32_t line,
554 Function *function,
555 std::vector<Address> &output_local,
556 std::vector<Address> &output_extern) {
557 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200558 for (const ModuleSP &module_sp : m_modules) {
559 module_sp->FindAddressesForLine(target_sp, file, line, function,
560 output_local, output_extern);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562}
563
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564ModuleSP ModuleList::FindFirstModule(const ModuleSpec &module_spec) const {
565 ModuleSP module_sp;
566 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
567 collection::const_iterator pos, end = m_modules.end();
568 for (pos = m_modules.begin(); pos != end; ++pos) {
569 ModuleSP module_sp(*pos);
570 if (module_sp->MatchesModuleSpec(module_spec))
571 return module_sp;
572 }
573 return module_sp;
574}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575
Kate Stoneb9c1b512016-09-06 20:57:50 +0000576size_t ModuleList::GetSize() const {
577 size_t size = 0;
578 {
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000579 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 size = m_modules.size();
581 }
582 return size;
583}
584
585void ModuleList::Dump(Stream *s) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200587 for (const ModuleSP &module_sp : m_modules)
588 module_sp->Dump(s);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589}
590
591void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
592 if (log != nullptr) {
593 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
594 collection::const_iterator pos, begin = m_modules.begin(),
595 end = m_modules.end();
596 for (pos = begin; pos != end; ++pos) {
597 Module *module = pos->get();
598 const FileSpec &module_file_spec = module->GetFileSpec();
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000599 LLDB_LOGF(log, "%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "",
600 (uint32_t)std::distance(begin, pos),
601 module->GetUUID().GetAsString().c_str(),
602 module->GetArchitecture().GetArchitectureName(),
603 module_file_spec.GetPath().c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000604 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606}
607
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr,
609 Address &so_addr) const {
610 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200611 for (const ModuleSP &module_sp : m_modules) {
612 if (module_sp->ResolveFileAddress(vm_addr, so_addr))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 return true;
614 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616 return false;
617}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618
Zachary Turner991e4452018-10-25 20:45:19 +0000619uint32_t
620ModuleList::ResolveSymbolContextForAddress(const Address &so_addr,
621 SymbolContextItem resolve_scope,
622 SymbolContext &sc) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623 // The address is already section offset so it has a module
624 uint32_t resolved_flags = 0;
625 ModuleSP module_sp(so_addr.GetModule());
626 if (module_sp) {
627 resolved_flags =
628 module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
629 } else {
630 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
631 collection::const_iterator pos, end = m_modules.end();
632 for (pos = m_modules.begin(); pos != end; ++pos) {
633 resolved_flags =
634 (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
635 if (resolved_flags != 0)
636 break;
637 }
638 }
639
640 return resolved_flags;
641}
642
643uint32_t ModuleList::ResolveSymbolContextForFilePath(
644 const char *file_path, uint32_t line, bool check_inlines,
Zachary Turner991e4452018-10-25 20:45:19 +0000645 SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000646 FileSpec file_spec(file_path);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000647 return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
648 resolve_scope, sc_list);
649}
650
651uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
652 const FileSpec &file_spec, uint32_t line, bool check_inlines,
Zachary Turner991e4452018-10-25 20:45:19 +0000653 SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Raphael Isemann4cf9d1e2021-10-30 13:29:36 +0200655 for (const ModuleSP &module_sp : m_modules) {
656 module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
657 resolve_scope, sc_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 }
659
660 return sc_list.GetSize();
661}
662
663size_t ModuleList::GetIndexForModule(const Module *module) const {
664 if (module) {
665 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
666 collection::const_iterator pos;
667 collection::const_iterator begin = m_modules.begin();
668 collection::const_iterator end = m_modules.end();
669 for (pos = begin; pos != end; ++pos) {
670 if ((*pos).get() == module)
671 return std::distance(begin, pos);
672 }
673 }
674 return LLDB_INVALID_INDEX32;
675}
676
Adrian Prantl235354be2018-03-02 22:42:44 +0000677namespace {
678struct SharedModuleListInfo {
679 ModuleList module_list;
680 ModuleListProperties module_list_properties;
681};
682}
683static SharedModuleListInfo &GetSharedModuleListInfo()
684{
685 static SharedModuleListInfo *g_shared_module_list_info = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000686 static llvm::once_flag g_once_flag;
687 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688 // NOTE: Intentionally leak the module list so a program doesn't have to
689 // cleanup all modules and object files as it exits. This just wastes time
690 // doing a bunch of cleanup that isn't required.
Adrian Prantl235354be2018-03-02 22:42:44 +0000691 if (g_shared_module_list_info == nullptr)
692 g_shared_module_list_info = new SharedModuleListInfo();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693 });
Adrian Prantl235354be2018-03-02 22:42:44 +0000694 return *g_shared_module_list_info;
695}
696
697static ModuleList &GetSharedModuleList() {
698 return GetSharedModuleListInfo().module_list;
699}
700
701ModuleListProperties &ModuleList::GetGlobalModuleListProperties() {
702 return GetSharedModuleListInfo().module_list_properties;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703}
704
705bool ModuleList::ModuleIsInCache(const Module *module_ptr) {
706 if (module_ptr) {
707 ModuleList &shared_module_list = GetSharedModuleList();
708 return shared_module_list.FindModule(module_ptr).get() != nullptr;
709 }
710 return false;
711}
712
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000713void ModuleList::FindSharedModules(const ModuleSpec &module_spec,
714 ModuleList &matching_module_list) {
715 GetSharedModuleList().FindModules(module_spec, matching_module_list);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000716}
717
718size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) {
719 return GetSharedModuleList().RemoveOrphans(mandatory);
720}
721
Joseph Tremoulet61bfc702020-10-30 15:12:10 -0400722Status
723ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
724 const FileSpecList *module_search_paths_ptr,
725 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
726 bool *did_create_ptr, bool always_create) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 ModuleList &shared_module_list = GetSharedModuleList();
728 std::lock_guard<std::recursive_mutex> guard(
729 shared_module_list.m_modules_mutex);
730 char path[PATH_MAX];
731
Zachary Turner97206d52017-05-12 04:51:55 +0000732 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733
734 module_sp.reset();
735
736 if (did_create_ptr)
737 *did_create_ptr = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738
739 const UUID *uuid_ptr = module_spec.GetUUIDPtr();
740 const FileSpec &module_file_spec = module_spec.GetFileSpec();
741 const ArchSpec &arch = module_spec.GetArchitecture();
742
743 // Make sure no one else can try and get or create a module while this
Adrian Prantl05097242018-04-30 16:49:04 +0000744 // function is actively working on it by doing an extra lock on the global
745 // mutex list.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746 if (!always_create) {
747 ModuleList matching_module_list;
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000748 shared_module_list.FindModules(module_spec, matching_module_list);
749 const size_t num_matching_modules = matching_module_list.GetSize();
750
Kate Stoneb9c1b512016-09-06 20:57:50 +0000751 if (num_matching_modules > 0) {
752 for (size_t module_idx = 0; module_idx < num_matching_modules;
753 ++module_idx) {
754 module_sp = matching_module_list.GetModuleAtIndex(module_idx);
755
756 // Make sure the file for the module hasn't been modified
757 if (module_sp->FileHasChanged()) {
Joseph Tremoulet61bfc702020-10-30 15:12:10 -0400758 if (old_modules)
759 old_modules->push_back(module_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000760
761 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
762 if (log != nullptr)
Adrian Prantl03043602019-11-15 16:25:46 -0800763 LLDB_LOGF(
764 log, "%p '%s' module changed: removing from global module list",
765 static_cast<void *>(module_sp.get()),
766 module_sp->GetFileSpec().GetFilename().GetCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000767
768 shared_module_list.Remove(module_sp);
769 module_sp.reset();
770 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000771 // The module matches and the module was not modified from when it
772 // was last loaded.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000778
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 if (module_sp)
780 return error;
781
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000782 module_sp = std::make_shared<Module>(module_spec);
Adrian Prantl05097242018-04-30 16:49:04 +0000783 // Make sure there are a module and an object file since we can specify a
784 // valid file path with an architecture that might not be in that file. By
785 // getting the object file we can guarantee that the architecture matches
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 if (module_sp->GetObjectFile()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000787 // If we get in here we got the correct arch, now we just need to verify
788 // the UUID if one was given
Kate Stoneb9c1b512016-09-06 20:57:50 +0000789 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
790 module_sp.reset();
791 } else {
792 if (module_sp->GetObjectFile() &&
793 module_sp->GetObjectFile()->GetType() ==
794 ObjectFile::eTypeStubLibrary) {
795 module_sp.reset();
796 } else {
797 if (did_create_ptr) {
798 *did_create_ptr = true;
Greg Clayton32e0a752011-03-30 18:16:51 +0000799 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000800
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400801 shared_module_list.ReplaceEquivalent(module_sp, old_modules);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 return error;
803 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000804 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000805 } else {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000806 module_sp.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000807 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808
Kate Stoneb9c1b512016-09-06 20:57:50 +0000809 if (module_search_paths_ptr) {
810 const auto num_directories = module_search_paths_ptr->GetSize();
811 for (size_t idx = 0; idx < num_directories; ++idx) {
812 auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000813 FileSystem::Instance().Resolve(search_path_spec);
Zachary Turner7d86ee52017-03-08 17:56:08 +0000814 namespace fs = llvm::sys::fs;
Jonas Devlieghere3a58d892018-11-08 00:14:50 +0000815 if (!FileSystem::Instance().IsDirectory(search_path_spec))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 continue;
817 search_path_spec.AppendPathComponent(
Raphael Isemann642bc152020-02-11 09:05:37 +0100818 module_spec.GetFileSpec().GetFilename().GetStringRef());
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000819 if (!FileSystem::Instance().Exists(search_path_spec))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000821
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822 auto resolved_module_spec(module_spec);
823 resolved_module_spec.GetFileSpec() = search_path_spec;
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000824 module_sp = std::make_shared<Module>(resolved_module_spec);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825 if (module_sp->GetObjectFile()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000826 // If we get in here we got the correct arch, now we just need to
827 // verify the UUID if one was given
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
829 module_sp.reset();
830 } else {
831 if (module_sp->GetObjectFile()->GetType() ==
832 ObjectFile::eTypeStubLibrary) {
833 module_sp.reset();
834 } else {
835 if (did_create_ptr)
836 *did_create_ptr = true;
837
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400838 shared_module_list.ReplaceEquivalent(module_sp, old_modules);
Zachary Turner97206d52017-05-12 04:51:55 +0000839 return Status();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000840 }
841 }
842 } else {
843 module_sp.reset();
844 }
845 }
846 }
847
848 // Either the file didn't exist where at the path, or no path was given, so
849 // we now have to use more extreme measures to try and find the appropriate
850 // module.
851
Adrian Prantl05097242018-04-30 16:49:04 +0000852 // Fixup the incoming path in case the path points to a valid file, yet the
853 // arch or UUID (if one was passed in) don't match.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000854 ModuleSpec located_binary_modulespec =
855 Symbols::LocateExecutableObjectFile(module_spec);
856
857 // Don't look for the file if it appears to be the same one we already
858 // checked for above...
859 if (located_binary_modulespec.GetFileSpec() != module_file_spec) {
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000860 if (!FileSystem::Instance().Exists(
861 located_binary_modulespec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
863 if (path[0] == '\0')
864 module_file_spec.GetPath(path, sizeof(path));
865 // How can this check ever be true? This branch it is false, and we
866 // haven't modified file_spec.
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000867 if (FileSystem::Instance().Exists(
868 located_binary_modulespec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 std::string uuid_str;
870 if (uuid_ptr && uuid_ptr->IsValid())
871 uuid_str = uuid_ptr->GetAsString();
872
873 if (arch.IsValid()) {
874 if (!uuid_str.empty())
875 error.SetErrorStringWithFormat(
876 "'%s' does not contain the %s architecture and UUID %s", path,
877 arch.GetArchitectureName(), uuid_str.c_str());
878 else
879 error.SetErrorStringWithFormat(
880 "'%s' does not contain the %s architecture.", path,
881 arch.GetArchitectureName());
882 }
883 } else {
884 error.SetErrorStringWithFormat("'%s' does not exist", path);
885 }
886 if (error.Fail())
887 module_sp.reset();
888 return error;
889 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000890
Greg Claytonb9a01b32012-02-26 05:51:37 +0000891 // Make sure no one else can try and get or create a module while this
Adrian Prantl05097242018-04-30 16:49:04 +0000892 // function is actively working on it by doing an extra lock on the global
893 // mutex list.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000894 ModuleSpec platform_module_spec(module_spec);
895 platform_module_spec.GetFileSpec() =
896 located_binary_modulespec.GetFileSpec();
897 platform_module_spec.GetPlatformFileSpec() =
898 located_binary_modulespec.GetFileSpec();
899 platform_module_spec.GetSymbolFileSpec() =
900 located_binary_modulespec.GetSymbolFileSpec();
901 ModuleList matching_module_list;
Adrian Prantl1ad655e2019-10-17 19:56:40 +0000902 shared_module_list.FindModules(platform_module_spec, matching_module_list);
903 if (!matching_module_list.IsEmpty()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 module_sp = matching_module_list.GetModuleAtIndex(0);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000905
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906 // If we didn't have a UUID in mind when looking for the object file,
907 // then we should make sure the modification time hasn't changed!
908 if (platform_module_spec.GetUUIDPtr() == nullptr) {
Jonas Devlieghere46376962018-10-31 21:49:27 +0000909 auto file_spec_mod_time = FileSystem::Instance().GetModificationTime(
Pavel Labath3dc342eb2016-11-09 14:04:08 +0000910 located_binary_modulespec.GetFileSpec());
911 if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000912 if (file_spec_mod_time != module_sp->GetModificationTime()) {
Joseph Tremoulet61bfc702020-10-30 15:12:10 -0400913 if (old_modules)
914 old_modules->push_back(module_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000915 shared_module_list.Remove(module_sp);
Oleksiy Vyalov933f8532015-03-16 23:44:30 +0000916 module_sp.reset();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000917 }
Jason Molenda9c077cf2015-10-22 03:50:28 +0000918 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 }
Jason Molenda9c077cf2015-10-22 03:50:28 +0000920 }
Oleksiy Vyalov933f8532015-03-16 23:44:30 +0000921
Kate Stoneb9c1b512016-09-06 20:57:50 +0000922 if (!module_sp) {
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000923 module_sp = std::make_shared<Module>(platform_module_spec);
Adrian Prantl05097242018-04-30 16:49:04 +0000924 // Make sure there are a module and an object file since we can specify a
925 // valid file path with an architecture that might not be in that file.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000926 // By getting the object file we can guarantee that the architecture
927 // matches
928 if (module_sp && module_sp->GetObjectFile()) {
929 if (module_sp->GetObjectFile()->GetType() ==
930 ObjectFile::eTypeStubLibrary) {
931 module_sp.reset();
932 } else {
933 if (did_create_ptr)
934 *did_create_ptr = true;
Oleksiy Vyalov933f8532015-03-16 23:44:30 +0000935
Joseph Tremouletd20aa7c2020-10-30 15:13:26 -0400936 shared_module_list.ReplaceEquivalent(module_sp, old_modules);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000937 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000938 } else {
939 located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
940
941 if (located_binary_modulespec.GetFileSpec()) {
942 if (arch.IsValid())
943 error.SetErrorStringWithFormat(
944 "unable to open %s architecture in '%s'",
945 arch.GetArchitectureName(), path);
946 else
947 error.SetErrorStringWithFormat("unable to open '%s'", path);
948 } else {
949 std::string uuid_str;
950 if (uuid_ptr && uuid_ptr->IsValid())
951 uuid_str = uuid_ptr->GetAsString();
952
953 if (!uuid_str.empty())
954 error.SetErrorStringWithFormat(
955 "cannot locate a module for UUID '%s'", uuid_str.c_str());
956 else
Jonas Devlieghere89533762020-07-20 22:57:06 -0700957 error.SetErrorString("cannot locate a module");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000958 }
959 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000961 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963 return error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964}
965
Kate Stoneb9c1b512016-09-06 20:57:50 +0000966bool ModuleList::RemoveSharedModule(lldb::ModuleSP &module_sp) {
967 return GetSharedModuleList().Remove(module_sp);
Greg Clayton616f4902011-03-15 03:56:33 +0000968}
969
Kate Stoneb9c1b512016-09-06 20:57:50 +0000970bool ModuleList::RemoveSharedModuleIfOrphaned(const Module *module_ptr) {
971 return GetSharedModuleList().RemoveIfOrphaned(module_ptr);
Jim Ingham4a94c912012-05-17 18:38:42 +0000972}
973
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974bool ModuleList::LoadScriptingResourcesInTarget(Target *target,
Zachary Turner97206d52017-05-12 04:51:55 +0000975 std::list<Status> &errors,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000976 Stream *feedback_stream,
977 bool continue_on_error) {
978 if (!target)
979 return false;
980 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
981 for (auto module : m_modules) {
Zachary Turner97206d52017-05-12 04:51:55 +0000982 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000983 if (module) {
984 if (!module->LoadScriptingResourceInTarget(target, error,
985 feedback_stream)) {
986 if (error.Fail() && error.AsCString()) {
987 error.SetErrorStringWithFormat("unable to load scripting data for "
988 "module %s - error reported was %s",
989 module->GetFileSpec()
990 .GetFileNameStrippingExtension()
991 .GetCString(),
992 error.AsCString());
993 errors.push_back(error);
Greg Clayton994740f2014-08-18 21:08:44 +0000994
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 if (!continue_on_error)
996 return false;
Enrico Granata84a53df2013-05-20 22:29:23 +0000997 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998 }
Enrico Granata84a53df2013-05-20 22:29:23 +0000999 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 }
1001 return errors.empty();
Enrico Granata84a53df2013-05-20 22:29:23 +00001002}
Greg Claytond6346e62015-02-13 01:19:24 +00001003
Kate Stoneb9c1b512016-09-06 20:57:50 +00001004void ModuleList::ForEach(
1005 std::function<bool(const ModuleSP &module_sp)> const &callback) const {
1006 std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1007 for (const auto &module : m_modules) {
1008 // If the callback returns false, then stop iterating and break out
1009 if (!callback(module))
1010 break;
1011 }
Greg Claytond6346e62015-02-13 01:19:24 +00001012}