Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/ModuleList.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ModuleList.cpp ----------------------------------------------------===//
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
#include "lldb/Core/ModuleList.h"
10
#include "lldb/Core/FileSpecList.h"
11
#include "lldb/Core/Module.h"
12
#include "lldb/Core/ModuleSpec.h"
13
#include "lldb/Host/FileSystem.h"
14
#include "lldb/Interpreter/OptionValueFileSpec.h"
15
#include "lldb/Interpreter/OptionValueFileSpecList.h"
16
#include "lldb/Interpreter/OptionValueProperties.h"
17
#include "lldb/Interpreter/Property.h"
18
#include "lldb/Symbol/LocateSymbolFile.h"
19
#include "lldb/Symbol/ObjectFile.h"
20
#include "lldb/Symbol/SymbolContext.h"
21
#include "lldb/Symbol/TypeList.h"
22
#include "lldb/Symbol/VariableList.h"
23
#include "lldb/Utility/ArchSpec.h"
24
#include "lldb/Utility/ConstString.h"
25
#include "lldb/Utility/Log.h"
26
#include "lldb/Utility/Logging.h"
27
#include "lldb/Utility/UUID.h"
28
#include "lldb/lldb-defines.h"
29
30
#if defined(_WIN32)
31
#include "lldb/Host/windows/PosixApi.h"
32
#endif
33
34
#include "clang/Driver/Driver.h"
35
#include "llvm/ADT/StringRef.h"
36
#include "llvm/Support/FileSystem.h"
37
#include "llvm/Support/Threading.h"
38
#include "llvm/Support/raw_ostream.h"
39
40
#include <chrono>
41
#include <memory>
42
#include <mutex>
43
#include <string>
44
#include <utility>
45
46
namespace lldb_private {
47
class Function;
48
}
49
namespace lldb_private {
50
class RegularExpression;
51
}
52
namespace lldb_private {
53
class Stream;
54
}
55
namespace lldb_private {
56
class SymbolFile;
57
}
58
namespace lldb_private {
59
class Target;
60
}
61
62
using namespace lldb;
63
using namespace lldb_private;
64
65
namespace {
66
67
#define LLDB_PROPERTIES_modulelist
68
#include "CoreProperties.inc"
69
70
enum {
71
#define LLDB_PROPERTIES_modulelist
72
#include "CorePropertiesEnum.inc"
73
};
74
75
} // namespace
76
77
3.44k
ModuleListProperties::ModuleListProperties() {
78
3.44k
  m_collection_sp =
79
3.44k
      std::make_shared<OptionValueProperties>(ConstString("symbols"));
80
3.44k
  m_collection_sp->Initialize(g_modulelist_properties);
81
3.44k
  m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths,
82
3.44k
                                           [this] 
{ UpdateSymlinkMappings(); }11
);
83
84
3.44k
  llvm::SmallString<128> path;
85
3.44k
  if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
86
3.44k
    lldbassert(SetClangModulesCachePath(FileSpec(path)));
87
3.44k
  }
88
89
3.44k
  path.clear();
90
3.44k
  if (llvm::sys::path::cache_directory(path)) {
91
3.44k
    llvm::sys::path::append(path, "lldb");
92
3.44k
    llvm::sys::path::append(path, "IndexCache");
93
3.44k
    lldbassert(SetLLDBIndexCachePath(FileSpec(path)));
94
3.44k
  }
95
96
3.44k
}
97
98
286k
bool ModuleListProperties::GetEnableExternalLookup() const {
99
286k
  const uint32_t idx = ePropertyEnableExternalLookup;
100
286k
  return m_collection_sp->GetPropertyAtIndexAsBoolean(
101
286k
      nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
102
286k
}
103
104
91
bool ModuleListProperties::SetEnableExternalLookup(bool new_value) {
105
91
  return m_collection_sp->SetPropertyAtIndexAsBoolean(
106
91
      nullptr, ePropertyEnableExternalLookup, new_value);
107
91
}
108
109
2.21k
FileSpec ModuleListProperties::GetClangModulesCachePath() const {
110
2.21k
  return m_collection_sp
111
2.21k
      ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
112
2.21k
                                                ePropertyClangModulesCachePath)
113
2.21k
      ->GetCurrentValue();
114
2.21k
}
115
116
3.44k
bool ModuleListProperties::SetClangModulesCachePath(const FileSpec &path) {
117
3.44k
  return m_collection_sp->SetPropertyAtIndexAsFileSpec(
118
3.44k
      nullptr, ePropertyClangModulesCachePath, path);
119
3.44k
}
120
121
4
FileSpec ModuleListProperties::GetLLDBIndexCachePath() const {
122
4
  return m_collection_sp
123
4
      ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
124
4
                                                ePropertyLLDBIndexCachePath)
125
4
      ->GetCurrentValue();
