1 //===-- Module.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/Module.h"
10
11 #include "lldb/Core/AddressRange.h"
12 #include "lldb/Core/AddressResolverFileLine.h"
13 #include "lldb/Core/DataFileCache.h"
14 #include "lldb/Core/Debugger.h"
15 #include "lldb/Core/FileSpecList.h"
16 #include "lldb/Core/Mangled.h"
17 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Core/SearchFilter.h"
19 #include "lldb/Core/Section.h"
20 #include "lldb/Host/FileSystem.h"
21 #include "lldb/Host/Host.h"
22 #include "lldb/Host/HostInfo.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/ScriptInterpreter.h"
25 #include "lldb/Symbol/CompileUnit.h"
26 #include "lldb/Symbol/Function.h"
27 #include "lldb/Symbol/LocateSymbolFile.h"
28 #include "lldb/Symbol/ObjectFile.h"
29 #include "lldb/Symbol/Symbol.h"
30 #include "lldb/Symbol/SymbolContext.h"
31 #include "lldb/Symbol/SymbolFile.h"
32 #include "lldb/Symbol/SymbolVendor.h"
33 #include "lldb/Symbol/Symtab.h"
34 #include "lldb/Symbol/Type.h"
35 #include "lldb/Symbol/TypeList.h"
36 #include "lldb/Symbol/TypeMap.h"
37 #include "lldb/Symbol/TypeSystem.h"
38 #include "lldb/Target/Language.h"
39 #include "lldb/Target/Process.h"
40 #include "lldb/Target/Target.h"
41 #include "lldb/Utility/DataBufferHeap.h"
42 #include "lldb/Utility/LLDBAssert.h"
43 #include "lldb/Utility/LLDBLog.h"
44 #include "lldb/Utility/Log.h"
45 #include "lldb/Utility/RegularExpression.h"
46 #include "lldb/Utility/Status.h"
47 #include "lldb/Utility/Stream.h"
48 #include "lldb/Utility/StreamString.h"
49 #include "lldb/Utility/Timer.h"
50
51 #if defined(_WIN32)
52 #include "lldb/Host/windows/PosixApi.h"
53 #endif
54
55 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
56 #include "Plugins/Language/ObjC/ObjCLanguage.h"
57
58 #include "llvm/ADT/STLExtras.h"
59 #include "llvm/Support/Compiler.h"
60 #include "llvm/Support/DJB.h"
61 #include "llvm/Support/FileSystem.h"
62 #include "llvm/Support/FormatVariadic.h"
63 #include "llvm/Support/JSON.h"
64 #include "llvm/Support/Signals.h"
65 #include "llvm/Support/raw_ostream.h"
66
67 #include <cassert>
68 #include <cinttypes>
69 #include <cstdarg>
70 #include <cstdint>
71 #include <cstring>
72 #include <map>
73 #include <optional>
74 #include <type_traits>
75 #include <utility>
76
77 namespace lldb_private {
78 class CompilerDeclContext;
79 }
80 namespace lldb_private {
81 class VariableList;
82 }
83
84 using namespace lldb;
85 using namespace lldb_private;
86
87 // Shared pointers to modules track module lifetimes in targets and in the
88 // global module, but this collection will track all module objects that are
89 // still alive
90 typedef std::vector<Module *> ModuleCollection;
91
GetModuleCollection()92 static ModuleCollection &GetModuleCollection() {
93 // This module collection needs to live past any module, so we could either
94 // make it a shared pointer in each module or just leak is. Since it is only
95 // an empty vector by the time all the modules have gone away, we just leak
96 // it for now. If we decide this is a big problem we can introduce a
97 // Finalize method that will tear everything down in a predictable order.
98
99 static ModuleCollection *g_module_collection = nullptr;
100 if (g_module_collection == nullptr)
101 g_module_collection = new ModuleCollection();
102
103 return *g_module_collection;
104 }
105
GetAllocationModuleCollectionMutex()106 std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
107 // NOTE: The mutex below must be leaked since the global module list in
108 // the ModuleList class will get torn at some point, and we can't know if it
109 // will tear itself down before the "g_module_collection_mutex" below will.
110 // So we leak a Mutex object below to safeguard against that
111
112 static std::recursive_mutex *g_module_collection_mutex = nullptr;
113 if (g_module_collection_mutex == nullptr)
114 g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
115 return *g_module_collection_mutex;
116 }
117
GetNumberAllocatedModules()118 size_t Module::GetNumberAllocatedModules() {
119 std::lock_guard<std::recursive_mutex> guard(
120 GetAllocationModuleCollectionMutex());
121 return GetModuleCollection().size();
122 }
123
GetAllocatedModuleAtIndex(size_t idx)124 Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
125 std::lock_guard<std::recursive_mutex> guard(
126 GetAllocationModuleCollectionMutex());
127 ModuleCollection &modules = GetModuleCollection();
128 if (idx < modules.size())
129 return modules[idx];
130 return nullptr;
131 }
132
Module(const ModuleSpec & module_spec)133 Module::Module(const ModuleSpec &module_spec)
134 : m_file_has_changed(false), m_first_file_changed_log(false) {
135 // Scope for locker below...
136 {
137 std::lock_guard<std::recursive_mutex> guard(
138 GetAllocationModuleCollectionMutex());
139 GetModuleCollection().push_back(this);
140 }
141
142 Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
143 if (log != nullptr)
144 LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
145 static_cast<void *>(this),
146 module_spec.GetArchitecture().GetArchitectureName(),
147 module_spec.GetFileSpec().GetPath().c_str(),
148 module_spec.GetObjectName().IsEmpty() ? "" : "(",
149 module_spec.GetObjectName().AsCString(""),
150 module_spec.GetObjectName().IsEmpty() ? "" : ")");
151
152 auto data_sp = module_spec.GetData();
153 lldb::offset_t file_size = 0;
154 if (data_sp)
155 file_size = data_sp->GetByteSize();
156
157 // First extract all module specifications from the file using the local file
158 // path. If there are no specifications, then don't fill anything in
159 ModuleSpecList modules_specs;
160 if (ObjectFile::GetModuleSpecifications(
161 module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)
162 return;
163
164 // Now make sure that one of the module specifications matches what we just
165 // extract. We might have a module specification that specifies a file
166 // "/usr/lib/dyld" with UUID XXX, but we might have a local version of
167 // "/usr/lib/dyld" that has
168 // UUID YYY and we don't want those to match. If they don't match, just don't
169 // fill any ivars in so we don't accidentally grab the wrong file later since
170 // they don't match...
171 ModuleSpec matching_module_spec;
172 if (!modules_specs.FindMatchingModuleSpec(module_spec,
173 matching_module_spec)) {
174 if (log) {
175 LLDB_LOGF(log, "Found local object file but the specs didn't match");
176 }
177 return;
178 }
179
180 // Set m_data_sp if it was initially provided in the ModuleSpec. Note that
181 // we cannot use the data_sp variable here, because it will have been
182 // modified by GetModuleSpecifications().
183 if (auto module_spec_data_sp = module_spec.GetData()) {
184 m_data_sp = module_spec_data_sp;
185 m_mod_time = {};
186 } else {
187 if (module_spec.GetFileSpec())
188 m_mod_time =
189 FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
190 else if (matching_module_spec.GetFileSpec())
191 m_mod_time = FileSystem::Instance().GetModificationTime(
192 matching_module_spec.GetFileSpec());
193 }
194
195 // Copy the architecture from the actual spec if we got one back, else use
196 // the one that was specified
197 if (matching_module_spec.GetArchitecture().IsValid())
198 m_arch = matching_module_spec.GetArchitecture();
199 else if (module_spec.GetArchitecture().IsValid())
200 m_arch = module_spec.GetArchitecture();
201
202 // Copy the file spec over and use the specified one (if there was one) so we
203 // don't use a path that might have gotten resolved a path in
204 // 'matching_module_spec'
205 if (module_spec.GetFileSpec())
206 m_file = module_spec.GetFileSpec();
207 else if (matching_module_spec.GetFileSpec())
208 m_file = matching_module_spec.GetFileSpec();
209
210 // Copy the platform file spec over
211 if (module_spec.GetPlatformFileSpec())
212 m_platform_file = module_spec.GetPlatformFileSpec();
213 else if (matching_module_spec.GetPlatformFileSpec())
214 m_platform_file = matching_module_spec.GetPlatformFileSpec();
215
216 // Copy the symbol file spec over
217 if (module_spec.GetSymbolFileSpec())
218 m_symfile_spec = module_spec.GetSymbolFileSpec();
219 else if (matching_module_spec.GetSymbolFileSpec())
220 m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
221
222 // Copy the object name over
223 if (matching_module_spec.GetObjectName())
224 m_object_name = matching_module_spec.GetObjectName();
225 else
226 m_object_name = module_spec.GetObjectName();
227
228 // Always trust the object offset (file offset) and object modification time
229 // (for mod time in a BSD static archive) of from the matching module
230 // specification
231 m_object_offset = matching_module_spec.GetObjectOffset();
232 m_object_mod_time = matching_module_spec.GetObjectModificationTime();
233 }
234
Module(const FileSpec & file_spec,const ArchSpec & arch,const ConstString * object_name,lldb::offset_t object_offset,const llvm::sys::TimePoint<> & object_mod_time)235 Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
236 const ConstString *object_name, lldb::offset_t object_offset,
237 const llvm::sys::TimePoint<> &object_mod_time)
238 : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
239 m_arch(arch), m_file(file_spec), m_object_offset(object_offset),
240 m_object_mod_time(object_mod_time), m_file_has_changed(false),
241 m_first_file_changed_log(false) {
242 // Scope for locker below...
243 {
244 std::lock_guard<std::recursive_mutex> guard(
245 GetAllocationModuleCollectionMutex());
246 GetModuleCollection().push_back(this);
247 }
248
249 if (object_name)
250 m_object_name = *object_name;
251
252 Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
253 if (log != nullptr)
254 LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
255 static_cast<void *>(this), m_arch.GetArchitectureName(),
256 m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
257 m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
258 }
259
Module()260 Module::Module() : m_file_has_changed(false), m_first_file_changed_log(false) {
261 std::lock_guard<std::recursive_mutex> guard(
262 GetAllocationModuleCollectionMutex());
263 GetModuleCollection().push_back(this);
264 }
265
~Module()266 Module::~Module() {
267 // Lock our module down while we tear everything down to make sure we don't
268 // get any access to the module while it is being destroyed
269 std::lock_guard<std::recursive_mutex> guard(m_mutex);
270 // Scope for locker below...
271 {
272 std::lock_guard<std::recursive_mutex> guard(
273 GetAllocationModuleCollectionMutex());
274 ModuleCollection &modules = GetModuleCollection();
275 ModuleCollection::iterator end = modules.end();
276 ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
277 assert(pos != end);
278 modules.erase(pos);
279 }
280 Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
281 if (log != nullptr)
282 LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",
283 static_cast<void *>(this), m_arch.GetArchitectureName(),
284 m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
285 m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
286 // Release any auto pointers before we start tearing down our member
287 // variables since the object file and symbol files might need to make
288 // function calls back into this module object. The ordering is important
289 // here because symbol files can require the module object file. So we tear
290 // down the symbol file first, then the object file.
291 m_sections_up.reset();
292 m_symfile_up.reset();
293 m_objfile_sp.reset();
294 }
295
GetMemoryObjectFile(const lldb::ProcessSP & process_sp,lldb::addr_t header_addr,Status & error,size_t size_to_read)296 ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
297 lldb::addr_t header_addr, Status &error,
298 size_t size_to_read) {
299 if (m_objfile_sp) {
300 error.SetErrorString("object file already exists");
301 } else {
302 std::lock_guard<std::recursive_mutex> guard(m_mutex);
303 if (process_sp) {
304 m_did_load_objfile = true;
305 std::shared_ptr<DataBufferHeap> data_sp =
306 std::make_shared<DataBufferHeap>(size_to_read, 0);
307 Status readmem_error;
308 const size_t bytes_read =
309 process_sp->ReadMemory(header_addr, data_sp->GetBytes(),
310 data_sp->GetByteSize(), readmem_error);
311 if (bytes_read < size_to_read)
312 data_sp->SetByteSize(bytes_read);
313 if (data_sp->GetByteSize() > 0) {
314 m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,
315 header_addr, data_sp);
316 if (m_objfile_sp) {
317 StreamString s;
318 s.Printf("0x%16.16" PRIx64, header_addr);
319 m_object_name.SetString(s.GetString());
320
321 // Once we get the object file, update our module with the object
322 // file's architecture since it might differ in vendor/os if some
323 // parts were unknown.
324 m_arch = m_objfile_sp->GetArchitecture();
325
326 // Augment the arch with the target's information in case
327 // we are unable to extract the os/environment from memory.
328 m_arch.MergeFrom(process_sp->GetTarget().GetArchitecture());
329 } else {
330 error.SetErrorString("unable to find suitable object file plug-in");
331 }
332 } else {
333 error.SetErrorStringWithFormat("unable to read header from memory: %s",
334 readmem_error.AsCString());
335 }
336 } else {
337 error.SetErrorString("invalid process");
338 }
339 }
340 return m_objfile_sp.get();
341 }
342
GetUUID()343 const lldb_private::UUID &Module::GetUUID() {
344 if (!m_did_set_uuid.load()) {
345 std::lock_guard<std::recursive_mutex> guard(m_mutex);
346 if (!m_did_set_uuid.load()) {
347 ObjectFile *obj_file = GetObjectFile();
348
349 if (obj_file != nullptr) {
350 m_uuid = obj_file->GetUUID();
351 m_did_set_uuid = true;
352 }
353 }
354 }
355 return m_uuid;
356 }
357
SetUUID(const lldb_private::UUID & uuid)358 void Module::SetUUID(const lldb_private::UUID &uuid) {
359 std::lock_guard<std::recursive_mutex> guard(m_mutex);
360 if (!m_did_set_uuid) {
361 m_uuid = uuid;
362 m_did_set_uuid = true;
363 } else {
364 lldbassert(0 && "Attempting to overwrite the existing module UUID");
365 }
366 }
367
368 llvm::Expected<TypeSystemSP>
GetTypeSystemForLanguage(LanguageType language)369 Module::GetTypeSystemForLanguage(LanguageType language) {
370 return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
371 }
372
ForEachTypeSystem(llvm::function_ref<bool (lldb::TypeSystemSP)> callback)373 void Module::ForEachTypeSystem(
374 llvm::function_ref<bool(lldb::TypeSystemSP)> callback) {
375 m_type_system_map.ForEach(callback);
376 }
377
ParseAllDebugSymbols()378 void Module::ParseAllDebugSymbols() {
379 std::lock_guard<std::recursive_mutex> guard(m_mutex);
380 size_t num_comp_units = GetNumCompileUnits();
381 if (num_comp_units == 0)
382 return;
383
384 SymbolFile *symbols = GetSymbolFile();
385
386 for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {
387 SymbolContext sc;
388 sc.module_sp = shared_from_this();
389 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
390 if (!sc.comp_unit)
391 continue;
392
393 symbols->ParseVariablesForContext(sc);
394
395 symbols->ParseFunctions(*sc.comp_unit);
396
397 sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {
398 symbols->ParseBlocksRecursive(*f);
399
400 // Parse the variables for this function and all its blocks
401 sc.function = f.get();
402 symbols->ParseVariablesForContext(sc);
403 return false;
404 });
405
406 // Parse all types for this compile unit
407 symbols->ParseTypes(*sc.comp_unit);
408 }
409 }
410
CalculateSymbolContext(SymbolContext * sc)411 void Module::CalculateSymbolContext(SymbolContext *sc) {
412 sc->module_sp = shared_from_this();
413 }
414
CalculateSymbolContextModule()415 ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }
416
DumpSymbolContext(Stream * s)417 void Module::DumpSymbolContext(Stream *s) {
418 s->Printf(", Module{%p}", static_cast<void *>(this));
419 }
420
GetNumCompileUnits()421 size_t Module::GetNumCompileUnits() {
422 std::lock_guard<std::recursive_mutex> guard(m_mutex);
423 if (SymbolFile *symbols = GetSymbolFile())
424 return symbols->GetNumCompileUnits();
425 return 0;
426 }
427
GetCompileUnitAtIndex(size_t index)428 CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
429 std::lock_guard<std::recursive_mutex> guard(m_mutex);
430 size_t num_comp_units = GetNumCompileUnits();
431 CompUnitSP cu_sp;
432
433 if (index < num_comp_units) {
434 if (SymbolFile *symbols = GetSymbolFile())
435 cu_sp = symbols->GetCompileUnitAtIndex(index);
436 }
437 return cu_sp;
438 }
439
ResolveFileAddress(lldb::addr_t vm_addr,Address & so_addr)440 bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
441 std::lock_guard<std::recursive_mutex> guard(m_mutex);
442 SectionList *section_list = GetSectionList();
443 if (section_list)
444 return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
445 return false;
446 }
447
ResolveSymbolContextForAddress(const Address & so_addr,lldb::SymbolContextItem resolve_scope,SymbolContext & sc,bool resolve_tail_call_address)448 uint32_t Module::ResolveSymbolContextForAddress(
449 const Address &so_addr, lldb::SymbolContextItem resolve_scope,
450 SymbolContext &sc, bool resolve_tail_call_address) {
451 std::lock_guard<std::recursive_mutex> guard(m_mutex);
452 uint32_t resolved_flags = 0;
453
454 // Clear the result symbol context in case we don't find anything, but don't
455 // clear the target
456 sc.Clear(false);
457
458 // Get the section from the section/offset address.
459 SectionSP section_sp(so_addr.GetSection());
460
461 // Make sure the section matches this module before we try and match anything
462 if (section_sp && section_sp->GetModule().get() == this) {
463 // If the section offset based address resolved itself, then this is the
464 // right module.
465 sc.module_sp = shared_from_this();
466 resolved_flags |= eSymbolContextModule;
467
468 SymbolFile *symfile = GetSymbolFile();
469 if (!symfile)
470 return resolved_flags;
471
472 // Resolve the compile unit, function, block, line table or line entry if
473 // requested.
474 if (resolve_scope & eSymbolContextCompUnit ||
475 resolve_scope & eSymbolContextFunction ||
476 resolve_scope & eSymbolContextBlock ||
477 resolve_scope & eSymbolContextLineEntry ||
478 resolve_scope & eSymbolContextVariable) {
479 symfile->SetLoadDebugInfoEnabled();
480 resolved_flags |=
481 symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);
482 }
483
484 // Resolve the symbol if requested, but don't re-look it up if we've
485 // already found it.
486 if (resolve_scope & eSymbolContextSymbol &&
487 !(resolved_flags & eSymbolContextSymbol)) {
488 Symtab *symtab = symfile->GetSymtab();
489 if (symtab && so_addr.IsSectionOffset()) {
490 Symbol *matching_symbol = nullptr;
491
492 symtab->ForEachSymbolContainingFileAddress(
493 so_addr.GetFileAddress(),
494 [&matching_symbol](Symbol *symbol) -> bool {
495 if (symbol->GetType() != eSymbolTypeInvalid) {
496 matching_symbol = symbol;
497 return false; // Stop iterating
498 }
499 return true; // Keep iterating
500 });
501 sc.symbol = matching_symbol;
502 if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
503 !(resolved_flags & eSymbolContextFunction)) {
504 bool verify_unique = false; // No need to check again since
505 // ResolveSymbolContext failed to find a
506 // symbol at this address.
507 if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
508 sc.symbol =
509 obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
510 }
511
512 if (sc.symbol) {
513 if (sc.symbol->IsSynthetic()) {
514 // We have a synthetic symbol so lets check if the object file from
515 // the symbol file in the symbol vendor is different than the
516 // object file for the module, and if so search its symbol table to
517 // see if we can come up with a better symbol. For example dSYM
518 // files on MacOSX have an unstripped symbol table inside of them.
519 ObjectFile *symtab_objfile = symtab->GetObjectFile();
520 if (symtab_objfile && symtab_objfile->IsStripped()) {
521 ObjectFile *symfile_objfile = symfile->GetObjectFile();
522 if (symfile_objfile != symtab_objfile) {
523 Symtab *symfile_symtab = symfile_objfile->GetSymtab();
524 if (symfile_symtab) {
525 Symbol *symbol =
526 symfile_symtab->FindSymbolContainingFileAddress(
527 so_addr.GetFileAddress());
528 if (symbol && !symbol->IsSynthetic()) {
529 sc.symbol = symbol;
530 }
531 }
532 }
533 }
534 }
535 resolved_flags |= eSymbolContextSymbol;
536 }
537 }
538 }
539
540 // For function symbols, so_addr may be off by one. This is a convention
541 // consistent with FDE row indices in eh_frame sections, but requires extra
542 // logic here to permit symbol lookup for disassembly and unwind.
543 if (resolve_scope & eSymbolContextSymbol &&
544 !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
545 so_addr.IsSectionOffset()) {
546 Address previous_addr = so_addr;
547 previous_addr.Slide(-1);
548
549 bool do_resolve_tail_call_address = false; // prevent recursion
550 const uint32_t flags = ResolveSymbolContextForAddress(
551 previous_addr, resolve_scope, sc, do_resolve_tail_call_address);
552 if (flags & eSymbolContextSymbol) {
553 AddressRange addr_range;
554 if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
555 false, addr_range)) {
556 if (addr_range.GetBaseAddress().GetSection() ==
557 so_addr.GetSection()) {
558 // If the requested address is one past the address range of a
559 // function (i.e. a tail call), or the decremented address is the
560 // start of a function (i.e. some forms of trampoline), indicate
561 // that the symbol has been resolved.
562 if (so_addr.GetOffset() ==
563 addr_range.GetBaseAddress().GetOffset() ||
564 so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() +
565 addr_range.GetByteSize()) {
566 resolved_flags |= flags;
567 }
568 } else {
569 sc.symbol =
570 nullptr; // Don't trust the symbol if the sections didn't match.
571 }
572 }
573 }
574 }
575 }
576 return resolved_flags;
577 }
578
ResolveSymbolContextForFilePath(const char * file_path,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)579 uint32_t Module::ResolveSymbolContextForFilePath(
580 const char *file_path, uint32_t line, bool check_inlines,
581 lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
582 FileSpec file_spec(file_path);
583 return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
584 resolve_scope, sc_list);
585 }
586
ResolveSymbolContextsForFileSpec(const FileSpec & file_spec,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)587 uint32_t Module::ResolveSymbolContextsForFileSpec(
588 const FileSpec &file_spec, uint32_t line, bool check_inlines,
589 lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
590 std::lock_guard<std::recursive_mutex> guard(m_mutex);
591 LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "
592 "check_inlines = %s, resolve_scope = 0x%8.8x)",
593 file_spec.GetPath().c_str(), line,
594 check_inlines ? "yes" : "no", resolve_scope);
595
596 const uint32_t initial_count = sc_list.GetSize();
597
598 if (SymbolFile *symbols = GetSymbolFile()) {
599 // TODO: Handle SourceLocationSpec column information
600 SourceLocationSpec location_spec(file_spec, line, /*column=*/std::nullopt,
601 check_inlines, /*exact_match=*/false);
602
603 symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list);
604 }
605
606 return sc_list.GetSize() - initial_count;
607 }
608
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,VariableList & variables)609 void Module::FindGlobalVariables(ConstString name,
610 const CompilerDeclContext &parent_decl_ctx,
611 size_t max_matches, VariableList &variables) {
612 if (SymbolFile *symbols = GetSymbolFile())
613 symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);
614 }
615
FindGlobalVariables(const RegularExpression & regex,size_t max_matches,VariableList & variables)616 void Module::FindGlobalVariables(const RegularExpression ®ex,
617 size_t max_matches, VariableList &variables) {
618 SymbolFile *symbols = GetSymbolFile();
619 if (symbols)
620 symbols->FindGlobalVariables(regex, max_matches, variables);
621 }
622
FindCompileUnits(const FileSpec & path,SymbolContextList & sc_list)623 void Module::FindCompileUnits(const FileSpec &path,
624 SymbolContextList &sc_list) {
625 const size_t num_compile_units = GetNumCompileUnits();
626 SymbolContext sc;
627 sc.module_sp = shared_from_this();
628 for (size_t i = 0; i < num_compile_units; ++i) {
629 sc.comp_unit = GetCompileUnitAtIndex(i).get();
630 if (sc.comp_unit) {
631 if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))
632 sc_list.Append(sc);
633 }
634 }
635 }
636
LookupInfo(ConstString name,FunctionNameType name_type_mask,LanguageType language)637 Module::LookupInfo::LookupInfo(ConstString name,
638 FunctionNameType name_type_mask,
639 LanguageType language)
640 : m_name(name), m_lookup_name(), m_language(language) {
641 const char *name_cstr = name.GetCString();
642 llvm::StringRef basename;
643 llvm::StringRef context;
644
645 if (name_type_mask & eFunctionNameTypeAuto) {
646 if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
647 m_name_type_mask = eFunctionNameTypeFull;
648 else if ((language == eLanguageTypeUnknown ||
649 Language::LanguageIsObjC(language)) &&
650 ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
651 m_name_type_mask = eFunctionNameTypeFull;
652 else if (Language::LanguageIsC(language)) {
653 m_name_type_mask = eFunctionNameTypeFull;
654 } else {
655 if ((language == eLanguageTypeUnknown ||
656 Language::LanguageIsObjC(language)) &&
657 ObjCLanguage::IsPossibleObjCSelector(name_cstr))
658 m_name_type_mask |= eFunctionNameTypeSelector;
659
660 CPlusPlusLanguage::MethodName cpp_method(name);
661 basename = cpp_method.GetBasename();
662 if (basename.empty()) {
663 if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
664 basename))
665 m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
666 else
667 m_name_type_mask |= eFunctionNameTypeFull;
668 } else {
669 m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
670 }
671 }
672 } else {
673 m_name_type_mask = name_type_mask;
674 if (name_type_mask & eFunctionNameTypeMethod ||
675 name_type_mask & eFunctionNameTypeBase) {
676 // If they've asked for a CPP method or function name and it can't be
677 // that, we don't even need to search for CPP methods or names.
678 CPlusPlusLanguage::MethodName cpp_method(name);
679 if (cpp_method.IsValid()) {
680 basename = cpp_method.GetBasename();
681
682 if (!cpp_method.GetQualifiers().empty()) {
683 // There is a "const" or other qualifier following the end of the
684 // function parens, this can't be a eFunctionNameTypeBase
685 m_name_type_mask &= ~(eFunctionNameTypeBase);
686 if (m_name_type_mask == eFunctionNameTypeNone)
687 return;
688 }
689 } else {
690 // If the CPP method parser didn't manage to chop this up, try to fill
691 // in the base name if we can. If a::b::c is passed in, we need to just
692 // look up "c", and then we'll filter the result later.
693 CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
694 basename);
695 }
696 }
697
698 if (name_type_mask & eFunctionNameTypeSelector) {
699 if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
700 m_name_type_mask &= ~(eFunctionNameTypeSelector);
701 if (m_name_type_mask == eFunctionNameTypeNone)
702 return;
703 }
704 }
705
706 // Still try and get a basename in case someone specifies a name type mask
707 // of eFunctionNameTypeFull and a name like "A::func"
708 if (basename.empty()) {
709 if (name_type_mask & eFunctionNameTypeFull &&
710 !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
711 CPlusPlusLanguage::MethodName cpp_method(name);
712 basename = cpp_method.GetBasename();
713 if (basename.empty())
714 CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
715 basename);
716 }
717 }
718 }
719
720 if (!basename.empty()) {
721 // The name supplied was a partial C++ path like "a::count". In this case
722 // we want to do a lookup on the basename "count" and then make sure any
723 // matching results contain "a::count" so that it would match "b::a::count"
724 // and "a::count". This is why we set "match_name_after_lookup" to true
725 m_lookup_name.SetString(basename);
726 m_match_name_after_lookup = true;
727 } else {
728 // The name is already correct, just use the exact name as supplied, and we
729 // won't need to check if any matches contain "name"
730 m_lookup_name = name;
731 m_match_name_after_lookup = false;
732 }
733 }
734
NameMatchesLookupInfo(ConstString function_name,LanguageType language_type) const735 bool Module::LookupInfo::NameMatchesLookupInfo(
736 ConstString function_name, LanguageType language_type) const {
737 // We always keep unnamed symbols
738 if (!function_name)
739 return true;
740
741 // If we match exactly, we can return early
742 if (m_name == function_name)
743 return true;
744
745 // If function_name is mangled, we'll need to demangle it.
746 // In the pathologial case where the function name "looks" mangled but is
747 // actually demangled (e.g. a method named _Zonk), this operation should be
748 // relatively inexpensive since no demangling is actually occuring. See
749 // Mangled::SetValue for more context.
750 const bool function_name_may_be_mangled =
751 Mangled::GetManglingScheme(function_name.GetStringRef()) !=
752 Mangled::eManglingSchemeNone;
753 ConstString demangled_function_name = function_name;
754 if (function_name_may_be_mangled) {
755 Mangled mangled_function_name(function_name);
756 demangled_function_name = mangled_function_name.GetDemangledName();
757 }
758
759 // If the symbol has a language, then let the language make the match.
760 // Otherwise just check that the demangled function name contains the
761 // demangled user-provided name.
762 if (Language *language = Language::FindPlugin(language_type))
763 return language->DemangledNameContainsPath(m_name.GetStringRef(),
764 demangled_function_name);
765
766 llvm::StringRef function_name_ref = demangled_function_name.GetStringRef();
767 return function_name_ref.contains(m_name.GetStringRef());
768 }
769
Prune(SymbolContextList & sc_list,size_t start_idx) const770 void Module::LookupInfo::Prune(SymbolContextList &sc_list,
771 size_t start_idx) const {
772 if (m_match_name_after_lookup && m_name) {
773 SymbolContext sc;
774 size_t i = start_idx;
775 while (i < sc_list.GetSize()) {
776 if (!sc_list.GetContextAtIndex(i, sc))
777 break;
778
779 bool keep_it =
780 NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage());
781 if (keep_it)
782 ++i;
783 else
784 sc_list.RemoveContextAtIndex(i);
785 }
786 }
787
788 // If we have only full name matches we might have tried to set breakpoint on
789 // "func" and specified eFunctionNameTypeFull, but we might have found
790 // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
791 // "func()" and "func" should end up matching.
792 if (m_name_type_mask == eFunctionNameTypeFull) {
793 SymbolContext sc;
794 size_t i = start_idx;
795 while (i < sc_list.GetSize()) {
796 if (!sc_list.GetContextAtIndex(i, sc))
797 break;
798 // Make sure the mangled and demangled names don't match before we try to
799 // pull anything out
800 ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
801 ConstString full_name(sc.GetFunctionName());
802 if (mangled_name != m_name && full_name != m_name) {
803 CPlusPlusLanguage::MethodName cpp_method(full_name);
804 if (cpp_method.IsValid()) {
805 if (cpp_method.GetContext().empty()) {
806 if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
807 sc_list.RemoveContextAtIndex(i);
808 continue;
809 }
810 } else {
811 std::string qualified_name;
812 llvm::StringRef anon_prefix("(anonymous namespace)");
813 if (cpp_method.GetContext() == anon_prefix)
814 qualified_name = cpp_method.GetBasename().str();
815 else
816 qualified_name = cpp_method.GetScopeQualifiedName();
817 if (qualified_name != m_name.GetCString()) {
818 sc_list.RemoveContextAtIndex(i);
819 continue;
820 }
821 }
822 }
823 }
824 ++i;
825 }
826 }
827 }
828
FindFunctions(const Module::LookupInfo & lookup_info,const CompilerDeclContext & parent_decl_ctx,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)829 void Module::FindFunctions(const Module::LookupInfo &lookup_info,
830 const CompilerDeclContext &parent_decl_ctx,
831 const ModuleFunctionSearchOptions &options,
832 SymbolContextList &sc_list) {
833 // Find all the functions (not symbols, but debug information functions...
834 if (SymbolFile *symbols = GetSymbolFile()) {
835 symbols->FindFunctions(lookup_info, parent_decl_ctx,
836 options.include_inlines, sc_list);
837 // Now check our symbol table for symbols that are code symbols if
838 // requested
839 if (options.include_symbols) {
840 if (Symtab *symtab = symbols->GetSymtab()) {
841 symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
842 lookup_info.GetNameTypeMask(), sc_list);
843 }
844 }
845 }
846 }
847
FindFunctions(ConstString name,const CompilerDeclContext & parent_decl_ctx,FunctionNameType name_type_mask,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)848 void Module::FindFunctions(ConstString name,
849 const CompilerDeclContext &parent_decl_ctx,
850 FunctionNameType name_type_mask,
851 const ModuleFunctionSearchOptions &options,
852 SymbolContextList &sc_list) {
853 const size_t old_size = sc_list.GetSize();
854 LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
855 FindFunctions(lookup_info, parent_decl_ctx, options, sc_list);
856 if (name_type_mask & eFunctionNameTypeAuto) {
857 const size_t new_size = sc_list.GetSize();
858 if (old_size < new_size)
859 lookup_info.Prune(sc_list, old_size);
860 }
861 }
862
FindFunctions(const RegularExpression & regex,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)863 void Module::FindFunctions(const RegularExpression ®ex,
864 const ModuleFunctionSearchOptions &options,
865 SymbolContextList &sc_list) {
866 const size_t start_size = sc_list.GetSize();
867
868 if (SymbolFile *symbols = GetSymbolFile()) {
869 symbols->FindFunctions(regex, options.include_inlines, sc_list);
870
871 // Now check our symbol table for symbols that are code symbols if
872 // requested
873 if (options.include_symbols) {
874 Symtab *symtab = symbols->GetSymtab();
875 if (symtab) {
876 std::vector<uint32_t> symbol_indexes;
877 symtab->AppendSymbolIndexesMatchingRegExAndType(
878 regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
879 symbol_indexes);
880 const size_t num_matches = symbol_indexes.size();
881 if (num_matches) {
882 SymbolContext sc(this);
883 const size_t end_functions_added_index = sc_list.GetSize();
884 size_t num_functions_added_to_sc_list =
885 end_functions_added_index - start_size;
886 if (num_functions_added_to_sc_list == 0) {
887 // No functions were added, just symbols, so we can just append
888 // them
889 for (size_t i = 0; i < num_matches; ++i) {
890 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
891 SymbolType sym_type = sc.symbol->GetType();
892 if (sc.symbol && (sym_type == eSymbolTypeCode ||
893 sym_type == eSymbolTypeResolver))
894 sc_list.Append(sc);
895 }
896 } else {
897 typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
898 FileAddrToIndexMap file_addr_to_index;
899 for (size_t i = start_size; i < end_functions_added_index; ++i) {
900 const SymbolContext &sc = sc_list[i];
901 if (sc.block)
902 continue;
903 file_addr_to_index[sc.function->GetAddressRange()
904 .GetBaseAddress()
905 .GetFileAddress()] = i;
906 }
907
908 FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
909 // Functions were added so we need to merge symbols into any
910 // existing function symbol contexts
911 for (size_t i = start_size; i < num_matches; ++i) {
912 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
913 SymbolType sym_type = sc.symbol->GetType();
914 if (sc.symbol && sc.symbol->ValueIsAddress() &&
915 (sym_type == eSymbolTypeCode ||
916 sym_type == eSymbolTypeResolver)) {
917 FileAddrToIndexMap::const_iterator pos =
918 file_addr_to_index.find(
919 sc.symbol->GetAddressRef().GetFileAddress());
920 if (pos == end)
921 sc_list.Append(sc);
922 else
923 sc_list[pos->second].symbol = sc.symbol;
924 }
925 }
926 }
927 }
928 }
929 }
930 }
931 }
932
FindAddressesForLine(const lldb::TargetSP target_sp,const FileSpec & file,uint32_t line,Function * function,std::vector<Address> & output_local,std::vector<Address> & output_extern)933 void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
934 const FileSpec &file, uint32_t line,
935 Function *function,
936 std::vector<Address> &output_local,
937 std::vector<Address> &output_extern) {
938 SearchFilterByModule filter(target_sp, m_file);
939
940 // TODO: Handle SourceLocationSpec column information
941 SourceLocationSpec location_spec(file, line, /*column=*/std::nullopt,
942 /*check_inlines=*/true,
943 /*exact_match=*/false);
944 AddressResolverFileLine resolver(location_spec);
945 resolver.ResolveAddress(filter);
946
947 for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {
948 Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
949 Function *f = addr.CalculateSymbolContextFunction();
950 if (f && f == function)
951 output_local.push_back(addr);
952 else
953 output_extern.push_back(addr);
954 }
955 }
956
FindTypes_Impl(ConstString name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)957 void Module::FindTypes_Impl(
958 ConstString name, const CompilerDeclContext &parent_decl_ctx,
959 size_t max_matches,
960 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
961 TypeMap &types) {
962 if (SymbolFile *symbols = GetSymbolFile())
963 symbols->FindTypes(name, parent_decl_ctx, max_matches,
964 searched_symbol_files, types);
965 }
966
FindTypesInNamespace(ConstString type_name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,TypeList & type_list)967 void Module::FindTypesInNamespace(ConstString type_name,
968 const CompilerDeclContext &parent_decl_ctx,
969 size_t max_matches, TypeList &type_list) {
970 TypeMap types_map;
971 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
972 FindTypes_Impl(type_name, parent_decl_ctx, max_matches, searched_symbol_files,
973 types_map);
974 if (types_map.GetSize()) {
975 SymbolContext sc;
976 sc.module_sp = shared_from_this();
977 sc.SortTypeList(types_map, type_list);
978 }
979 }
980
FindFirstType(const SymbolContext & sc,ConstString name,bool exact_match)981 lldb::TypeSP Module::FindFirstType(const SymbolContext &sc, ConstString name,
982 bool exact_match) {
983 TypeList type_list;
984 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
985 FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
986 if (type_list.GetSize())
987 return type_list.GetTypeAtIndex(0);
988 return TypeSP();
989 }
990
FindTypes(ConstString name,bool exact_match,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeList & types)991 void Module::FindTypes(
992 ConstString name, bool exact_match, size_t max_matches,
993 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
994 TypeList &types) {
995 const char *type_name_cstr = name.GetCString();
996 llvm::StringRef type_scope;
997 llvm::StringRef type_basename;
998 TypeClass type_class = eTypeClassAny;
999 TypeMap typesmap;
1000
1001 if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename,
1002 type_class)) {
1003 // Check if "name" starts with "::" which means the qualified type starts
1004 // from the root namespace and implies and exact match. The typenames we
1005 // get back from clang do not start with "::" so we need to strip this off
1006 // in order to get the qualified names to match
1007 exact_match = type_scope.consume_front("::");
1008
1009 ConstString type_basename_const_str(type_basename);
1010 FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches,
1011 searched_symbol_files, typesmap);
1012 if (typesmap.GetSize())
1013 typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
1014 exact_match);
1015 } else {
1016 // The type is not in a namespace/class scope, just search for it by
1017 // basename
1018 if (type_class != eTypeClassAny && !type_basename.empty()) {
1019 // The "type_name_cstr" will have been modified if we have a valid type
1020 // class prefix (like "struct", "class", "union", "typedef" etc).
1021 FindTypes_Impl(ConstString(type_basename), CompilerDeclContext(),
1022 UINT_MAX, searched_symbol_files, typesmap);
1023 typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
1024 exact_match);
1025 } else {
1026 FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX,
1027 searched_symbol_files, typesmap);
1028 if (exact_match) {
1029 typesmap.RemoveMismatchedTypes(type_scope, name.GetStringRef(),
1030 type_class, exact_match);
1031 }
1032 }
1033 }
1034 if (typesmap.GetSize()) {
1035 SymbolContext sc;
1036 sc.module_sp = shared_from_this();
1037 sc.SortTypeList(typesmap, types);
1038 }
1039 }
1040
FindTypes(llvm::ArrayRef<CompilerContext> pattern,LanguageSet languages,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)1041 void Module::FindTypes(
1042 llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1043 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1044 TypeMap &types) {
1045 // If a scoped timer is needed, place it in a SymbolFile::FindTypes override.
1046 // A timer here is too high volume for some cases, for example when calling
1047 // FindTypes on each object file.
1048 if (SymbolFile *symbols = GetSymbolFile())
1049 symbols->FindTypes(pattern, languages, searched_symbol_files, types);
1050 }
1051
GetSymbolFile(bool can_create,Stream * feedback_strm)1052 SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
1053 if (!m_did_load_symfile.load()) {
1054 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1055 if (!m_did_load_symfile.load() && can_create) {
1056 ObjectFile *obj_file = GetObjectFile();
1057 if (obj_file != nullptr) {
1058 LLDB_SCOPED_TIMER();
1059 m_symfile_up.reset(
1060 SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
1061 m_did_load_symfile = true;
1062 }
1063 }
1064 }
1065 return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
1066 }
1067
GetSymtab()1068 Symtab *Module::GetSymtab() {
1069 if (SymbolFile *symbols = GetSymbolFile())
1070 return symbols->GetSymtab();
1071 return nullptr;
1072 }
1073
SetFileSpecAndObjectName(const FileSpec & file,ConstString object_name)1074 void Module::SetFileSpecAndObjectName(const FileSpec &file,
1075 ConstString object_name) {
1076 // Container objects whose paths do not specify a file directly can call this
1077 // function to correct the file and object names.
1078 m_file = file;
1079 m_mod_time = FileSystem::Instance().GetModificationTime(file);
1080 m_object_name = object_name;
1081 }
1082
GetArchitecture() const1083 const ArchSpec &Module::GetArchitecture() const { return m_arch; }
1084
GetSpecificationDescription() const1085 std::string Module::GetSpecificationDescription() const {
1086 std::string spec(GetFileSpec().GetPath());
1087 if (m_object_name) {
1088 spec += '(';
1089 spec += m_object_name.GetCString();
1090 spec += ')';
1091 }
1092 return spec;
1093 }
1094
GetDescription(llvm::raw_ostream & s,lldb::DescriptionLevel level)1095 void Module::GetDescription(llvm::raw_ostream &s,
1096 lldb::DescriptionLevel level) {
1097 if (level >= eDescriptionLevelFull) {
1098 if (m_arch.IsValid())
1099 s << llvm::formatv("({0}) ", m_arch.GetArchitectureName());
1100 }
1101
1102 if (level == eDescriptionLevelBrief) {
1103 const char *filename = m_file.GetFilename().GetCString();
1104 if (filename)
1105 s << filename;
1106 } else {
1107 char path[PATH_MAX];
1108 if (m_file.GetPath(path, sizeof(path)))
1109 s << path;
1110 }
1111
1112 const char *object_name = m_object_name.GetCString();
1113 if (object_name)
1114 s << llvm::formatv("({0})", object_name);
1115 }
1116
FileHasChanged() const1117 bool Module::FileHasChanged() const {
1118 // We have provided the DataBuffer for this module to avoid accessing the
1119 // filesystem. We never want to reload those files.
1120 if (m_data_sp)
1121 return false;
1122 if (!m_file_has_changed)
1123 m_file_has_changed =
1124 (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
1125 return m_file_has_changed;
1126 }
1127
ReportWarningOptimization(std::optional<lldb::user_id_t> debugger_id)1128 void Module::ReportWarningOptimization(
1129 std::optional<lldb::user_id_t> debugger_id) {
1130 ConstString file_name = GetFileSpec().GetFilename();
1131 if (file_name.IsEmpty())
1132 return;
1133
1134 StreamString ss;
1135 ss << file_name.GetStringRef()
1136 << " was compiled with optimization - stepping may behave "
1137 "oddly; variables may not be available.";
1138 Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
1139 &m_optimization_warning);
1140 }
1141
ReportWarningUnsupportedLanguage(LanguageType language,std::optional<lldb::user_id_t> debugger_id)1142 void Module::ReportWarningUnsupportedLanguage(
1143 LanguageType language, std::optional<lldb::user_id_t> debugger_id) {
1144 StreamString ss;
1145 ss << "This version of LLDB has no plugin for the language \""
1146 << Language::GetNameForLanguageType(language)
1147 << "\". "
1148 "Inspection of frame variables will be limited.";
1149 Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
1150 &m_language_warning);
1151 }
1152
ReportErrorIfModifyDetected(const llvm::formatv_object_base & payload)1153 void Module::ReportErrorIfModifyDetected(
1154 const llvm::formatv_object_base &payload) {
1155 if (!m_first_file_changed_log) {
1156 if (FileHasChanged()) {
1157 m_first_file_changed_log = true;
1158 StreamString strm;
1159 strm.PutCString("the object file ");
1160 GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
1161 strm.PutCString(" has been modified\n");
1162 strm.PutCString(payload.str());
1163 strm.PutCString("The debug session should be aborted as the original "
1164 "debug information has been overwritten.");
1165 Debugger::ReportError(std::string(strm.GetString()));
1166 }
1167 }
1168 }
1169
ReportError(const llvm::formatv_object_base & payload)1170 void Module::ReportError(const llvm::formatv_object_base &payload) {
1171 StreamString strm;
1172 GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);
1173 strm.PutChar(' ');
1174 strm.PutCString(payload.str());
1175 Debugger::ReportError(strm.GetString().str());
1176 }
1177
ReportWarning(const llvm::formatv_object_base & payload)1178 void Module::ReportWarning(const llvm::formatv_object_base &payload) {
1179 StreamString strm;
1180 GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
1181 strm.PutChar(' ');
1182 strm.PutCString(payload.str());
1183 Debugger::ReportWarning(std::string(strm.GetString()));
1184 }
1185
LogMessage(Log * log,const llvm::formatv_object_base & payload)1186 void Module::LogMessage(Log *log, const llvm::formatv_object_base &payload) {
1187 StreamString log_message;
1188 GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
1189 log_message.PutCString(": ");
1190 log_message.PutCString(payload.str());
1191 log->PutCString(log_message.GetData());
1192 }
1193
LogMessageVerboseBacktrace(Log * log,const llvm::formatv_object_base & payload)1194 void Module::LogMessageVerboseBacktrace(
1195 Log *log, const llvm::formatv_object_base &payload) {
1196 StreamString log_message;
1197 GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
1198 log_message.PutCString(": ");
1199 log_message.PutCString(payload.str());
1200 if (log->GetVerbose()) {
1201 std::string back_trace;
1202 llvm::raw_string_ostream stream(back_trace);
1203 llvm::sys::PrintStackTrace(stream);
1204 log_message.PutCString(back_trace);
1205 }
1206 log->PutCString(log_message.GetData());
1207 }
1208
Dump(Stream * s)1209 void Module::Dump(Stream *s) {
1210 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1211 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
1212 s->Indent();
1213 s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),
1214 m_object_name ? "(" : "",
1215 m_object_name ? m_object_name.GetCString() : "",
1216 m_object_name ? ")" : "");
1217
1218 s->IndentMore();
1219
1220 ObjectFile *objfile = GetObjectFile();
1221 if (objfile)
1222 objfile->Dump(s);
1223
1224 if (SymbolFile *symbols = GetSymbolFile())
1225 symbols->Dump(*s);
1226
1227 s->IndentLess();
1228 }
1229
GetObjectName() const1230 ConstString Module::GetObjectName() const { return m_object_name; }
1231
GetObjectFile()1232 ObjectFile *Module::GetObjectFile() {
1233 if (!m_did_load_objfile.load()) {
1234 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1235 if (!m_did_load_objfile.load()) {
1236 LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",
1237 GetFileSpec().GetFilename().AsCString(""));
1238 lldb::offset_t data_offset = 0;
1239 lldb::offset_t file_size = 0;
1240
1241 if (m_data_sp)
1242 file_size = m_data_sp->GetByteSize();
1243 else if (m_file)
1244 file_size = FileSystem::Instance().GetByteSize(m_file);
1245
1246 if (file_size > m_object_offset) {
1247 m_did_load_objfile = true;
1248 // FindPlugin will modify its data_sp argument. Do not let it
1249 // modify our m_data_sp member.
1250 auto data_sp = m_data_sp;
1251 m_objfile_sp = ObjectFile::FindPlugin(
1252 shared_from_this(), &m_file, m_object_offset,
1253 file_size - m_object_offset, data_sp, data_offset);
1254 if (m_objfile_sp) {
1255 // Once we get the object file, update our module with the object
1256 // file's architecture since it might differ in vendor/os if some
1257 // parts were unknown. But since the matching arch might already be
1258 // more specific than the generic COFF architecture, only merge in
1259 // those values that overwrite unspecified unknown values.
1260 m_arch.MergeFrom(m_objfile_sp->GetArchitecture());
1261 } else {
1262 ReportError("failed to load objfile for {0}",
1263 GetFileSpec().GetPath().c_str());
1264 }
1265 }
1266 }
1267 }
1268 return m_objfile_sp.get();
1269 }
1270
GetSectionList()1271 SectionList *Module::GetSectionList() {
1272 // Populate m_sections_up with sections from objfile.
1273 if (!m_sections_up) {
1274 ObjectFile *obj_file = GetObjectFile();
1275 if (obj_file != nullptr)
1276 obj_file->CreateSections(*GetUnifiedSectionList());
1277 }
1278 return m_sections_up.get();
1279 }
1280
SectionFileAddressesChanged()1281 void Module::SectionFileAddressesChanged() {
1282 ObjectFile *obj_file = GetObjectFile();
1283 if (obj_file)
1284 obj_file->SectionFileAddressesChanged();
1285 if (SymbolFile *symbols = GetSymbolFile())
1286 symbols->SectionFileAddressesChanged();
1287 }
1288
GetUnwindTable()1289 UnwindTable &Module::GetUnwindTable() {
1290 if (!m_unwind_table) {
1291 m_unwind_table.emplace(*this);
1292 if (!m_symfile_spec)
1293 Symbols::DownloadSymbolFileAsync(GetUUID());
1294 }
1295 return *m_unwind_table;
1296 }
1297
GetUnifiedSectionList()1298 SectionList *Module::GetUnifiedSectionList() {
1299 if (!m_sections_up)
1300 m_sections_up = std::make_unique<SectionList>();
1301 return m_sections_up.get();
1302 }
1303
FindFirstSymbolWithNameAndType(ConstString name,SymbolType symbol_type)1304 const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,
1305 SymbolType symbol_type) {
1306 LLDB_SCOPED_TIMERF(
1307 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
1308 name.AsCString(), symbol_type);
1309 if (Symtab *symtab = GetSymtab())
1310 return symtab->FindFirstSymbolWithNameAndType(
1311 name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
1312 return nullptr;
1313 }
SymbolIndicesToSymbolContextList(Symtab * symtab,std::vector<uint32_t> & symbol_indexes,SymbolContextList & sc_list)1314 void Module::SymbolIndicesToSymbolContextList(
1315 Symtab *symtab, std::vector<uint32_t> &symbol_indexes,
1316 SymbolContextList &sc_list) {
1317 // No need to protect this call using m_mutex all other method calls are
1318 // already thread safe.
1319
1320 size_t num_indices = symbol_indexes.size();
1321 if (num_indices > 0) {
1322 SymbolContext sc;
1323 CalculateSymbolContext(&sc);
1324 for (size_t i = 0; i < num_indices; i++) {
1325 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
1326 if (sc.symbol)
1327 sc_list.Append(sc);
1328 }
1329 }
1330 }
1331
FindFunctionSymbols(ConstString name,uint32_t name_type_mask,SymbolContextList & sc_list)1332 void Module::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
1333 SymbolContextList &sc_list) {
1334 LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
1335 name.AsCString(), name_type_mask);
1336 if (Symtab *symtab = GetSymtab())
1337 symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
1338 }
1339
FindSymbolsWithNameAndType(ConstString name,SymbolType symbol_type,SymbolContextList & sc_list)1340 void Module::FindSymbolsWithNameAndType(ConstString name,
1341 SymbolType symbol_type,
1342 SymbolContextList &sc_list) {
1343 // No need to protect this call using m_mutex all other method calls are
1344 // already thread safe.
1345 if (Symtab *symtab = GetSymtab()) {
1346 std::vector<uint32_t> symbol_indexes;
1347 symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
1348 SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
1349 }
1350 }
1351
FindSymbolsMatchingRegExAndType(const RegularExpression & regex,SymbolType symbol_type,SymbolContextList & sc_list,Mangled::NamePreference mangling_preference)1352 void Module::FindSymbolsMatchingRegExAndType(
1353 const RegularExpression ®ex, SymbolType symbol_type,
1354 SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
1355 // No need to protect this call using m_mutex all other method calls are
1356 // already thread safe.
1357 LLDB_SCOPED_TIMERF(
1358 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
1359 regex.GetText().str().c_str(), symbol_type);
1360 if (Symtab *symtab = GetSymtab()) {
1361 std::vector<uint32_t> symbol_indexes;
1362 symtab->FindAllSymbolsMatchingRexExAndType(
1363 regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
1364 symbol_indexes, mangling_preference);
1365 SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
1366 }
1367 }
1368
PreloadSymbols()1369 void Module::PreloadSymbols() {
1370 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1371 SymbolFile *sym_file = GetSymbolFile();
1372 if (!sym_file)
1373 return;
1374
1375 // Load the object file symbol table and any symbols from the SymbolFile that
1376 // get appended using SymbolFile::AddSymbols(...).
1377 if (Symtab *symtab = sym_file->GetSymtab())
1378 symtab->PreloadSymbols();
1379
1380 // Now let the symbol file preload its data and the symbol table will be
1381 // available without needing to take the module lock.
1382 sym_file->PreloadSymbols();
1383 }
1384
SetSymbolFileFileSpec(const FileSpec & file)1385 void Module::SetSymbolFileFileSpec(const FileSpec &file) {
1386 if (!FileSystem::Instance().Exists(file))
1387 return;
1388 if (m_symfile_up) {
1389 // Remove any sections in the unified section list that come from the
1390 // current symbol vendor.
1391 SectionList *section_list = GetSectionList();
1392 SymbolFile *symbol_file = GetSymbolFile();
1393 if (section_list && symbol_file) {
1394 ObjectFile *obj_file = symbol_file->GetObjectFile();
1395 // Make sure we have an object file and that the symbol vendor's objfile
1396 // isn't the same as the module's objfile before we remove any sections
1397 // for it...
1398 if (obj_file) {
1399 // Check to make sure we aren't trying to specify the file we already
1400 // have
1401 if (obj_file->GetFileSpec() == file) {
1402 // We are being told to add the exact same file that we already have
1403 // we don't have to do anything.
1404 return;
1405 }
1406
1407 // Cleare the current symtab as we are going to replace it with a new
1408 // one
1409 obj_file->ClearSymtab();
1410
1411 // Clear the unwind table too, as that may also be affected by the
1412 // symbol file information.
1413 m_unwind_table.reset();
1414
1415 // The symbol file might be a directory bundle ("/tmp/a.out.dSYM")
1416 // instead of a full path to the symbol file within the bundle
1417 // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
1418 // check this
1419
1420 if (FileSystem::Instance().IsDirectory(file)) {
1421 std::string new_path(file.GetPath());
1422 std::string old_path(obj_file->GetFileSpec().GetPath());
1423 if (llvm::StringRef(old_path).startswith(new_path)) {
1424 // We specified the same bundle as the symbol file that we already
1425 // have
1426 return;
1427 }
1428 }
1429
1430 if (obj_file != m_objfile_sp.get()) {
1431 size_t num_sections = section_list->GetNumSections(0);
1432 for (size_t idx = num_sections; idx > 0; --idx) {
1433 lldb::SectionSP section_sp(
1434 section_list->GetSectionAtIndex(idx - 1));
1435 if (section_sp->GetObjectFile() == obj_file) {
1436 section_list->DeleteSection(idx - 1);
1437 }
1438 }
1439 }
1440 }
1441 }
1442 // Keep all old symbol files around in case there are any lingering type
1443 // references in any SBValue objects that might have been handed out.
1444 m_old_symfiles.push_back(std::move(m_symfile_up));
1445 }
1446 m_symfile_spec = file;
1447 m_symfile_up.reset();
1448 m_did_load_symfile = false;
1449 }
1450
IsExecutable()1451 bool Module::IsExecutable() {
1452 if (GetObjectFile() == nullptr)
1453 return false;
1454 else
1455 return GetObjectFile()->IsExecutable();
1456 }
1457
IsLoadedInTarget(Target * target)1458 bool Module::IsLoadedInTarget(Target *target) {
1459 ObjectFile *obj_file = GetObjectFile();
1460 if (obj_file) {
1461 SectionList *sections = GetSectionList();
1462 if (sections != nullptr) {
1463 size_t num_sections = sections->GetSize();
1464 for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {
1465 SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
1466 if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {
1467 return true;
1468 }
1469 }
1470 }
1471 }
1472 return false;
1473 }
1474
LoadScriptingResourceInTarget(Target * target,Status & error,Stream * feedback_stream)1475 bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,
1476 Stream *feedback_stream) {
1477 if (!target) {
1478 error.SetErrorString("invalid destination Target");
1479 return false;
1480 }
1481
1482 LoadScriptFromSymFile should_load =
1483 target->TargetProperties::GetLoadScriptFromSymbolFile();
1484
1485 if (should_load == eLoadScriptFromSymFileFalse)
1486 return false;
1487
1488 Debugger &debugger = target->GetDebugger();
1489 const ScriptLanguage script_language = debugger.GetScriptLanguage();
1490 if (script_language != eScriptLanguageNone) {
1491
1492 PlatformSP platform_sp(target->GetPlatform());
1493
1494 if (!platform_sp) {
1495 error.SetErrorString("invalid Platform");
1496 return false;
1497 }
1498
1499 FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
1500 target, *this, feedback_stream);
1501
1502 const uint32_t num_specs = file_specs.GetSize();
1503 if (num_specs) {
1504 ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
1505 if (script_interpreter) {
1506 for (uint32_t i = 0; i < num_specs; ++i) {
1507 FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
1508 if (scripting_fspec &&
1509 FileSystem::Instance().Exists(scripting_fspec)) {
1510 if (should_load == eLoadScriptFromSymFileWarn) {
1511 if (feedback_stream)
1512 feedback_stream->Printf(
1513 "warning: '%s' contains a debug script. To run this script "
1514 "in "
1515 "this debug session:\n\n command script import "
1516 "\"%s\"\n\n"
1517 "To run all discovered debug scripts in this session:\n\n"
1518 " settings set target.load-script-from-symbol-file "
1519 "true\n",
1520 GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1521 scripting_fspec.GetPath().c_str());
1522 return false;
1523 }
1524 StreamString scripting_stream;
1525 scripting_fspec.Dump(scripting_stream.AsRawOstream());
1526 LoadScriptOptions options;
1527 bool did_load = script_interpreter->LoadScriptingModule(
1528 scripting_stream.GetData(), options, error);
1529 if (!did_load)
1530 return false;
1531 }
1532 }
1533 } else {
1534 error.SetErrorString("invalid ScriptInterpreter");
1535 return false;
1536 }
1537 }
1538 }
1539 return true;
1540 }
1541
SetArchitecture(const ArchSpec & new_arch)1542 bool Module::SetArchitecture(const ArchSpec &new_arch) {
1543 if (!m_arch.IsValid()) {
1544 m_arch = new_arch;
1545 return true;
1546 }
1547 return m_arch.IsCompatibleMatch(new_arch);
1548 }
1549
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset,bool & changed)1550 bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
1551 bool value_is_offset, bool &changed) {
1552 ObjectFile *object_file = GetObjectFile();
1553 if (object_file != nullptr) {
1554 changed = object_file->SetLoadAddress(target, value, value_is_offset);
1555 return true;
1556 } else {
1557 changed = false;
1558 }
1559 return false;
1560 }
1561
MatchesModuleSpec(const ModuleSpec & module_ref)1562 bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
1563 const UUID &uuid = module_ref.GetUUID();
1564
1565 if (uuid.IsValid()) {
1566 // If the UUID matches, then nothing more needs to match...
1567 return (uuid == GetUUID());
1568 }
1569
1570 const FileSpec &file_spec = module_ref.GetFileSpec();
1571 if (!FileSpec::Match(file_spec, m_file) &&
1572 !FileSpec::Match(file_spec, m_platform_file))
1573 return false;
1574
1575 const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
1576 if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))
1577 return false;
1578
1579 const ArchSpec &arch = module_ref.GetArchitecture();
1580 if (arch.IsValid()) {
1581 if (!m_arch.IsCompatibleMatch(arch))
1582 return false;
1583 }
1584
1585 ConstString object_name = module_ref.GetObjectName();
1586 if (object_name) {
1587 if (object_name != GetObjectName())
1588 return false;
1589 }
1590 return true;
1591 }
1592
FindSourceFile(const FileSpec & orig_spec,FileSpec & new_spec) const1593 bool Module::FindSourceFile(const FileSpec &orig_spec,
1594 FileSpec &new_spec) const {
1595 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1596 if (auto remapped = m_source_mappings.FindFile(orig_spec)) {
1597 new_spec = *remapped;
1598 return true;
1599 }
1600 return false;
1601 }
1602
RemapSourceFile(llvm::StringRef path) const1603 std::optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {
1604 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1605 if (auto remapped = m_source_mappings.RemapPath(path))
1606 return remapped->GetPath();
1607 return {};
1608 }
1609
RegisterXcodeSDK(llvm::StringRef sdk_name,llvm::StringRef sysroot)1610 void Module::RegisterXcodeSDK(llvm::StringRef sdk_name,
1611 llvm::StringRef sysroot) {
1612 XcodeSDK sdk(sdk_name.str());
1613 auto sdk_path_or_err = HostInfo::GetXcodeSDKPath(sdk);
1614
1615 if (!sdk_path_or_err) {
1616 Debugger::ReportError("Error while searching for Xcode SDK: " +
1617 toString(sdk_path_or_err.takeError()));
1618 return;
1619 }
1620
1621 auto sdk_path = *sdk_path_or_err;
1622 if (sdk_path.empty())
1623 return;
1624 // If the SDK changed for a previously registered source path, update it.
1625 // This could happend with -fdebug-prefix-map, otherwise it's unlikely.
1626 if (!m_source_mappings.Replace(sysroot, sdk_path, true))
1627 // In the general case, however, append it to the list.
1628 m_source_mappings.Append(sysroot, sdk_path, false);
1629 }
1630
MergeArchitecture(const ArchSpec & arch_spec)1631 bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
1632 if (!arch_spec.IsValid())
1633 return false;
1634 LLDB_LOGF(GetLog(LLDBLog::Object | LLDBLog::Modules),
1635 "module has arch %s, merging/replacing with arch %s",
1636 m_arch.GetTriple().getTriple().c_str(),
1637 arch_spec.GetTriple().getTriple().c_str());
1638 if (!m_arch.IsCompatibleMatch(arch_spec)) {
1639 // The new architecture is different, we just need to replace it.
1640 return SetArchitecture(arch_spec);
1641 }
1642
1643 // Merge bits from arch_spec into "merged_arch" and set our architecture.
1644 ArchSpec merged_arch(m_arch);
1645 merged_arch.MergeFrom(arch_spec);
1646 // SetArchitecture() is a no-op if m_arch is already valid.
1647 m_arch = ArchSpec();
1648 return SetArchitecture(merged_arch);
1649 }
1650
GetVersion()1651 llvm::VersionTuple Module::GetVersion() {
1652 if (ObjectFile *obj_file = GetObjectFile())
1653 return obj_file->GetVersion();
1654 return llvm::VersionTuple();
1655 }
1656
GetIsDynamicLinkEditor()1657 bool Module::GetIsDynamicLinkEditor() {
1658 ObjectFile *obj_file = GetObjectFile();
1659
1660 if (obj_file)
1661 return obj_file->GetIsDynamicLinkEditor();
1662
1663 return false;
1664 }
1665
Hash()1666 uint32_t Module::Hash() {
1667 std::string identifier;
1668 llvm::raw_string_ostream id_strm(identifier);
1669 id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath();
1670 if (m_object_name)
1671 id_strm << '(' << m_object_name.GetStringRef() << ')';
1672 if (m_object_offset > 0)
1673 id_strm << m_object_offset;
1674 const auto mtime = llvm::sys::toTimeT(m_object_mod_time);
1675 if (mtime > 0)
1676 id_strm << mtime;
1677 return llvm::djbHash(id_strm.str());
1678 }
1679
GetCacheKey()1680 std::string Module::GetCacheKey() {
1681 std::string key;
1682 llvm::raw_string_ostream strm(key);
1683 strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename();
1684 if (m_object_name)
1685 strm << '(' << m_object_name.GetStringRef() << ')';
1686 strm << '-' << llvm::format_hex(Hash(), 10);
1687 return strm.str();
1688 }
1689
GetIndexCache()1690 DataFileCache *Module::GetIndexCache() {
1691 if (!ModuleList::GetGlobalModuleListProperties().GetEnableLLDBIndexCache())
1692 return nullptr;
1693 // NOTE: intentional leak so we don't crash if global destructor chain gets
1694 // called as other threads still use the result of this function
1695 static DataFileCache *g_data_file_cache =
1696 new DataFileCache(ModuleList::GetGlobalModuleListProperties()
1697 .GetLLDBIndexCachePath()
1698 .GetPath());
1699 return g_data_file_cache;
1700 }
1701