126
4
}
127
128
3.44k
bool ModuleListProperties::SetLLDBIndexCachePath(const FileSpec &path) {
129
3.44k
  return m_collection_sp->SetPropertyAtIndexAsFileSpec(
130
3.44k
      nullptr, ePropertyLLDBIndexCachePath, path);
131
3.44k
}
132
133
291k
bool ModuleListProperties::GetEnableLLDBIndexCache() const {
134
291k
  const uint32_t idx = ePropertyEnableLLDBIndexCache;
135
291k
  return m_collection_sp->GetPropertyAtIndexAsBoolean(
136
291k
      nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
137
291k
}
138
139
0
bool ModuleListProperties::SetEnableLLDBIndexCache(bool new_value) {
140
0
  return m_collection_sp->SetPropertyAtIndexAsBoolean(
141
0
      nullptr, ePropertyEnableLLDBIndexCache, new_value);
142
0
}
143
144
4
uint64_t ModuleListProperties::GetLLDBIndexCacheMaxByteSize() {
145
4
  const uint32_t idx = ePropertyLLDBIndexCacheMaxByteSize;
146
4
  return m_collection_sp->GetPropertyAtIndexAsUInt64(
147
4
      nullptr, idx, g_modulelist_properties[idx].default_uint_value);
148
4
}
149
150
4
uint64_t ModuleListProperties::GetLLDBIndexCacheMaxPercent() {
151
4
  const uint32_t idx = ePropertyLLDBIndexCacheMaxPercent;
152
4
  return m_collection_sp->GetPropertyAtIndexAsUInt64(
153
4
      nullptr, idx, g_modulelist_properties[idx].default_uint_value);
154
4
}
155
156
4
uint64_t ModuleListProperties::GetLLDBIndexCacheExpirationDays() {
157
4
  const uint32_t idx = ePropertyLLDBIndexCacheExpirationDays;
158
4
  return m_collection_sp->GetPropertyAtIndexAsUInt64(
159
4
      nullptr, idx, g_modulelist_properties[idx].default_uint_value);
160
4
}
161
162
11
void ModuleListProperties::UpdateSymlinkMappings() {
163
11
  FileSpecList list = m_collection_sp
164
11
                          ->GetPropertyAtIndexAsOptionValueFileSpecList(
165
11
                              nullptr, false, ePropertySymLinkPaths)
166
11
                          ->GetCurrentValue();
167
11
  llvm::sys::ScopedWriter lock(m_symlink_paths_mutex);
168
11
  const bool notify = false;
169
11
  m_symlink_paths.Clear(notify);
170
11
  for (FileSpec symlink : list) {
171
3
    FileSpec resolved;
172
3
    Status status = FileSystem::Instance().Readlink(symlink, resolved);
173
3
    if (status.Success())
174
3
      m_symlink_paths.Append(symlink.GetPath(), resolved.GetPath(), notify);
175
3
  }
176
11
}
177
178
145k
PathMappingList ModuleListProperties::GetSymlinkMappings() const {
179
145k
  llvm::sys::ScopedReader lock(m_symlink_paths_mutex);
180
145k
  return m_symlink_paths;
181
145k
}
182
183
480k
ModuleList::ModuleList() : m_modules(), m_modules_mutex() {}
184
185
ModuleList::ModuleList(const ModuleList &rhs)
186
19.8k
    : m_modules(), m_modules_mutex(), m_notifier(nullptr) {
187
19.8k
  std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
188
19.8k
  std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
189
19.8k
  m_modules = rhs.m_modules;
190
19.8k
}
191
192
ModuleList::ModuleList(ModuleList::Notifier *notifier)
193
9.03k
    : m_modules(), m_modules_mutex(), m_notifier(notifier) {}
194
195
83
const ModuleList &ModuleList::operator=(const ModuleList &rhs) {
196
83
  if (this != &rhs) {
197
83
    std::lock(m_modules_mutex, rhs.m_modules_mutex);
198
83
    std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex,
199
83
                                                    std::adopt_lock);
200
83
    std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex,
201
83
                                                    std::adopt_lock);
202
83
    m_modules = rhs.m_modules;
203
83
  }
204
83
  return *this;
205
83
}
206
207
505k
ModuleList::~ModuleList() = default;
208
209
1.11M
void ModuleList::AppendImpl(const ModuleSP &module_sp, bool use_notifier) {
210
1.11M
  if (module_sp) {
211
1.11M
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
212
1.11M
    m_modules.push_back(module_sp);
213
1.11M
    if (use_notifier && 
m_notifier709k
)
214
9.11k
      m_notifier->NotifyModuleAdded(*this, module_sp);
215
1.11M
  }
216
1.11M
}
217
218
1.11M
void ModuleList::Append(const ModuleSP &module_sp, bool notify) {
219
1.11M
  AppendImpl(module_sp, notify);
220
1.11M
}
221
222
void ModuleList::ReplaceEquivalent(
223
    const ModuleSP &module_sp,
224
136k
    llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules) {
225
136k
  if (module_sp) {
226
136k
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
227
228
    // First remove any equivalent modules. Equivalent modules are modules
229
    // whose path, platform path and architecture match.
230
136k
    ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(),
231
136k
                                      module_sp->GetArchitecture());
232
136k
    equivalent_module_spec.GetPlatformFileSpec() =
233
136k
        module_sp->GetPlatformFileSpec();
234
235
136k
    size_t idx = 0;
236
4.90M
    while (idx < m_modules.size()) {
237
4.77M
      ModuleSP test_module_sp(m_modules[idx]);
238
4.77M
      if (test_module_sp->MatchesModuleSpec(equivalent_module_spec)) {
239
3
        if (old_modules)
240
3
          old_modules->push_back(test_module_sp);
241
3
        RemoveImpl(m_modules.begin() + idx);
242
4.77M
      } else {
243
4.77M
        ++idx;
244
4.77M
      }
245
4.77M
    }
246
    // Now add the new module to the list
247
136k
    Append(module_sp);
248
136k
  }
249
136k
}
250
251
550k
bool ModuleList::AppendIfNeeded(const ModuleSP &new_module, bool notify) {
252
550k
  if (new_module) {
253
550k
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
254
17.8M
    for (const ModuleSP &module_sp : m_modules) {
255
17.8M
      if (module_sp.get() == new_module.get())
256
138k
        return false; // Already in the list
257
17.8M
    }
258
    // Only push module_sp on the list if it wasn't already in there.
259
412k
    Append(new_module, notify);
260
412k
    return true;
261
550k
  }
262
0
  return false;
263
550k
}
264
265
0
void ModuleList::Append(const ModuleList &module_list) {
266
0
  for (auto pos : module_list.m_modules)
267
0
    Append(pos);
268
0
}
269
270
3
bool ModuleList::AppendIfNeeded(const ModuleList &module_list) {
271
3
  bool any_in = false;
272
3
  for (auto pos : module_list.m_modules) {
273
3
    if (AppendIfNeeded(pos))
274
0
      any_in = true;
275
3
  }
276
3
  return any_in;
277
3
}
278
279
138k
bool ModuleList::RemoveImpl(const ModuleSP &module_sp, bool use_notifier) {
280
138k
  if (module_sp) {
281
138k
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
282
138k
    collection::iterator pos, end = m_modules.end();
283
505k
    for (pos = m_modules.begin(); pos != end; 
++pos367k
) {
284
505k
      if (pos->get() == module_sp.get()) {
285
138k
        m_modules.erase(pos);
286
138k
        if (use_notifier && 
m_notifier5.88k
)
287
5.88k
          m_notifier->NotifyModuleRemoved(*this, module_sp);
288
138k
        return true;
289
138k
      }
290
505k
    }
291
138k
  }
292
1
  return false;
293
138k
}
294
295
ModuleList::collection::iterator
296
ModuleList::RemoveImpl(ModuleList::collection::iterator pos,
297
131k
                       bool use_notifier) {
298
131k
  ModuleSP module_sp(*pos);
299
131k
  collection::iterator retval = m_modules.erase(pos);
300
131k
  if (use_notifier && m_notifier)
301
0
    m_notifier->NotifyModuleRemoved(*this, module_sp);
302
131k
  return retval;
303
131k
}
304
305
138k
bool ModuleList::Remove(const ModuleSP &module_sp, bool notify) {
306
138k
  return RemoveImpl(module_sp, notify);
307
138k
}
308
309
bool ModuleList::ReplaceModule(const lldb::ModuleSP &old_module_sp,
310
1
                               const lldb::ModuleSP &new_module_sp) {
311
1
  if (!RemoveImpl(old_module_sp, false))
312
0
    return false;
313
1
  AppendImpl(new_module_sp, false);
314
1
  if (m_notifier)
315
1
    m_notifier->NotifyModuleUpdated(*this, old_module_sp, new_module_sp);
316
1
  return true;
317
1
}
318
319
1
bool ModuleList::RemoveIfOrphaned(const Module *module_ptr) {
320
1
  if (module_ptr) {
321
1
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
322
1
    collection::iterator pos, end = m_modules.end();
323
2
    for (pos = m_modules.begin(); pos != end; 
++pos1
) {
324
1
      if (pos->get() == module_ptr) {
325
0
        if (pos->unique()) {
326
0
          pos = RemoveImpl(pos);
327
0
          return true;
328
0
        } else
329
0
          return false;
330
0
      }
331
1
    }
332
1
  }
333
1
  return false;
334
1
}
335
336
3.42k
size_t ModuleList::RemoveOrphans(bool mandatory) {
337
3.42k
  std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
338
339
3.42k
  if (mandatory) {
340
0
    lock.lock();
341
3.42k
  } else {
342
    // Not mandatory, remove orphans if we can get the mutex
343
3.42k
    if (!lock.try_lock())
344
0
      return 0;
345
3.42k
  }
346
3.42k
  size_t remove_count = 0;
347
  // Modules might hold shared pointers to other modules, so removing one
348
  // module might make other other modules orphans. Keep removing modules until
349
  // there are no further modules that can be removed.
350
3.42k
  bool made_progress = true;
351
10.1k
  while (made_progress) {
352
    // Keep track if we make progress this iteration.
353
6.70k
    made_progress = false;
354
6.70k
    collection::iterator pos = m_modules.begin();
355
142k
    while (pos != m_modules.end()) {
356
135k
      if (pos->unique()) {
357
131k
        pos = RemoveImpl(pos);
358
131k
        ++remove_count;
359
        // We did make progress.
360
131k
        made_progress = true;
361
131k
      } else {
362
4.30k
        ++pos;
363
4.30k
      }
364
135k
    }
365
6.70k
  }
366
3.42k
  return remove_count;
367
3.42k
}
368
369
2.59k
size_t ModuleList::Remove(ModuleList &module_list) {
370
2.59k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
371
2.59k
  size_t num_removed = 0;
372
2.59k
  collection::iterator pos, end = module_list.m_modules.end();
373
135k
  for (pos = module_list.m_modules.begin(); pos != end; 
++pos132k
) {
374
132k
    if (Remove(*pos, false /* notify */))
375
132k
      ++num_removed;
376
132k
  }
377
2.59k
  if (m_notifier)
378
2.59k
    m_notifier->NotifyModulesRemoved(module_list);
379
2.59k
  return num_removed;
380
2.59k
}
381
382
5.99k
void ModuleList::Clear() { ClearImpl(); }
383
384
0
void ModuleList::Destroy() { ClearImpl(); }
385
386
5.99k
void ModuleList::ClearImpl(bool use_notifier) {
387
5.99k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
388
5.99k
  if (use_notifier && m_notifier)
389
5.97k
    m_notifier->NotifyWillClearList(*this);
390
5.99k
  m_modules.clear();
391
5.99k
}
392
393
457
Module *ModuleList::GetModulePointerAtIndex(size_t idx) const {
394
457
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
395
457
  if (idx < m_modules.size())
396
457
    return m_modules[idx].get();
397
0
  return nullptr;
398
457
}
399
400
738k
ModuleSP ModuleList::GetModuleAtIndex(size_t idx) const {
401
738k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
402
738k
  return GetModuleAtIndexUnlocked(idx);
403
738k
}
404
405
739k
ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {
406
739k
  ModuleSP module_sp;
407
739k
  if (idx < m_modules.size())
408
720k
    module_sp = m_modules[idx];
409
739k
  return module_sp;
410
739k
}
411
412
void ModuleList::FindFunctions(ConstString name,
413
                               FunctionNameType name_type_mask,
414
                               const ModuleFunctionSearchOptions &options,
415
31.1k
                               SymbolContextList &sc_list) const {
416
31.1k
  const size_t old_size = sc_list.GetSize();
417
418
31.1k
  if (name_type_mask & eFunctionNameTypeAuto) {
419
17.2k
    Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
420
421
17.2k
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
422
2.06M
    for (const ModuleSP &module_sp : m_modules) {
423
2.06M
      module_sp->FindFunctions(lookup_info.GetLookupName(),
424
2.06M
                               CompilerDeclContext(),
425
2.06M
                               lookup_info.GetNameTypeMask(), options, sc_list);
426
2.06M
    }
427
428
17.2k
    const size_t new_size = sc_list.GetSize();
429
430
17.2k
    if (old_size < new_size)
431
17.2k
      lookup_info.Prune(sc_list, old_size);
432
17.2k
  } else {
433
13.8k
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
434
859k
    for (const ModuleSP &module_sp : m_modules) {
435
859k
      module_sp->FindFunctions(name, CompilerDeclContext(), name_type_mask,
436
859k
                               options, sc_list);
437
859k
    }
438
13.8k
  }
439
31.1k
}
440
441
void ModuleList::FindFunctionSymbols(ConstString name,
442
                                     lldb::FunctionNameType name_type_mask,
443
250
                                     SymbolContextList &sc_list) {
444
250
  const size_t old_size = sc_list.GetSize();
445
446
250
  if (name_type_mask & eFunctionNameTypeAuto) {
447
250
    Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
448
449
250
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
450
10.2k
    for (const ModuleSP &module_sp : m_modules) {
451
10.2k
      module_sp->FindFunctionSymbols(lookup_info.GetLookupName(),
452
10.2k
                                     lookup_info.GetNameTypeMask(), sc_list);
453
10.2k
    }
454
455
250
    const size_t new_size = sc_list.GetSize();
456
457
250
    if (old_size < new_size)
458
250
      lookup_info.Prune(sc_list, old_size);
459
250
  } else {
460
0
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
461
0
    for (const ModuleSP &module_sp : m_modules) {
462
0
      module_sp->FindFunctionSymbols(name, name_type_mask, sc_list);
463
0
    }
464
0
  }
465
250
}
466
467
void ModuleList::FindFunctions(const RegularExpression &name,
468
                               const ModuleFunctionSearchOptions &options,
469
0
                               SymbolContextList &sc_list) {
470
0
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
471
0
  for (const ModuleSP &module_sp : m_modules)
472
0
    module_sp->FindFunctions(name, options, sc_list);
473
0
}
474
475
void ModuleList::FindCompileUnits(const FileSpec &path,
476
15
                                  SymbolContextList &sc_list) const {
477
15
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
478
15
  for (const ModuleSP &module_sp : m_modules)
479
600
    module_sp->FindCompileUnits(path, sc_list);
480
15
}
481
482
void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches,
483
3.95k
                                     VariableList &variable_list) const {
484
3.95k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
485
179k
  for (const ModuleSP &module_sp : m_modules) {
486
179k
    module_sp->FindGlobalVariables(name, CompilerDeclContext(), max_matches,
487
179k
                                   variable_list);
488
179k
  }
489
3.95k
}
490
491
void ModuleList::FindGlobalVariables(const RegularExpression &regex,
492
                                     size_t max_matches,
493
0
                                     VariableList &variable_list) const {
494
0
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
495
0
  for (const ModuleSP &module_sp : m_modules)
496
0
    module_sp->FindGlobalVariables(regex, max_matches, variable_list);
497
0
}
498
499
void ModuleList::FindSymbolsWithNameAndType(ConstString name,
500
                                            SymbolType symbol_type,
501
14.7k
                                            SymbolContextList &sc_list) const {
502
14.7k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
503
14.7k
  for (const ModuleSP &module_sp : m_modules)
504
754k
    module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
505
14.7k
}
506
507
void ModuleList::FindSymbolsMatchingRegExAndType(
508
    const RegularExpression &regex, lldb::SymbolType symbol_type,
509
0
    SymbolContextList &sc_list) const {
510
0
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
511
0
  for (const ModuleSP &module_sp : m_modules)
512
0
    module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
513
0
}
514
515
void ModuleList::FindModules(const ModuleSpec &module_spec,
516
416k
                             ModuleList &matching_module_list) const {
517
416k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
518
19.8M
  for (const ModuleSP &module_sp : m_modules) {
519
19.8M
    if (module_sp->MatchesModuleSpec(module_spec))
520
145k
      matching_module_list.Append(module_sp);
521
19.8M
  }
522
416k
}
523
524
0
ModuleSP ModuleList::FindModule(const Module *module_ptr) const {
525
0
  ModuleSP module_sp;
526
527
  // Scope for "locker"
528
0
  {
529
0
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
530
0
    collection::const_iterator pos, end = m_modules.end();
531
532
0
    for (pos = m_modules.begin(); pos != end; ++pos) {
533
0
      if ((*pos).get() == module_ptr) {
534
0
        module_sp = (*pos);
535
0
        break;
536
0
      }
537
0
    }
538
0
  }
539
0
  return module_sp;
540
0
}
541
542
0
ModuleSP ModuleList::FindModule(const UUID &uuid) const {
543
0
  ModuleSP module_sp;
544
545
0
  if (uuid.IsValid()) {
546
0
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
547
0
    collection::const_iterator pos, end = m_modules.end();
548
549
0
    for (pos = m_modules.begin(); pos != end; ++pos) {
550
0
      if ((*pos)->GetUUID() == uuid) {
551
0
        module_sp = (*pos);
552
0
        break;
553
0
      }
554
0
    }
555
0
  }
556
0
  return module_sp;
557
0
}
558
559
void ModuleList::FindTypes(Module *search_first, ConstString name,
560
                           bool name_is_fully_qualified, size_t max_matches,
561
                           llvm::DenseSet<SymbolFile *> &searched_symbol_files,
562
13.3k
                           TypeList &types) const {
563
13.3k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
564
565
13.3k
  collection::const_iterator pos, end = m_modules.end();
566
13.3k
  if (search_first) {
567
408
    for (pos = m_modules.begin(); pos != end; 
++pos396
) {
568
399
      if (search_first == pos->get()) {
569
12
        search_first->FindTypes(name, name_is_fully_qualified, max_matches,
570
12
                                searched_symbol_files, types);
571
572
12
        if (types.GetSize() >= max_matches)
573
3
          return;
574
12
      }
575
399
    }
576
12
  }
577
578
591k
  
for (pos = m_modules.begin(); 13.2k
pos != end;
++pos578k
) {
579
    // Search the module if the module is not equal to the one in the symbol
580
    // context "sc". If "sc" contains a empty module shared pointer, then the
581
    // comparison will always be true (valid_module_ptr != nullptr).
582
578k
    if (search_first != pos->get())
583
578k
      (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
584
578k
                        searched_symbol_files, types);
585
586
578k
    if (types.GetSize() >= max_matches)
587
797
      return;
588
578k
  }
589
13.2k
}
590
591
bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
592
34
                                FileSpec &new_spec) const {
593
34
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
594
98
  for (const ModuleSP &module_sp : m_modules) {
595
98
    if (module_sp->FindSourceFile(orig_spec, new_spec))
596
0
      return true;
597
98
  }
598
34
  return false;
599
34
}
600
601
void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp,
602
                                      const FileSpec &file, uint32_t line,
603
                                      Function *function,
604
                                      std::vector<Address> &output_local,
605
30
                                      std::vector<Address> &output_extern) {
606
30
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
607
1.29k
  for (const ModuleSP &module_sp : m_modules) {
608
1.29k
    module_sp->FindAddressesForLine(target_sp, file, line, function,
609
1.29k
                                    output_local, output_extern);
610
1.29k
  }
611
30
}
612
613
277k
ModuleSP ModuleList::FindFirstModule(const ModuleSpec &module_spec) const {
614
277k
  ModuleSP module_sp;
615
277k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
616
277k
  collection::const_iterator pos, end = m_modules.end();
617
9.37M
  for (pos = m_modules.begin(); pos != end; 
++pos9.09M
) {
618
9.10M
    ModuleSP module_sp(*pos);
619
9.10M
    if (module_sp->MatchesModuleSpec(module_spec))
620
10.3k
      return module_sp;
621
9.10M
  }
622
266k
  return module_sp;
623
277k
}
624
625
459k
size_t ModuleList::GetSize() const {
626
459k
  size_t size = 0;
627
459k
  {
628
459k
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
629
459k
    size = m_modules.size();
630
459k
  }
631
459k
  return size;
632
459k
}
633
634
3
void ModuleList::Dump(Stream *s) const {
635
3
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
636
3
  for (const ModuleSP &module_sp : m_modules)
637
120
    module_sp->Dump(s);
638
3
}
639
640
0
void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
641
0
  if (log != nullptr) {
642
0
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
643
0
    collection::const_iterator pos, begin = m_modules.begin(),
644
0
                                    end = m_modules.end();
645
0
    for (pos = begin; pos != end; ++pos) {
646
0
      Module *module = pos->get();
647
0
      const FileSpec &module_file_spec = module->GetFileSpec();
648
0
      LLDB_LOGF(log, "%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "",
649
0
                (uint32_t)std::distance(begin, pos),
650
0
                module->GetUUID().GetAsString().c_str(),
651
0
                module->GetArchitecture().GetArchitectureName(),
652
0
                module_file_spec.GetPath().c_str());
653
0
    }
654
0
  }
655
0
}
656
657
bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr,
658
282
                                    Address &so_addr) const {
659
282
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
660
282
  for (const ModuleSP &module_sp : m_modules) {
661
254
    if (module_sp->ResolveFileAddress(vm_addr, so_addr))
662
254
      return true;
663
254
  }
664
665
28
  return false;
666
282
}
667
668
uint32_t
669
ModuleList::ResolveSymbolContextForAddress(const Address &so_addr,
670
                                           SymbolContextItem resolve_scope,
671
65.4k
                                           SymbolContext &sc) const {
672
  // The address is already section offset so it has a module
673
65.4k
  uint32_t resolved_flags = 0;
674
65.4k
  ModuleSP module_sp(so_addr.GetModule());
675
65.4k
  if (module_sp) {
676
64.8k
    resolved_flags =
677
64.8k
        module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
678
64.8k
  } else {
679
596
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
680
596
    collection::const_iterator pos, end = m_modules.end();
681
5.88k
    for (pos = m_modules.begin(); pos != end; 
++pos5.28k
) {
682
5.28k
      resolved_flags =
683
5.28k
          (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
684
5.28k
      if (resolved_flags != 0)
685
0
        break;
686
5.28k
    }
687
596
  }
688
689
65.4k
  return resolved_flags;
690
65.4k
}
691
692
uint32_t ModuleList::ResolveSymbolContextForFilePath(
693
    const char *file_path, uint32_t line, bool check_inlines,
694
6
    SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
695
6
  FileSpec file_spec(file_path);
696
6
  return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
697
6
                                          resolve_scope, sc_list);
698
6
}
699
700
uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
701
    const FileSpec &file_spec, uint32_t line, bool check_inlines,
702
6
    SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
703
6
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
704
123
  for (const ModuleSP &module_sp : m_modules) {
705
123
    module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
706
123
                                                resolve_scope, sc_list);
707
123
  }
708
709
6
  return sc_list.GetSize();
710
6
}
711
712
40
size_t ModuleList::GetIndexForModule(const Module *module) const {
713
40
  if (module) {
714
40
    std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
715
40
    collection::const_iterator pos;
716
40
    collection::const_iterator begin = m_modules.begin();
717
40
    collection::const_iterator end = m_modules.end();
718
40
    for (pos = begin; pos != end; 
++pos0
) {
719
37
      if ((*pos).get() == module)
720
37
        return std::distance(begin, pos);
721
37
    }
722
40
  }
723
3
  return LLDB_INVALID_INDEX32;
724
40
}
725
726
namespace {
727
struct SharedModuleListInfo {
728
  ModuleList module_list;
729
  ModuleListProperties module_list_properties;
730
};
731
}
732
static SharedModuleListInfo &GetSharedModuleListInfo()
733
1.01M
{
734
1.01M
  static SharedModuleListInfo *g_shared_module_list_info = nullptr;
735
1.01M
  static llvm::once_flag g_once_flag;
736
1.01M
  llvm::call_once(g_once_flag, []() {
737
    // NOTE: Intentionally leak the module list so a program doesn't have to
738
    // cleanup all modules and object files as it exits. This just wastes time
739
    // doing a bunch of cleanup that isn't required.
740
3.44k
    if (g_shared_module_list_info == nullptr)
741
3.44k
      g_shared_module_list_info = new SharedModuleListInfo();
742
3.44k
  });
743
1.01M
  return *g_shared_module_list_info;
744
1.01M
}
745
746
286k
static ModuleList &GetSharedModuleList() {
747
286k
  return GetSharedModuleListInfo().module_list;
748
286k
}
749
750
731k
ModuleListProperties &ModuleList::GetGlobalModuleListProperties() {
751
731k
  return GetSharedModuleListInfo().module_list_properties;
752
731k
}
753
754
0
bool ModuleList::ModuleIsInCache(const Module *module_ptr) {
755
0
  if (module_ptr) {
756
0
    ModuleList &shared_module_list = GetSharedModuleList();
757
0
    return shared_module_list.FindModule(module_ptr).get() != nullptr;
758
0
  }
759
0
  return false;
760
0
}
761
762
void ModuleList::FindSharedModules(const ModuleSpec &module_spec,
763
0
                                   ModuleList &matching_module_list) {
764
0
  GetSharedModuleList().FindModules(module_spec, matching_module_list);
765
0
}
766
767
3.42k
size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) {
768
3.42k
  return GetSharedModuleList().RemoveOrphans(mandatory);
769
3.42k
}
770
771
Status
772
ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
773
                            const FileSpecList *module_search_paths_ptr,
774
                            llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
775
283k
                            bool *did_create_ptr, bool always_create) {
776
283k
  ModuleList &shared_module_list = GetSharedModuleList();
777
283k
  std::lock_guard<std::recursive_mutex> guard(
778
283k
      shared_module_list.m_modules_mutex);
779
283k
  char path[PATH_MAX];
780
781
283k
  Status error;
782
783
283k
  module_sp.reset();
784
785
283k
  if (did_create_ptr)
786
270k
    *did_create_ptr = false;
787
788
283k
  const UUID *uuid_ptr = module_spec.GetUUIDPtr();
789
283k
  const FileSpec &module_file_spec = module_spec.GetFileSpec();
790
283k
  const ArchSpec &arch = module_spec.GetArchitecture();
791
792
  // Make sure no one else can try and get or create a module while this
793
  // function is actively working on it by doing an extra lock on the global
794
  // mutex list.
795
283k
  if (
!always_create283k
) {
796
283k
    ModuleList matching_module_list;
797
283k
    shared_module_list.FindModules(module_spec, matching_module_list);
798
283k
    const size_t num_matching_modules = matching_module_list.GetSize();
799
800
283k
    if (num_matching_modules > 0) {
801
145k
      for (size_t module_idx = 0; module_idx < num_matching_modules;
802
145k
           
++module_idx2
) {
803
145k
        module_sp = matching_module_list.GetModuleAtIndex(module_idx);
804
805
        // Make sure the file for the module hasn't been modified
806
145k
        if (module_sp->FileHasChanged()) {
807
2
          if (old_modules)
808
1
            old_modules->push_back(module_sp);
809
810
2
          Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
811
2
          if (log != nullptr)
812
0
            LLDB_LOGF(
813
2
                log, "%p '%s' module changed: removing from global module list",
814
2
                static_cast<void *>(module_sp.get()),
815
2
                module_sp->GetFileSpec().GetFilename().GetCString());
816
817
2
          shared_module_list.Remove(module_sp);
818
2
          module_sp.reset();
819
145k
        } else {
820
          // The module matches and the module was not modified from when it
821
          // was last loaded.
822
145k
          return error;
823
145k
        }
824
145k
      }
825
145k
    }
826
283k
  }
827
828
137k
  if (module_sp)
829
0
    return error;
830
831
137k
  module_sp = std::make_shared<Module>(module_spec);
832
  // Make sure there are a module and an object file since we can specify a
833
  // valid file path with an architecture that might not be in that file. By
834
  // getting the object file we can guarantee that the architecture matches
835
137k
  if (module_sp->GetObjectFile()) {
836
    // If we get in here we got the correct arch, now we just need to verify
837
    // the UUID if one was given
838
136k
    if (uuid_ptr && 
*uuid_ptr != module_sp->GetUUID()127k
) {
839
0
      module_sp.reset();
840
136k
    } else {
841
136k
      if (module_sp->GetObjectFile() &&
842
136k
          module_sp->GetObjectFile()->GetType() ==
843
136k
              ObjectFile::eTypeStubLibrary) {
844
0
        module_sp.reset();
845
136k
      } else {
846
136k
        if (did_create_ptr) {
847
130k
          *did_create_ptr = true;
848
130k
        }
849
850
136k
        shared_module_list.ReplaceEquivalent(module_sp, old_modules);
851
136k
        return error;
852
136k
      }
853
136k
    }
854
136k
  } else {
855
893
    module_sp.reset();
856
893
  }
857
858
893
  if (module_search_paths_ptr) {
859
828
    const auto num_directories = module_search_paths_ptr->GetSize();
860
1.14k
    for (size_t idx = 0; idx < num_directories; 
++idx320
) {
861
329
      auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
862
329
      FileSystem::Instance().Resolve(search_path_spec);
863
329
      namespace fs = llvm::sys::fs;
864
329
      if (!FileSystem::Instance().IsDirectory(search_path_spec))
865
0
        continue;
866
329
      search_path_spec.AppendPathComponent(
867
329
          module_spec.GetFileSpec().GetFilename().GetStringRef());
868
329
      if (!FileSystem::Instance().Exists(search_path_spec))
869
290
        continue;
870
871
39
      auto resolved_module_spec(module_spec);
872
39
      resolved_module_spec.GetFileSpec() = search_path_spec;
873
39
      module_sp = std::make_shared<Module>(resolved_module_spec);
874
39
      if (module_sp->GetObjectFile()) {
875
        // If we get in here we got the correct arch, now we just need to
876
        // verify the UUID if one was given
877
9
        if (uuid_ptr && 
*uuid_ptr != module_sp->GetUUID()0
) {
878
0
          module_sp.reset();
879
9
        } else {
880
9
          if (module_sp->GetObjectFile()->GetType() ==
881
9
              ObjectFile::eTypeStubLibrary) {
882
0
            module_sp.reset();
883
9
          } else {
884
9
            if (did_create_ptr)
885
9
              *did_create_ptr = true;
886
887
9
            shared_module_list.ReplaceEquivalent(module_sp, old_modules);
888
9
            return Status();
889
9
          }
890
9
        }
891
30
      } else {
892
30
        module_sp.reset();
893
30
      }
894
39
    }
895
828
  }
896
897
  // Either the file didn't exist where at the path, or no path was given, so
898
  // we now have to use more extreme measures to try and find the appropriate
899
  // module.
900
901
  // Fixup the incoming path in case the path points to a valid file, yet the
902
  // arch or UUID (if one was passed in) don't match.
903
884
  ModuleSpec located_binary_modulespec =
904
884
      Symbols::LocateExecutableObjectFile(module_spec);
905
906
  // Don't look for the file if it appears to be the same one we already
907
  // checked for above...
908
884
  if (located_binary_modulespec.GetFileSpec() != module_file_spec) {
909
881
    if (!FileSystem::Instance().Exists(
910
881
            located_binary_modulespec.GetFileSpec())) {
911
881
      located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
912
881
      if (path[0] == '\0')
913
881
        module_file_spec.GetPath(path, sizeof(path));
914
      // How can this check ever be true? This branch it is false, and we
915
      // haven't modified file_spec.
916
881
      if (FileSystem::Instance().Exists(
917
881
              located_binary_modulespec.GetFileSpec())) {
918
0
        std::string uuid_str;
919
0
        if (uuid_ptr && uuid_ptr->IsValid())
920
0
          uuid_str = uuid_ptr->GetAsString();
921
922
0
        if (arch.IsValid()) {
923
0
          if (!uuid_str.empty())
924
0
            error.SetErrorStringWithFormat(
925
0
                "'%s' does not contain the %s architecture and UUID %s", path,
926
0
                arch.GetArchitectureName(), uuid_str.c_str());
927
0
          else
928
0
            error.SetErrorStringWithFormat(
929
0
                "'%s' does not contain the %s architecture.", path,
930
0
                arch.GetArchitectureName());
931
0
        }
932
881
      } else {
933
881
        error.SetErrorStringWithFormat("'%s' does not exist", path);
934
881
      }
935
881
      if (error.Fail())
936
881
        module_sp.reset();
937
881
      return error;
938
881
    }
939
940
    // Make sure no one else can try and get or create a module while this
941
    // function is actively working on it by doing an extra lock on the global
942
    // mutex list.
943
0
    ModuleSpec platform_module_spec(module_spec);
944
0
    platform_module_spec.GetFileSpec() =
945
0
        located_binary_modulespec.GetFileSpec();
946
0
    platform_module_spec.GetPlatformFileSpec() =
947
0
        located_binary_modulespec.GetFileSpec();
948
0
    platform_module_spec.GetSymbolFileSpec() =
949
0
        located_binary_modulespec.GetSymbolFileSpec();
950
0
    ModuleList matching_module_list;
951
0
    shared_module_list.FindModules(platform_module_spec, matching_module_list);
952
0
    if (!matching_module_list.IsEmpty()) {
953
0
      module_sp = matching_module_list.GetModuleAtIndex(0);
954
955
      // If we didn't have a UUID in mind when looking for the object file,
956
      // then we should make sure the modification time hasn't changed!
957
0
      if (platform_module_spec.GetUUIDPtr() == nullptr) {
958
0
        auto file_spec_mod_time = FileSystem::Instance().GetModificationTime(
959
0
            located_binary_modulespec.GetFileSpec());
960
0
        if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
961
0
          if (file_spec_mod_time != module_sp->GetModificationTime()) {
962
0
            if (old_modules)
963
0
              old_modules->push_back(module_sp);
964
0
            shared_module_list.Remove(module_sp);
965
0
            module_sp.reset();
966
0
          }
967
0
        }
968
0
      }
969
0
    }
970
971
0
    if (!module_sp) {
972
0
      module_sp = std::make_shared<Module>(platform_module_spec);
973
      // Make sure there are a module and an object file since we can specify a
974
      // valid file path with an architecture that might not be in that file.
975
      // By getting the object file we can guarantee that the architecture
976
      // matches
977
0
      if (module_sp && module_sp->GetObjectFile()) {
978
0
        if (module_sp->GetObjectFile()->GetType() ==
979
0
            ObjectFile::eTypeStubLibrary) {
980
0
          module_sp.reset();
981
0
        } else {
982
0
          if (did_create_ptr)
983
0
            *did_create_ptr = true;
984
985
0
          shared_module_list.ReplaceEquivalent(module_sp, old_modules);
986
0
        }
987
0
      } else {
988
0
        located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
989
990
0
        if (located_binary_modulespec.GetFileSpec()) {
991
0
          if (arch.IsValid())
992
0
            error.SetErrorStringWithFormat(
993
0
                "unable to open %s architecture in '%s'",
994
0
                arch.GetArchitectureName(), path);
995
0
          else
996
0
            error.SetErrorStringWithFormat("unable to open '%s'", path);
997
0
        } else {
998
0
          std::string uuid_str;
999
0
          if (uuid_ptr && uuid_ptr->IsValid())
1000
0
            uuid_str = uuid_ptr->GetAsString();
1001
1002
0
          if (!uuid_str.empty())
1003
0
            error.SetErrorStringWithFormat(
1004
0
                "cannot locate a module for UUID '%s'", uuid_str.c_str());
1005
0
          else
1006
0
            error.SetErrorString("cannot locate a module");
1007
0
        }
1008
0
      }
1009
0
    }
1010
0
  }
1011
1012
3
  return error;
1013
884
}
1014
1015
0
bool ModuleList::RemoveSharedModule(lldb::ModuleSP &module_sp) {
1016
0
  return GetSharedModuleList().Remove(module_sp);
1017
0
}
1018
1019
1
bool ModuleList::RemoveSharedModuleIfOrphaned(const Module *module_ptr) {
1020
1
  return GetSharedModuleList().RemoveIfOrphaned(module_ptr);
1021
1
}
1022
1023
bool ModuleList::LoadScriptingResourcesInTarget(Target *target,
1024
                                                std::list<Status> &errors,
1025
                                                Stream *feedback_stream,
1026
0
                                                bool continue_on_error) {
1027
0
  if (!target)
1028
0
    return false;
1029
0
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1030
0
  for (auto module : m_modules) {
1031
0
    Status error;
1032
0
    if (module) {
1033
0
      if (!module->LoadScriptingResourceInTarget(target, error,
1034
0
                                                 feedback_stream)) {
1035
0
        if (error.Fail() && error.AsCString()) {
1036
0
          error.SetErrorStringWithFormat("unable to load scripting data for "
1037
0
                                         "module %s - error reported was %s",
1038
0
                                         module->GetFileSpec()
1039
0
                                             .GetFileNameStrippingExtension()
1040
0
                                             .GetCString(),
1041
0
                                         error.AsCString());
1042
0
          errors.push_back(error);
1043
1044
0
          if (!continue_on_error)
1045
0
            return false;
1046
0
        }
1047
0
      }
1048
0
    }
1049
0
  }
1050
0
  return errors.empty();
1051
0
}
1052
1053
void ModuleList::ForEach(
1054
179k
    std::function<bool(const ModuleSP &module_sp)> const &callback) const {
1055
179k
  std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1056
558k
  for (const auto &module : m_modules) {
1057
    // If the callback returns false, then stop iterating and break out
1058
558k
    if (!callback(module))
1059
3
      break;
1060
558k
  }
1061
179k
}