1dda28197Spatrick //===-- Module.cpp --------------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Core/Module.h"
10061da546Spatrick
11061da546Spatrick #include "lldb/Core/AddressRange.h"
12061da546Spatrick #include "lldb/Core/AddressResolverFileLine.h"
13*f6aab3d8Srobert #include "lldb/Core/DataFileCache.h"
14061da546Spatrick #include "lldb/Core/Debugger.h"
15061da546Spatrick #include "lldb/Core/FileSpecList.h"
16061da546Spatrick #include "lldb/Core/Mangled.h"
17061da546Spatrick #include "lldb/Core/ModuleSpec.h"
18061da546Spatrick #include "lldb/Core/SearchFilter.h"
19061da546Spatrick #include "lldb/Core/Section.h"
20061da546Spatrick #include "lldb/Host/FileSystem.h"
21061da546Spatrick #include "lldb/Host/Host.h"
22dda28197Spatrick #include "lldb/Host/HostInfo.h"
23061da546Spatrick #include "lldb/Interpreter/CommandInterpreter.h"
24061da546Spatrick #include "lldb/Interpreter/ScriptInterpreter.h"
25061da546Spatrick #include "lldb/Symbol/CompileUnit.h"
26061da546Spatrick #include "lldb/Symbol/Function.h"
27*f6aab3d8Srobert #include "lldb/Symbol/LocateSymbolFile.h"
28061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
29061da546Spatrick #include "lldb/Symbol/Symbol.h"
30061da546Spatrick #include "lldb/Symbol/SymbolContext.h"
31061da546Spatrick #include "lldb/Symbol/SymbolFile.h"
32061da546Spatrick #include "lldb/Symbol/SymbolVendor.h"
33061da546Spatrick #include "lldb/Symbol/Symtab.h"
34061da546Spatrick #include "lldb/Symbol/Type.h"
35061da546Spatrick #include "lldb/Symbol/TypeList.h"
36061da546Spatrick #include "lldb/Symbol/TypeMap.h"
37061da546Spatrick #include "lldb/Symbol/TypeSystem.h"
38061da546Spatrick #include "lldb/Target/Language.h"
39061da546Spatrick #include "lldb/Target/Process.h"
40061da546Spatrick #include "lldb/Target/Target.h"
41061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
42061da546Spatrick #include "lldb/Utility/LLDBAssert.h"
43*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
44061da546Spatrick #include "lldb/Utility/Log.h"
45061da546Spatrick #include "lldb/Utility/RegularExpression.h"
46061da546Spatrick #include "lldb/Utility/Status.h"
47061da546Spatrick #include "lldb/Utility/Stream.h"
48061da546Spatrick #include "lldb/Utility/StreamString.h"
49061da546Spatrick #include "lldb/Utility/Timer.h"
50061da546Spatrick
51061da546Spatrick #if defined(_WIN32)
52061da546Spatrick #include "lldb/Host/windows/PosixApi.h"
53061da546Spatrick #endif
54061da546Spatrick
55061da546Spatrick #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
56061da546Spatrick #include "Plugins/Language/ObjC/ObjCLanguage.h"
57061da546Spatrick
58061da546Spatrick #include "llvm/ADT/STLExtras.h"
59061da546Spatrick #include "llvm/Support/Compiler.h"
60*f6aab3d8Srobert #include "llvm/Support/DJB.h"
61061da546Spatrick #include "llvm/Support/FileSystem.h"
62*f6aab3d8Srobert #include "llvm/Support/FormatVariadic.h"
63*f6aab3d8Srobert #include "llvm/Support/JSON.h"
64061da546Spatrick #include "llvm/Support/Signals.h"
65061da546Spatrick #include "llvm/Support/raw_ostream.h"
66061da546Spatrick
67be691f3bSpatrick #include <cassert>
68be691f3bSpatrick #include <cinttypes>
69be691f3bSpatrick #include <cstdarg>
70061da546Spatrick #include <cstdint>
71be691f3bSpatrick #include <cstring>
72061da546Spatrick #include <map>
73*f6aab3d8Srobert #include <optional>
74061da546Spatrick #include <type_traits>
75061da546Spatrick #include <utility>
76061da546Spatrick
77061da546Spatrick namespace lldb_private {
78061da546Spatrick class CompilerDeclContext;
79061da546Spatrick }
80061da546Spatrick namespace lldb_private {
81061da546Spatrick class VariableList;
82061da546Spatrick }
83061da546Spatrick
84061da546Spatrick using namespace lldb;
85061da546Spatrick using namespace lldb_private;
86061da546Spatrick
87061da546Spatrick // Shared pointers to modules track module lifetimes in targets and in the
88061da546Spatrick // global module, but this collection will track all module objects that are
89061da546Spatrick // still alive
90061da546Spatrick typedef std::vector<Module *> ModuleCollection;
91061da546Spatrick
GetModuleCollection()92061da546Spatrick static ModuleCollection &GetModuleCollection() {
93061da546Spatrick // This module collection needs to live past any module, so we could either
94061da546Spatrick // make it a shared pointer in each module or just leak is. Since it is only
95061da546Spatrick // an empty vector by the time all the modules have gone away, we just leak
96061da546Spatrick // it for now. If we decide this is a big problem we can introduce a
97061da546Spatrick // Finalize method that will tear everything down in a predictable order.
98061da546Spatrick
99061da546Spatrick static ModuleCollection *g_module_collection = nullptr;
100061da546Spatrick if (g_module_collection == nullptr)
101061da546Spatrick g_module_collection = new ModuleCollection();
102061da546Spatrick
103061da546Spatrick return *g_module_collection;
104061da546Spatrick }
105061da546Spatrick
GetAllocationModuleCollectionMutex()106061da546Spatrick std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
107061da546Spatrick // NOTE: The mutex below must be leaked since the global module list in
108061da546Spatrick // the ModuleList class will get torn at some point, and we can't know if it
109061da546Spatrick // will tear itself down before the "g_module_collection_mutex" below will.
110061da546Spatrick // So we leak a Mutex object below to safeguard against that
111061da546Spatrick
112061da546Spatrick static std::recursive_mutex *g_module_collection_mutex = nullptr;
113061da546Spatrick if (g_module_collection_mutex == nullptr)
114061da546Spatrick g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
115061da546Spatrick return *g_module_collection_mutex;
116061da546Spatrick }
117061da546Spatrick
GetNumberAllocatedModules()118061da546Spatrick size_t Module::GetNumberAllocatedModules() {
119061da546Spatrick std::lock_guard<std::recursive_mutex> guard(
120061da546Spatrick GetAllocationModuleCollectionMutex());
121061da546Spatrick return GetModuleCollection().size();
122061da546Spatrick }
123061da546Spatrick
GetAllocatedModuleAtIndex(size_t idx)124061da546Spatrick Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
125061da546Spatrick std::lock_guard<std::recursive_mutex> guard(
126061da546Spatrick GetAllocationModuleCollectionMutex());
127061da546Spatrick ModuleCollection &modules = GetModuleCollection();
128061da546Spatrick if (idx < modules.size())
129061da546Spatrick return modules[idx];
130061da546Spatrick return nullptr;
131061da546Spatrick }
132061da546Spatrick
Module(const ModuleSpec & module_spec)133061da546Spatrick Module::Module(const ModuleSpec &module_spec)
134*f6aab3d8Srobert : m_file_has_changed(false), m_first_file_changed_log(false) {
135061da546Spatrick // Scope for locker below...
136061da546Spatrick {
137061da546Spatrick std::lock_guard<std::recursive_mutex> guard(
138061da546Spatrick GetAllocationModuleCollectionMutex());
139061da546Spatrick GetModuleCollection().push_back(this);
140061da546Spatrick }
141061da546Spatrick
142*f6aab3d8Srobert Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
143061da546Spatrick if (log != nullptr)
144061da546Spatrick LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
145061da546Spatrick static_cast<void *>(this),
146061da546Spatrick module_spec.GetArchitecture().GetArchitectureName(),
147061da546Spatrick module_spec.GetFileSpec().GetPath().c_str(),
148061da546Spatrick module_spec.GetObjectName().IsEmpty() ? "" : "(",
149*f6aab3d8Srobert module_spec.GetObjectName().AsCString(""),
150061da546Spatrick module_spec.GetObjectName().IsEmpty() ? "" : ")");
151061da546Spatrick
152dda28197Spatrick auto data_sp = module_spec.GetData();
153dda28197Spatrick lldb::offset_t file_size = 0;
154dda28197Spatrick if (data_sp)
155dda28197Spatrick file_size = data_sp->GetByteSize();
156dda28197Spatrick
157061da546Spatrick // First extract all module specifications from the file using the local file
158061da546Spatrick // path. If there are no specifications, then don't fill anything in
159061da546Spatrick ModuleSpecList modules_specs;
160dda28197Spatrick if (ObjectFile::GetModuleSpecifications(
161dda28197Spatrick module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)
162061da546Spatrick return;
163061da546Spatrick
164061da546Spatrick // Now make sure that one of the module specifications matches what we just
165061da546Spatrick // extract. We might have a module specification that specifies a file
166061da546Spatrick // "/usr/lib/dyld" with UUID XXX, but we might have a local version of
167061da546Spatrick // "/usr/lib/dyld" that has
168061da546Spatrick // UUID YYY and we don't want those to match. If they don't match, just don't
169061da546Spatrick // fill any ivars in so we don't accidentally grab the wrong file later since
170061da546Spatrick // they don't match...
171061da546Spatrick ModuleSpec matching_module_spec;
172061da546Spatrick if (!modules_specs.FindMatchingModuleSpec(module_spec,
173061da546Spatrick matching_module_spec)) {
174061da546Spatrick if (log) {
175061da546Spatrick LLDB_LOGF(log, "Found local object file but the specs didn't match");
176061da546Spatrick }
177061da546Spatrick return;
178061da546Spatrick }
179061da546Spatrick
180dda28197Spatrick // Set m_data_sp if it was initially provided in the ModuleSpec. Note that
181dda28197Spatrick // we cannot use the data_sp variable here, because it will have been
182dda28197Spatrick // modified by GetModuleSpecifications().
183dda28197Spatrick if (auto module_spec_data_sp = module_spec.GetData()) {
184dda28197Spatrick m_data_sp = module_spec_data_sp;
185dda28197Spatrick m_mod_time = {};
186dda28197Spatrick } else {
187061da546Spatrick if (module_spec.GetFileSpec())
188061da546Spatrick m_mod_time =
189dda28197Spatrick FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
190dda28197Spatrick else if (matching_module_spec.GetFileSpec())
191dda28197Spatrick m_mod_time = FileSystem::Instance().GetModificationTime(
192dda28197Spatrick matching_module_spec.GetFileSpec());
193dda28197Spatrick }
194061da546Spatrick
195061da546Spatrick // Copy the architecture from the actual spec if we got one back, else use
196061da546Spatrick // the one that was specified
197061da546Spatrick if (matching_module_spec.GetArchitecture().IsValid())
198061da546Spatrick m_arch = matching_module_spec.GetArchitecture();
199061da546Spatrick else if (module_spec.GetArchitecture().IsValid())
200061da546Spatrick m_arch = module_spec.GetArchitecture();
201061da546Spatrick
202061da546Spatrick // Copy the file spec over and use the specified one (if there was one) so we
203061da546Spatrick // don't use a path that might have gotten resolved a path in
204061da546Spatrick // 'matching_module_spec'
205061da546Spatrick if (module_spec.GetFileSpec())
206061da546Spatrick m_file = module_spec.GetFileSpec();
207061da546Spatrick else if (matching_module_spec.GetFileSpec())
208061da546Spatrick m_file = matching_module_spec.GetFileSpec();
209061da546Spatrick
210061da546Spatrick // Copy the platform file spec over
211061da546Spatrick if (module_spec.GetPlatformFileSpec())
212061da546Spatrick m_platform_file = module_spec.GetPlatformFileSpec();
213061da546Spatrick else if (matching_module_spec.GetPlatformFileSpec())
214061da546Spatrick m_platform_file = matching_module_spec.GetPlatformFileSpec();
215061da546Spatrick
216061da546Spatrick // Copy the symbol file spec over
217061da546Spatrick if (module_spec.GetSymbolFileSpec())
218061da546Spatrick m_symfile_spec = module_spec.GetSymbolFileSpec();
219061da546Spatrick else if (matching_module_spec.GetSymbolFileSpec())
220061da546Spatrick m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
221061da546Spatrick
222061da546Spatrick // Copy the object name over
223061da546Spatrick if (matching_module_spec.GetObjectName())
224061da546Spatrick m_object_name = matching_module_spec.GetObjectName();
225061da546Spatrick else
226061da546Spatrick m_object_name = module_spec.GetObjectName();
227061da546Spatrick
228061da546Spatrick // Always trust the object offset (file offset) and object modification time
229061da546Spatrick // (for mod time in a BSD static archive) of from the matching module
230061da546Spatrick // specification
231061da546Spatrick m_object_offset = matching_module_spec.GetObjectOffset();
232061da546Spatrick m_object_mod_time = matching_module_spec.GetObjectModificationTime();
233061da546Spatrick }
234061da546Spatrick
Module(const FileSpec & file_spec,const ArchSpec & arch,const ConstString * object_name,lldb::offset_t object_offset,const llvm::sys::TimePoint<> & object_mod_time)235061da546Spatrick Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
236061da546Spatrick const ConstString *object_name, lldb::offset_t object_offset,
237061da546Spatrick const llvm::sys::TimePoint<> &object_mod_time)
238*f6aab3d8Srobert : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
239*f6aab3d8Srobert m_arch(arch), m_file(file_spec), m_object_offset(object_offset),
240061da546Spatrick m_object_mod_time(object_mod_time), m_file_has_changed(false),
241061da546Spatrick m_first_file_changed_log(false) {
242061da546Spatrick // Scope for locker below...
243061da546Spatrick {
244061da546Spatrick std::lock_guard<std::recursive_mutex> guard(
245061da546Spatrick GetAllocationModuleCollectionMutex());
246061da546Spatrick GetModuleCollection().push_back(this);
247061da546Spatrick }
248061da546Spatrick
249061da546Spatrick if (object_name)
250061da546Spatrick m_object_name = *object_name;
251061da546Spatrick
252*f6aab3d8Srobert Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
253061da546Spatrick if (log != nullptr)
254061da546Spatrick LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
255061da546Spatrick static_cast<void *>(this), m_arch.GetArchitectureName(),
256061da546Spatrick m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
257*f6aab3d8Srobert m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
258061da546Spatrick }
259061da546Spatrick
Module()260be691f3bSpatrick Module::Module() : m_file_has_changed(false), m_first_file_changed_log(false) {
261061da546Spatrick std::lock_guard<std::recursive_mutex> guard(
262061da546Spatrick GetAllocationModuleCollectionMutex());
263061da546Spatrick GetModuleCollection().push_back(this);
264061da546Spatrick }
265061da546Spatrick
~Module()266061da546Spatrick Module::~Module() {
267061da546Spatrick // Lock our module down while we tear everything down to make sure we don't
268061da546Spatrick // get any access to the module while it is being destroyed
269061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
270061da546Spatrick // Scope for locker below...
271061da546Spatrick {
272061da546Spatrick std::lock_guard<std::recursive_mutex> guard(
273061da546Spatrick GetAllocationModuleCollectionMutex());
274061da546Spatrick ModuleCollection &modules = GetModuleCollection();
275061da546Spatrick ModuleCollection::iterator end = modules.end();
276061da546Spatrick ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
277061da546Spatrick assert(pos != end);
278061da546Spatrick modules.erase(pos);
279061da546Spatrick }
280*f6aab3d8Srobert Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
281061da546Spatrick if (log != nullptr)
282061da546Spatrick LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",
283061da546Spatrick static_cast<void *>(this), m_arch.GetArchitectureName(),
284061da546Spatrick m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
285*f6aab3d8Srobert m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
286061da546Spatrick // Release any auto pointers before we start tearing down our member
287061da546Spatrick // variables since the object file and symbol files might need to make
288061da546Spatrick // function calls back into this module object. The ordering is important
289061da546Spatrick // here because symbol files can require the module object file. So we tear
290061da546Spatrick // down the symbol file first, then the object file.
291061da546Spatrick m_sections_up.reset();
292061da546Spatrick m_symfile_up.reset();
293061da546Spatrick m_objfile_sp.reset();
294061da546Spatrick }
295061da546Spatrick
GetMemoryObjectFile(const lldb::ProcessSP & process_sp,lldb::addr_t header_addr,Status & error,size_t size_to_read)296061da546Spatrick ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
297061da546Spatrick lldb::addr_t header_addr, Status &error,
298061da546Spatrick size_t size_to_read) {
299061da546Spatrick if (m_objfile_sp) {
300061da546Spatrick error.SetErrorString("object file already exists");
301061da546Spatrick } else {
302061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
303061da546Spatrick if (process_sp) {
304061da546Spatrick m_did_load_objfile = true;
305*f6aab3d8Srobert std::shared_ptr<DataBufferHeap> data_sp =
306*f6aab3d8Srobert std::make_shared<DataBufferHeap>(size_to_read, 0);
307061da546Spatrick Status readmem_error;
308061da546Spatrick const size_t bytes_read =
309*f6aab3d8Srobert process_sp->ReadMemory(header_addr, data_sp->GetBytes(),
310*f6aab3d8Srobert data_sp->GetByteSize(), readmem_error);
311dda28197Spatrick if (bytes_read < size_to_read)
312*f6aab3d8Srobert data_sp->SetByteSize(bytes_read);
313*f6aab3d8Srobert if (data_sp->GetByteSize() > 0) {
314061da546Spatrick m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,
315061da546Spatrick header_addr, data_sp);
316061da546Spatrick if (m_objfile_sp) {
317061da546Spatrick StreamString s;
318061da546Spatrick s.Printf("0x%16.16" PRIx64, header_addr);
319061da546Spatrick m_object_name.SetString(s.GetString());
320061da546Spatrick
321061da546Spatrick // Once we get the object file, update our module with the object
322061da546Spatrick // file's architecture since it might differ in vendor/os if some
323061da546Spatrick // parts were unknown.
324061da546Spatrick m_arch = m_objfile_sp->GetArchitecture();
325061da546Spatrick
326061da546Spatrick // Augment the arch with the target's information in case
327061da546Spatrick // we are unable to extract the os/environment from memory.
328061da546Spatrick m_arch.MergeFrom(process_sp->GetTarget().GetArchitecture());
329061da546Spatrick } else {
330061da546Spatrick error.SetErrorString("unable to find suitable object file plug-in");
331061da546Spatrick }
332061da546Spatrick } else {
333061da546Spatrick error.SetErrorStringWithFormat("unable to read header from memory: %s",
334061da546Spatrick readmem_error.AsCString());
335061da546Spatrick }
336061da546Spatrick } else {
337061da546Spatrick error.SetErrorString("invalid process");
338061da546Spatrick }
339061da546Spatrick }
340061da546Spatrick return m_objfile_sp.get();
341061da546Spatrick }
342061da546Spatrick
GetUUID()343061da546Spatrick const lldb_private::UUID &Module::GetUUID() {
344061da546Spatrick if (!m_did_set_uuid.load()) {
345061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
346061da546Spatrick if (!m_did_set_uuid.load()) {
347061da546Spatrick ObjectFile *obj_file = GetObjectFile();
348061da546Spatrick
349061da546Spatrick if (obj_file != nullptr) {
350061da546Spatrick m_uuid = obj_file->GetUUID();
351061da546Spatrick m_did_set_uuid = true;
352061da546Spatrick }
353061da546Spatrick }
354061da546Spatrick }
355061da546Spatrick return m_uuid;
356061da546Spatrick }
357061da546Spatrick
SetUUID(const lldb_private::UUID & uuid)358061da546Spatrick void Module::SetUUID(const lldb_private::UUID &uuid) {
359061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
360061da546Spatrick if (!m_did_set_uuid) {
361061da546Spatrick m_uuid = uuid;
362061da546Spatrick m_did_set_uuid = true;
363061da546Spatrick } else {
364061da546Spatrick lldbassert(0 && "Attempting to overwrite the existing module UUID");
365061da546Spatrick }
366061da546Spatrick }
367061da546Spatrick
368*f6aab3d8Srobert llvm::Expected<TypeSystemSP>
GetTypeSystemForLanguage(LanguageType language)369061da546Spatrick Module::GetTypeSystemForLanguage(LanguageType language) {
370061da546Spatrick return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
371061da546Spatrick }
372061da546Spatrick
ForEachTypeSystem(llvm::function_ref<bool (lldb::TypeSystemSP)> callback)373*f6aab3d8Srobert void Module::ForEachTypeSystem(
374*f6aab3d8Srobert llvm::function_ref<bool(lldb::TypeSystemSP)> callback) {
375*f6aab3d8Srobert m_type_system_map.ForEach(callback);
376*f6aab3d8Srobert }
377*f6aab3d8Srobert
ParseAllDebugSymbols()378061da546Spatrick void Module::ParseAllDebugSymbols() {
379061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
380061da546Spatrick size_t num_comp_units = GetNumCompileUnits();
381061da546Spatrick if (num_comp_units == 0)
382061da546Spatrick return;
383061da546Spatrick
384061da546Spatrick SymbolFile *symbols = GetSymbolFile();
385061da546Spatrick
386061da546Spatrick for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {
387dda28197Spatrick SymbolContext sc;
388dda28197Spatrick sc.module_sp = shared_from_this();
389061da546Spatrick sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
390061da546Spatrick if (!sc.comp_unit)
391061da546Spatrick continue;
392061da546Spatrick
393061da546Spatrick symbols->ParseVariablesForContext(sc);
394061da546Spatrick
395061da546Spatrick symbols->ParseFunctions(*sc.comp_unit);
396061da546Spatrick
397061da546Spatrick sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {
398061da546Spatrick symbols->ParseBlocksRecursive(*f);
399061da546Spatrick
400061da546Spatrick // Parse the variables for this function and all its blocks
401061da546Spatrick sc.function = f.get();
402061da546Spatrick symbols->ParseVariablesForContext(sc);
403061da546Spatrick return false;
404061da546Spatrick });
405061da546Spatrick
406061da546Spatrick // Parse all types for this compile unit
407061da546Spatrick symbols->ParseTypes(*sc.comp_unit);
408061da546Spatrick }
409061da546Spatrick }
410061da546Spatrick
CalculateSymbolContext(SymbolContext * sc)411061da546Spatrick void Module::CalculateSymbolContext(SymbolContext *sc) {
412061da546Spatrick sc->module_sp = shared_from_this();
413061da546Spatrick }
414061da546Spatrick
CalculateSymbolContextModule()415061da546Spatrick ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }
416061da546Spatrick
DumpSymbolContext(Stream * s)417061da546Spatrick void Module::DumpSymbolContext(Stream *s) {
418061da546Spatrick s->Printf(", Module{%p}", static_cast<void *>(this));
419061da546Spatrick }
420061da546Spatrick
GetNumCompileUnits()421061da546Spatrick size_t Module::GetNumCompileUnits() {
422061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
423061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
424061da546Spatrick return symbols->GetNumCompileUnits();
425061da546Spatrick return 0;
426061da546Spatrick }
427061da546Spatrick
GetCompileUnitAtIndex(size_t index)428061da546Spatrick CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
429061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
430061da546Spatrick size_t num_comp_units = GetNumCompileUnits();
431061da546Spatrick CompUnitSP cu_sp;
432061da546Spatrick
433061da546Spatrick if (index < num_comp_units) {
434061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
435061da546Spatrick cu_sp = symbols->GetCompileUnitAtIndex(index);
436061da546Spatrick }
437061da546Spatrick return cu_sp;
438061da546Spatrick }
439061da546Spatrick
ResolveFileAddress(lldb::addr_t vm_addr,Address & so_addr)440061da546Spatrick bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
441061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
442061da546Spatrick SectionList *section_list = GetSectionList();
443061da546Spatrick if (section_list)
444061da546Spatrick return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
445061da546Spatrick return false;
446061da546Spatrick }
447061da546Spatrick
ResolveSymbolContextForAddress(const Address & so_addr,lldb::SymbolContextItem resolve_scope,SymbolContext & sc,bool resolve_tail_call_address)448061da546Spatrick uint32_t Module::ResolveSymbolContextForAddress(
449061da546Spatrick const Address &so_addr, lldb::SymbolContextItem resolve_scope,
450061da546Spatrick SymbolContext &sc, bool resolve_tail_call_address) {
451061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
452061da546Spatrick uint32_t resolved_flags = 0;
453061da546Spatrick
454061da546Spatrick // Clear the result symbol context in case we don't find anything, but don't
455061da546Spatrick // clear the target
456061da546Spatrick sc.Clear(false);
457061da546Spatrick
458061da546Spatrick // Get the section from the section/offset address.
459061da546Spatrick SectionSP section_sp(so_addr.GetSection());
460061da546Spatrick
461061da546Spatrick // Make sure the section matches this module before we try and match anything
462061da546Spatrick if (section_sp && section_sp->GetModule().get() == this) {
463061da546Spatrick // If the section offset based address resolved itself, then this is the
464061da546Spatrick // right module.
465061da546Spatrick sc.module_sp = shared_from_this();
466061da546Spatrick resolved_flags |= eSymbolContextModule;
467061da546Spatrick
468061da546Spatrick SymbolFile *symfile = GetSymbolFile();
469061da546Spatrick if (!symfile)
470061da546Spatrick return resolved_flags;
471061da546Spatrick
472061da546Spatrick // Resolve the compile unit, function, block, line table or line entry if
473061da546Spatrick // requested.
474061da546Spatrick if (resolve_scope & eSymbolContextCompUnit ||
475061da546Spatrick resolve_scope & eSymbolContextFunction ||
476061da546Spatrick resolve_scope & eSymbolContextBlock ||
477061da546Spatrick resolve_scope & eSymbolContextLineEntry ||
478061da546Spatrick resolve_scope & eSymbolContextVariable) {
479*f6aab3d8Srobert symfile->SetLoadDebugInfoEnabled();
480061da546Spatrick resolved_flags |=
481061da546Spatrick symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);
482061da546Spatrick }
483061da546Spatrick
484061da546Spatrick // Resolve the symbol if requested, but don't re-look it up if we've
485061da546Spatrick // already found it.
486061da546Spatrick if (resolve_scope & eSymbolContextSymbol &&
487061da546Spatrick !(resolved_flags & eSymbolContextSymbol)) {
488061da546Spatrick Symtab *symtab = symfile->GetSymtab();
489061da546Spatrick if (symtab && so_addr.IsSectionOffset()) {
490061da546Spatrick Symbol *matching_symbol = nullptr;
491061da546Spatrick
492061da546Spatrick symtab->ForEachSymbolContainingFileAddress(
493061da546Spatrick so_addr.GetFileAddress(),
494061da546Spatrick [&matching_symbol](Symbol *symbol) -> bool {
495061da546Spatrick if (symbol->GetType() != eSymbolTypeInvalid) {
496061da546Spatrick matching_symbol = symbol;
497061da546Spatrick return false; // Stop iterating
498061da546Spatrick }
499061da546Spatrick return true; // Keep iterating
500061da546Spatrick });
501061da546Spatrick sc.symbol = matching_symbol;
502061da546Spatrick if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
503061da546Spatrick !(resolved_flags & eSymbolContextFunction)) {
504061da546Spatrick bool verify_unique = false; // No need to check again since
505061da546Spatrick // ResolveSymbolContext failed to find a
506061da546Spatrick // symbol at this address.
507061da546Spatrick if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
508061da546Spatrick sc.symbol =
509061da546Spatrick obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
510061da546Spatrick }
511061da546Spatrick
512061da546Spatrick if (sc.symbol) {
513061da546Spatrick if (sc.symbol->IsSynthetic()) {
514061da546Spatrick // We have a synthetic symbol so lets check if the object file from
515061da546Spatrick // the symbol file in the symbol vendor is different than the
516061da546Spatrick // object file for the module, and if so search its symbol table to
517061da546Spatrick // see if we can come up with a better symbol. For example dSYM
518061da546Spatrick // files on MacOSX have an unstripped symbol table inside of them.
519061da546Spatrick ObjectFile *symtab_objfile = symtab->GetObjectFile();
520061da546Spatrick if (symtab_objfile && symtab_objfile->IsStripped()) {
521061da546Spatrick ObjectFile *symfile_objfile = symfile->GetObjectFile();
522061da546Spatrick if (symfile_objfile != symtab_objfile) {
523061da546Spatrick Symtab *symfile_symtab = symfile_objfile->GetSymtab();
524061da546Spatrick if (symfile_symtab) {
525061da546Spatrick Symbol *symbol =
526061da546Spatrick symfile_symtab->FindSymbolContainingFileAddress(
527061da546Spatrick so_addr.GetFileAddress());
528061da546Spatrick if (symbol && !symbol->IsSynthetic()) {
529061da546Spatrick sc.symbol = symbol;
530061da546Spatrick }
531061da546Spatrick }
532061da546Spatrick }
533061da546Spatrick }
534061da546Spatrick }
535061da546Spatrick resolved_flags |= eSymbolContextSymbol;
536061da546Spatrick }
537061da546Spatrick }
538061da546Spatrick }
539061da546Spatrick
540061da546Spatrick // For function symbols, so_addr may be off by one. This is a convention
541061da546Spatrick // consistent with FDE row indices in eh_frame sections, but requires extra
542061da546Spatrick // logic here to permit symbol lookup for disassembly and unwind.
543061da546Spatrick if (resolve_scope & eSymbolContextSymbol &&
544061da546Spatrick !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
545061da546Spatrick so_addr.IsSectionOffset()) {
546061da546Spatrick Address previous_addr = so_addr;
547061da546Spatrick previous_addr.Slide(-1);
548061da546Spatrick
549061da546Spatrick bool do_resolve_tail_call_address = false; // prevent recursion
550061da546Spatrick const uint32_t flags = ResolveSymbolContextForAddress(
551061da546Spatrick previous_addr, resolve_scope, sc, do_resolve_tail_call_address);
552061da546Spatrick if (flags & eSymbolContextSymbol) {
553061da546Spatrick AddressRange addr_range;
554061da546Spatrick if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
555061da546Spatrick false, addr_range)) {
556061da546Spatrick if (addr_range.GetBaseAddress().GetSection() ==
557061da546Spatrick so_addr.GetSection()) {
558061da546Spatrick // If the requested address is one past the address range of a
559061da546Spatrick // function (i.e. a tail call), or the decremented address is the
560061da546Spatrick // start of a function (i.e. some forms of trampoline), indicate
561061da546Spatrick // that the symbol has been resolved.
562061da546Spatrick if (so_addr.GetOffset() ==
563061da546Spatrick addr_range.GetBaseAddress().GetOffset() ||
564*f6aab3d8Srobert so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() +
565061da546Spatrick addr_range.GetByteSize()) {
566061da546Spatrick resolved_flags |= flags;
567061da546Spatrick }
568061da546Spatrick } else {
569061da546Spatrick sc.symbol =
570061da546Spatrick nullptr; // Don't trust the symbol if the sections didn't match.
571061da546Spatrick }
572061da546Spatrick }
573061da546Spatrick }
574061da546Spatrick }
575061da546Spatrick }
576061da546Spatrick return resolved_flags;
577061da546Spatrick }
578061da546Spatrick
ResolveSymbolContextForFilePath(const char * file_path,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)579061da546Spatrick uint32_t Module::ResolveSymbolContextForFilePath(
580061da546Spatrick const char *file_path, uint32_t line, bool check_inlines,
581061da546Spatrick lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
582061da546Spatrick FileSpec file_spec(file_path);
583061da546Spatrick return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
584061da546Spatrick resolve_scope, sc_list);
585061da546Spatrick }
586061da546Spatrick
ResolveSymbolContextsForFileSpec(const FileSpec & file_spec,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)587061da546Spatrick uint32_t Module::ResolveSymbolContextsForFileSpec(
588061da546Spatrick const FileSpec &file_spec, uint32_t line, bool check_inlines,
589061da546Spatrick lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
590061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
591be691f3bSpatrick LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "
592061da546Spatrick "check_inlines = %s, resolve_scope = 0x%8.8x)",
593061da546Spatrick file_spec.GetPath().c_str(), line,
594061da546Spatrick check_inlines ? "yes" : "no", resolve_scope);
595061da546Spatrick
596061da546Spatrick const uint32_t initial_count = sc_list.GetSize();
597061da546Spatrick
598be691f3bSpatrick if (SymbolFile *symbols = GetSymbolFile()) {
599be691f3bSpatrick // TODO: Handle SourceLocationSpec column information
600*f6aab3d8Srobert SourceLocationSpec location_spec(file_spec, line, /*column=*/std::nullopt,
601be691f3bSpatrick check_inlines, /*exact_match=*/false);
602be691f3bSpatrick
603be691f3bSpatrick symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list);
604be691f3bSpatrick }
605061da546Spatrick
606061da546Spatrick return sc_list.GetSize() - initial_count;
607061da546Spatrick }
608061da546Spatrick
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,VariableList & variables)609061da546Spatrick void Module::FindGlobalVariables(ConstString name,
610dda28197Spatrick const CompilerDeclContext &parent_decl_ctx,
611061da546Spatrick size_t max_matches, VariableList &variables) {
612061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
613061da546Spatrick symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);
614061da546Spatrick }
615061da546Spatrick
FindGlobalVariables(const RegularExpression & regex,size_t max_matches,VariableList & variables)616061da546Spatrick void Module::FindGlobalVariables(const RegularExpression ®ex,
617061da546Spatrick size_t max_matches, VariableList &variables) {
618061da546Spatrick SymbolFile *symbols = GetSymbolFile();
619061da546Spatrick if (symbols)
620061da546Spatrick symbols->FindGlobalVariables(regex, max_matches, variables);
621061da546Spatrick }
622061da546Spatrick
FindCompileUnits(const FileSpec & path,SymbolContextList & sc_list)623061da546Spatrick void Module::FindCompileUnits(const FileSpec &path,
624061da546Spatrick SymbolContextList &sc_list) {
625061da546Spatrick const size_t num_compile_units = GetNumCompileUnits();
626061da546Spatrick SymbolContext sc;
627061da546Spatrick sc.module_sp = shared_from_this();
628061da546Spatrick for (size_t i = 0; i < num_compile_units; ++i) {
629061da546Spatrick sc.comp_unit = GetCompileUnitAtIndex(i).get();
630061da546Spatrick if (sc.comp_unit) {
631061da546Spatrick if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))
632061da546Spatrick sc_list.Append(sc);
633061da546Spatrick }
634061da546Spatrick }
635061da546Spatrick }
636061da546Spatrick
LookupInfo(ConstString name,FunctionNameType name_type_mask,LanguageType language)637061da546Spatrick Module::LookupInfo::LookupInfo(ConstString name,
638061da546Spatrick FunctionNameType name_type_mask,
639061da546Spatrick LanguageType language)
640*f6aab3d8Srobert : m_name(name), m_lookup_name(), m_language(language) {
641061da546Spatrick const char *name_cstr = name.GetCString();
642061da546Spatrick llvm::StringRef basename;
643061da546Spatrick llvm::StringRef context;
644061da546Spatrick
645061da546Spatrick if (name_type_mask & eFunctionNameTypeAuto) {
646061da546Spatrick if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
647061da546Spatrick m_name_type_mask = eFunctionNameTypeFull;
648061da546Spatrick else if ((language == eLanguageTypeUnknown ||
649061da546Spatrick Language::LanguageIsObjC(language)) &&
650061da546Spatrick ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
651061da546Spatrick m_name_type_mask = eFunctionNameTypeFull;
652061da546Spatrick else if (Language::LanguageIsC(language)) {
653061da546Spatrick m_name_type_mask = eFunctionNameTypeFull;
654061da546Spatrick } else {
655061da546Spatrick if ((language == eLanguageTypeUnknown ||
656061da546Spatrick Language::LanguageIsObjC(language)) &&
657061da546Spatrick ObjCLanguage::IsPossibleObjCSelector(name_cstr))
658061da546Spatrick m_name_type_mask |= eFunctionNameTypeSelector;
659061da546Spatrick
660061da546Spatrick CPlusPlusLanguage::MethodName cpp_method(name);
661061da546Spatrick basename = cpp_method.GetBasename();
662061da546Spatrick if (basename.empty()) {
663061da546Spatrick if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
664061da546Spatrick basename))
665061da546Spatrick m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
666061da546Spatrick else
667061da546Spatrick m_name_type_mask |= eFunctionNameTypeFull;
668061da546Spatrick } else {
669061da546Spatrick m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
670061da546Spatrick }
671061da546Spatrick }
672061da546Spatrick } else {
673061da546Spatrick m_name_type_mask = name_type_mask;
674061da546Spatrick if (name_type_mask & eFunctionNameTypeMethod ||
675061da546Spatrick name_type_mask & eFunctionNameTypeBase) {
676061da546Spatrick // If they've asked for a CPP method or function name and it can't be
677061da546Spatrick // that, we don't even need to search for CPP methods or names.
678061da546Spatrick CPlusPlusLanguage::MethodName cpp_method(name);
679061da546Spatrick if (cpp_method.IsValid()) {
680061da546Spatrick basename = cpp_method.GetBasename();
681061da546Spatrick
682061da546Spatrick if (!cpp_method.GetQualifiers().empty()) {
683061da546Spatrick // There is a "const" or other qualifier following the end of the
684061da546Spatrick // function parens, this can't be a eFunctionNameTypeBase
685061da546Spatrick m_name_type_mask &= ~(eFunctionNameTypeBase);
686061da546Spatrick if (m_name_type_mask == eFunctionNameTypeNone)
687061da546Spatrick return;
688061da546Spatrick }
689061da546Spatrick } else {
690061da546Spatrick // If the CPP method parser didn't manage to chop this up, try to fill
691061da546Spatrick // in the base name if we can. If a::b::c is passed in, we need to just
692061da546Spatrick // look up "c", and then we'll filter the result later.
693061da546Spatrick CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
694061da546Spatrick basename);
695061da546Spatrick }
696061da546Spatrick }
697061da546Spatrick
698061da546Spatrick if (name_type_mask & eFunctionNameTypeSelector) {
699061da546Spatrick if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
700061da546Spatrick m_name_type_mask &= ~(eFunctionNameTypeSelector);
701061da546Spatrick if (m_name_type_mask == eFunctionNameTypeNone)
702061da546Spatrick return;
703061da546Spatrick }
704061da546Spatrick }
705061da546Spatrick
706061da546Spatrick // Still try and get a basename in case someone specifies a name type mask
707061da546Spatrick // of eFunctionNameTypeFull and a name like "A::func"
708061da546Spatrick if (basename.empty()) {
709061da546Spatrick if (name_type_mask & eFunctionNameTypeFull &&
710061da546Spatrick !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
711061da546Spatrick CPlusPlusLanguage::MethodName cpp_method(name);
712061da546Spatrick basename = cpp_method.GetBasename();
713061da546Spatrick if (basename.empty())
714061da546Spatrick CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
715061da546Spatrick basename);
716061da546Spatrick }
717061da546Spatrick }
718061da546Spatrick }
719061da546Spatrick
720061da546Spatrick if (!basename.empty()) {
721061da546Spatrick // The name supplied was a partial C++ path like "a::count". In this case
722061da546Spatrick // we want to do a lookup on the basename "count" and then make sure any
723061da546Spatrick // matching results contain "a::count" so that it would match "b::a::count"
724061da546Spatrick // and "a::count". This is why we set "match_name_after_lookup" to true
725061da546Spatrick m_lookup_name.SetString(basename);
726061da546Spatrick m_match_name_after_lookup = true;
727061da546Spatrick } else {
728061da546Spatrick // The name is already correct, just use the exact name as supplied, and we
729061da546Spatrick // won't need to check if any matches contain "name"
730061da546Spatrick m_lookup_name = name;
731061da546Spatrick m_match_name_after_lookup = false;
732061da546Spatrick }
733061da546Spatrick }
734061da546Spatrick
NameMatchesLookupInfo(ConstString function_name,LanguageType language_type) const735*f6aab3d8Srobert bool Module::LookupInfo::NameMatchesLookupInfo(
736*f6aab3d8Srobert ConstString function_name, LanguageType language_type) const {
737*f6aab3d8Srobert // We always keep unnamed symbols
738*f6aab3d8Srobert if (!function_name)
739*f6aab3d8Srobert return true;
740*f6aab3d8Srobert
741*f6aab3d8Srobert // If we match exactly, we can return early
742*f6aab3d8Srobert if (m_name == function_name)
743*f6aab3d8Srobert return true;
744*f6aab3d8Srobert
745*f6aab3d8Srobert // If function_name is mangled, we'll need to demangle it.
746*f6aab3d8Srobert // In the pathologial case where the function name "looks" mangled but is
747*f6aab3d8Srobert // actually demangled (e.g. a method named _Zonk), this operation should be
748*f6aab3d8Srobert // relatively inexpensive since no demangling is actually occuring. See
749*f6aab3d8Srobert // Mangled::SetValue for more context.
750*f6aab3d8Srobert const bool function_name_may_be_mangled =
751*f6aab3d8Srobert Mangled::GetManglingScheme(function_name.GetStringRef()) !=
752*f6aab3d8Srobert Mangled::eManglingSchemeNone;
753*f6aab3d8Srobert ConstString demangled_function_name = function_name;
754*f6aab3d8Srobert if (function_name_may_be_mangled) {
755*f6aab3d8Srobert Mangled mangled_function_name(function_name);
756*f6aab3d8Srobert demangled_function_name = mangled_function_name.GetDemangledName();
757*f6aab3d8Srobert }
758*f6aab3d8Srobert
759*f6aab3d8Srobert // If the symbol has a language, then let the language make the match.
760*f6aab3d8Srobert // Otherwise just check that the demangled function name contains the
761*f6aab3d8Srobert // demangled user-provided name.
762*f6aab3d8Srobert if (Language *language = Language::FindPlugin(language_type))
763*f6aab3d8Srobert return language->DemangledNameContainsPath(m_name.GetStringRef(),
764*f6aab3d8Srobert demangled_function_name);
765*f6aab3d8Srobert
766*f6aab3d8Srobert llvm::StringRef function_name_ref = demangled_function_name.GetStringRef();
767*f6aab3d8Srobert return function_name_ref.contains(m_name.GetStringRef());
768*f6aab3d8Srobert }
769*f6aab3d8Srobert
Prune(SymbolContextList & sc_list,size_t start_idx) const770061da546Spatrick void Module::LookupInfo::Prune(SymbolContextList &sc_list,
771061da546Spatrick size_t start_idx) const {
772061da546Spatrick if (m_match_name_after_lookup && m_name) {
773061da546Spatrick SymbolContext sc;
774061da546Spatrick size_t i = start_idx;
775061da546Spatrick while (i < sc_list.GetSize()) {
776061da546Spatrick if (!sc_list.GetContextAtIndex(i, sc))
777061da546Spatrick break;
778*f6aab3d8Srobert
779*f6aab3d8Srobert bool keep_it =
780*f6aab3d8Srobert NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage());
781*f6aab3d8Srobert if (keep_it)
782061da546Spatrick ++i;
783*f6aab3d8Srobert else
784*f6aab3d8Srobert sc_list.RemoveContextAtIndex(i);
785061da546Spatrick }
786061da546Spatrick }
787061da546Spatrick
788061da546Spatrick // If we have only full name matches we might have tried to set breakpoint on
789061da546Spatrick // "func" and specified eFunctionNameTypeFull, but we might have found
790061da546Spatrick // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
791061da546Spatrick // "func()" and "func" should end up matching.
792061da546Spatrick if (m_name_type_mask == eFunctionNameTypeFull) {
793061da546Spatrick SymbolContext sc;
794061da546Spatrick size_t i = start_idx;
795061da546Spatrick while (i < sc_list.GetSize()) {
796061da546Spatrick if (!sc_list.GetContextAtIndex(i, sc))
797061da546Spatrick break;
798061da546Spatrick // Make sure the mangled and demangled names don't match before we try to
799061da546Spatrick // pull anything out
800061da546Spatrick ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
801061da546Spatrick ConstString full_name(sc.GetFunctionName());
802*f6aab3d8Srobert if (mangled_name != m_name && full_name != m_name) {
803061da546Spatrick CPlusPlusLanguage::MethodName cpp_method(full_name);
804061da546Spatrick if (cpp_method.IsValid()) {
805061da546Spatrick if (cpp_method.GetContext().empty()) {
806061da546Spatrick if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
807061da546Spatrick sc_list.RemoveContextAtIndex(i);
808061da546Spatrick continue;
809061da546Spatrick }
810061da546Spatrick } else {
811061da546Spatrick std::string qualified_name;
812061da546Spatrick llvm::StringRef anon_prefix("(anonymous namespace)");
813061da546Spatrick if (cpp_method.GetContext() == anon_prefix)
814061da546Spatrick qualified_name = cpp_method.GetBasename().str();
815061da546Spatrick else
816061da546Spatrick qualified_name = cpp_method.GetScopeQualifiedName();
817061da546Spatrick if (qualified_name != m_name.GetCString()) {
818061da546Spatrick sc_list.RemoveContextAtIndex(i);
819061da546Spatrick continue;
820061da546Spatrick }
821061da546Spatrick }
822061da546Spatrick }
823061da546Spatrick }
824061da546Spatrick ++i;
825061da546Spatrick }
826061da546Spatrick }
827061da546Spatrick }
828061da546Spatrick
FindFunctions(const Module::LookupInfo & lookup_info,const CompilerDeclContext & parent_decl_ctx,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)829*f6aab3d8Srobert void Module::FindFunctions(const Module::LookupInfo &lookup_info,
830dda28197Spatrick const CompilerDeclContext &parent_decl_ctx,
831*f6aab3d8Srobert const ModuleFunctionSearchOptions &options,
832061da546Spatrick SymbolContextList &sc_list) {
833061da546Spatrick // Find all the functions (not symbols, but debug information functions...
834*f6aab3d8Srobert if (SymbolFile *symbols = GetSymbolFile()) {
835*f6aab3d8Srobert symbols->FindFunctions(lookup_info, parent_decl_ctx,
836*f6aab3d8Srobert options.include_inlines, sc_list);
837061da546Spatrick // Now check our symbol table for symbols that are code symbols if
838061da546Spatrick // requested
839*f6aab3d8Srobert if (options.include_symbols) {
840*f6aab3d8Srobert if (Symtab *symtab = symbols->GetSymtab()) {
841061da546Spatrick symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
842061da546Spatrick lookup_info.GetNameTypeMask(), sc_list);
843061da546Spatrick }
844061da546Spatrick }
845*f6aab3d8Srobert }
846*f6aab3d8Srobert }
847061da546Spatrick
FindFunctions(ConstString name,const CompilerDeclContext & parent_decl_ctx,FunctionNameType name_type_mask,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)848*f6aab3d8Srobert void Module::FindFunctions(ConstString name,
849*f6aab3d8Srobert const CompilerDeclContext &parent_decl_ctx,
850*f6aab3d8Srobert FunctionNameType name_type_mask,
851*f6aab3d8Srobert const ModuleFunctionSearchOptions &options,
852*f6aab3d8Srobert SymbolContextList &sc_list) {
853*f6aab3d8Srobert const size_t old_size = sc_list.GetSize();
854*f6aab3d8Srobert LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
855*f6aab3d8Srobert FindFunctions(lookup_info, parent_decl_ctx, options, sc_list);
856*f6aab3d8Srobert if (name_type_mask & eFunctionNameTypeAuto) {
857061da546Spatrick const size_t new_size = sc_list.GetSize();
858061da546Spatrick if (old_size < new_size)
859061da546Spatrick lookup_info.Prune(sc_list, old_size);
860061da546Spatrick }
861061da546Spatrick }
862061da546Spatrick
FindFunctions(const RegularExpression & regex,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)863*f6aab3d8Srobert void Module::FindFunctions(const RegularExpression ®ex,
864*f6aab3d8Srobert const ModuleFunctionSearchOptions &options,
865061da546Spatrick SymbolContextList &sc_list) {
866061da546Spatrick const size_t start_size = sc_list.GetSize();
867061da546Spatrick
868061da546Spatrick if (SymbolFile *symbols = GetSymbolFile()) {
869*f6aab3d8Srobert symbols->FindFunctions(regex, options.include_inlines, sc_list);
870061da546Spatrick
871061da546Spatrick // Now check our symbol table for symbols that are code symbols if
872061da546Spatrick // requested
873*f6aab3d8Srobert if (options.include_symbols) {
874061da546Spatrick Symtab *symtab = symbols->GetSymtab();
875061da546Spatrick if (symtab) {
876061da546Spatrick std::vector<uint32_t> symbol_indexes;
877061da546Spatrick symtab->AppendSymbolIndexesMatchingRegExAndType(
878061da546Spatrick regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
879061da546Spatrick symbol_indexes);
880061da546Spatrick const size_t num_matches = symbol_indexes.size();
881061da546Spatrick if (num_matches) {
882061da546Spatrick SymbolContext sc(this);
883061da546Spatrick const size_t end_functions_added_index = sc_list.GetSize();
884061da546Spatrick size_t num_functions_added_to_sc_list =
885061da546Spatrick end_functions_added_index - start_size;
886061da546Spatrick if (num_functions_added_to_sc_list == 0) {
887061da546Spatrick // No functions were added, just symbols, so we can just append
888061da546Spatrick // them
889061da546Spatrick for (size_t i = 0; i < num_matches; ++i) {
890061da546Spatrick sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
891061da546Spatrick SymbolType sym_type = sc.symbol->GetType();
892061da546Spatrick if (sc.symbol && (sym_type == eSymbolTypeCode ||
893061da546Spatrick sym_type == eSymbolTypeResolver))
894061da546Spatrick sc_list.Append(sc);
895061da546Spatrick }
896061da546Spatrick } else {
897061da546Spatrick typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
898061da546Spatrick FileAddrToIndexMap file_addr_to_index;
899061da546Spatrick for (size_t i = start_size; i < end_functions_added_index; ++i) {
900061da546Spatrick const SymbolContext &sc = sc_list[i];
901061da546Spatrick if (sc.block)
902061da546Spatrick continue;
903061da546Spatrick file_addr_to_index[sc.function->GetAddressRange()
904061da546Spatrick .GetBaseAddress()
905061da546Spatrick .GetFileAddress()] = i;
906061da546Spatrick }
907061da546Spatrick
908061da546Spatrick FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
909061da546Spatrick // Functions were added so we need to merge symbols into any
910061da546Spatrick // existing function symbol contexts
911061da546Spatrick for (size_t i = start_size; i < num_matches; ++i) {
912061da546Spatrick sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
913061da546Spatrick SymbolType sym_type = sc.symbol->GetType();
914061da546Spatrick if (sc.symbol && sc.symbol->ValueIsAddress() &&
915061da546Spatrick (sym_type == eSymbolTypeCode ||
916061da546Spatrick sym_type == eSymbolTypeResolver)) {
917061da546Spatrick FileAddrToIndexMap::const_iterator pos =
918061da546Spatrick file_addr_to_index.find(
919061da546Spatrick sc.symbol->GetAddressRef().GetFileAddress());
920061da546Spatrick if (pos == end)
921061da546Spatrick sc_list.Append(sc);
922061da546Spatrick else
923061da546Spatrick sc_list[pos->second].symbol = sc.symbol;
924061da546Spatrick }
925061da546Spatrick }
926061da546Spatrick }
927061da546Spatrick }
928061da546Spatrick }
929061da546Spatrick }
930061da546Spatrick }
931061da546Spatrick }
932061da546Spatrick
FindAddressesForLine(const lldb::TargetSP target_sp,const FileSpec & file,uint32_t line,Function * function,std::vector<Address> & output_local,std::vector<Address> & output_extern)933061da546Spatrick void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
934061da546Spatrick const FileSpec &file, uint32_t line,
935061da546Spatrick Function *function,
936061da546Spatrick std::vector<Address> &output_local,
937061da546Spatrick std::vector<Address> &output_extern) {
938061da546Spatrick SearchFilterByModule filter(target_sp, m_file);
939be691f3bSpatrick
940be691f3bSpatrick // TODO: Handle SourceLocationSpec column information
941*f6aab3d8Srobert SourceLocationSpec location_spec(file, line, /*column=*/std::nullopt,
942be691f3bSpatrick /*check_inlines=*/true,
943be691f3bSpatrick /*exact_match=*/false);
944be691f3bSpatrick AddressResolverFileLine resolver(location_spec);
945061da546Spatrick resolver.ResolveAddress(filter);
946061da546Spatrick
947061da546Spatrick for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {
948061da546Spatrick Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
949061da546Spatrick Function *f = addr.CalculateSymbolContextFunction();
950061da546Spatrick if (f && f == function)
951061da546Spatrick output_local.push_back(addr);
952061da546Spatrick else
953061da546Spatrick output_extern.push_back(addr);
954061da546Spatrick }
955061da546Spatrick }
956061da546Spatrick
FindTypes_Impl(ConstString name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)957061da546Spatrick void Module::FindTypes_Impl(
958dda28197Spatrick ConstString name, const CompilerDeclContext &parent_decl_ctx,
959061da546Spatrick size_t max_matches,
960061da546Spatrick llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
961061da546Spatrick TypeMap &types) {
962061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
963061da546Spatrick symbols->FindTypes(name, parent_decl_ctx, max_matches,
964061da546Spatrick searched_symbol_files, types);
965061da546Spatrick }
966061da546Spatrick
FindTypesInNamespace(ConstString type_name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,TypeList & type_list)967061da546Spatrick void Module::FindTypesInNamespace(ConstString type_name,
968dda28197Spatrick const CompilerDeclContext &parent_decl_ctx,
969061da546Spatrick size_t max_matches, TypeList &type_list) {
970061da546Spatrick TypeMap types_map;
971061da546Spatrick llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
972061da546Spatrick FindTypes_Impl(type_name, parent_decl_ctx, max_matches, searched_symbol_files,
973061da546Spatrick types_map);
974061da546Spatrick if (types_map.GetSize()) {
975061da546Spatrick SymbolContext sc;
976061da546Spatrick sc.module_sp = shared_from_this();
977061da546Spatrick sc.SortTypeList(types_map, type_list);
978061da546Spatrick }
979061da546Spatrick }
980061da546Spatrick
FindFirstType(const SymbolContext & sc,ConstString name,bool exact_match)981*f6aab3d8Srobert lldb::TypeSP Module::FindFirstType(const SymbolContext &sc, ConstString name,
982*f6aab3d8Srobert bool exact_match) {
983061da546Spatrick TypeList type_list;
984061da546Spatrick llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
985061da546Spatrick FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
986061da546Spatrick if (type_list.GetSize())
987061da546Spatrick return type_list.GetTypeAtIndex(0);
988061da546Spatrick return TypeSP();
989061da546Spatrick }
990061da546Spatrick
FindTypes(ConstString name,bool exact_match,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeList & types)991061da546Spatrick void Module::FindTypes(
992061da546Spatrick ConstString name, bool exact_match, size_t max_matches,
993061da546Spatrick llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
994061da546Spatrick TypeList &types) {
995061da546Spatrick const char *type_name_cstr = name.GetCString();
996061da546Spatrick llvm::StringRef type_scope;
997061da546Spatrick llvm::StringRef type_basename;
998061da546Spatrick TypeClass type_class = eTypeClassAny;
999061da546Spatrick TypeMap typesmap;
1000061da546Spatrick
1001061da546Spatrick if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename,
1002061da546Spatrick type_class)) {
1003061da546Spatrick // Check if "name" starts with "::" which means the qualified type starts
1004061da546Spatrick // from the root namespace and implies and exact match. The typenames we
1005061da546Spatrick // get back from clang do not start with "::" so we need to strip this off
1006061da546Spatrick // in order to get the qualified names to match
1007061da546Spatrick exact_match = type_scope.consume_front("::");
1008061da546Spatrick
1009061da546Spatrick ConstString type_basename_const_str(type_basename);
1010dda28197Spatrick FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches,
1011061da546Spatrick searched_symbol_files, typesmap);
1012061da546Spatrick if (typesmap.GetSize())
1013*f6aab3d8Srobert typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
1014061da546Spatrick exact_match);
1015061da546Spatrick } else {
1016061da546Spatrick // The type is not in a namespace/class scope, just search for it by
1017061da546Spatrick // basename
1018061da546Spatrick if (type_class != eTypeClassAny && !type_basename.empty()) {
1019061da546Spatrick // The "type_name_cstr" will have been modified if we have a valid type
1020061da546Spatrick // class prefix (like "struct", "class", "union", "typedef" etc).
1021dda28197Spatrick FindTypes_Impl(ConstString(type_basename), CompilerDeclContext(),
1022dda28197Spatrick UINT_MAX, searched_symbol_files, typesmap);
1023*f6aab3d8Srobert typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
1024061da546Spatrick exact_match);
1025061da546Spatrick } else {
1026dda28197Spatrick FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX,
1027dda28197Spatrick searched_symbol_files, typesmap);
1028061da546Spatrick if (exact_match) {
1029*f6aab3d8Srobert typesmap.RemoveMismatchedTypes(type_scope, name.GetStringRef(),
1030dda28197Spatrick type_class, exact_match);
1031061da546Spatrick }
1032061da546Spatrick }
1033061da546Spatrick }
1034061da546Spatrick if (typesmap.GetSize()) {
1035061da546Spatrick SymbolContext sc;
1036061da546Spatrick sc.module_sp = shared_from_this();
1037061da546Spatrick sc.SortTypeList(typesmap, types);
1038061da546Spatrick }
1039061da546Spatrick }
1040061da546Spatrick
FindTypes(llvm::ArrayRef<CompilerContext> pattern,LanguageSet languages,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)1041061da546Spatrick void Module::FindTypes(
1042061da546Spatrick llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1043061da546Spatrick llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1044061da546Spatrick TypeMap &types) {
1045*f6aab3d8Srobert // If a scoped timer is needed, place it in a SymbolFile::FindTypes override.
1046*f6aab3d8Srobert // A timer here is too high volume for some cases, for example when calling
1047*f6aab3d8Srobert // FindTypes on each object file.
1048061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
1049061da546Spatrick symbols->FindTypes(pattern, languages, searched_symbol_files, types);
1050061da546Spatrick }
1051061da546Spatrick
GetSymbolFile(bool can_create,Stream * feedback_strm)1052061da546Spatrick SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
1053061da546Spatrick if (!m_did_load_symfile.load()) {
1054061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
1055061da546Spatrick if (!m_did_load_symfile.load() && can_create) {
1056061da546Spatrick ObjectFile *obj_file = GetObjectFile();
1057061da546Spatrick if (obj_file != nullptr) {
1058be691f3bSpatrick LLDB_SCOPED_TIMER();
1059061da546Spatrick m_symfile_up.reset(
1060061da546Spatrick SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
1061061da546Spatrick m_did_load_symfile = true;
1062061da546Spatrick }
1063061da546Spatrick }
1064061da546Spatrick }
1065061da546Spatrick return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
1066061da546Spatrick }
1067061da546Spatrick
GetSymtab()1068061da546Spatrick Symtab *Module::GetSymtab() {
1069061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
1070061da546Spatrick return symbols->GetSymtab();
1071061da546Spatrick return nullptr;
1072061da546Spatrick }
1073061da546Spatrick
SetFileSpecAndObjectName(const FileSpec & file,ConstString object_name)1074061da546Spatrick void Module::SetFileSpecAndObjectName(const FileSpec &file,
1075061da546Spatrick ConstString object_name) {
1076061da546Spatrick // Container objects whose paths do not specify a file directly can call this
1077061da546Spatrick // function to correct the file and object names.
1078061da546Spatrick m_file = file;
1079061da546Spatrick m_mod_time = FileSystem::Instance().GetModificationTime(file);
1080061da546Spatrick m_object_name = object_name;
1081061da546Spatrick }
1082061da546Spatrick
GetArchitecture() const1083061da546Spatrick const ArchSpec &Module::GetArchitecture() const { return m_arch; }
1084061da546Spatrick
GetSpecificationDescription() const1085061da546Spatrick std::string Module::GetSpecificationDescription() const {
1086061da546Spatrick std::string spec(GetFileSpec().GetPath());
1087061da546Spatrick if (m_object_name) {
1088061da546Spatrick spec += '(';
1089061da546Spatrick spec += m_object_name.GetCString();
1090061da546Spatrick spec += ')';
1091061da546Spatrick }
1092061da546Spatrick return spec;
1093061da546Spatrick }
1094061da546Spatrick
GetDescription(llvm::raw_ostream & s,lldb::DescriptionLevel level)1095061da546Spatrick void Module::GetDescription(llvm::raw_ostream &s,
1096061da546Spatrick lldb::DescriptionLevel level) {
1097061da546Spatrick if (level >= eDescriptionLevelFull) {
1098061da546Spatrick if (m_arch.IsValid())
1099061da546Spatrick s << llvm::formatv("({0}) ", m_arch.GetArchitectureName());
1100061da546Spatrick }
1101061da546Spatrick
1102061da546Spatrick if (level == eDescriptionLevelBrief) {
1103061da546Spatrick const char *filename = m_file.GetFilename().GetCString();
1104061da546Spatrick if (filename)
1105061da546Spatrick s << filename;
1106061da546Spatrick } else {
1107061da546Spatrick char path[PATH_MAX];
1108061da546Spatrick if (m_file.GetPath(path, sizeof(path)))
1109061da546Spatrick s << path;
1110061da546Spatrick }
1111061da546Spatrick
1112061da546Spatrick const char *object_name = m_object_name.GetCString();
1113061da546Spatrick if (object_name)
1114061da546Spatrick s << llvm::formatv("({0})", object_name);
1115061da546Spatrick }
1116061da546Spatrick
FileHasChanged() const1117061da546Spatrick bool Module::FileHasChanged() const {
1118dda28197Spatrick // We have provided the DataBuffer for this module to avoid accessing the
1119dda28197Spatrick // filesystem. We never want to reload those files.
1120dda28197Spatrick if (m_data_sp)
1121dda28197Spatrick return false;
1122061da546Spatrick if (!m_file_has_changed)
1123061da546Spatrick m_file_has_changed =
1124061da546Spatrick (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
1125061da546Spatrick return m_file_has_changed;
1126061da546Spatrick }
1127061da546Spatrick
ReportWarningOptimization(std::optional<lldb::user_id_t> debugger_id)1128*f6aab3d8Srobert void Module::ReportWarningOptimization(
1129*f6aab3d8Srobert std::optional<lldb::user_id_t> debugger_id) {
1130*f6aab3d8Srobert ConstString file_name = GetFileSpec().GetFilename();
1131*f6aab3d8Srobert if (file_name.IsEmpty())
1132*f6aab3d8Srobert return;
1133*f6aab3d8Srobert
1134*f6aab3d8Srobert StreamString ss;
1135*f6aab3d8Srobert ss << file_name.GetStringRef()
1136*f6aab3d8Srobert << " was compiled with optimization - stepping may behave "
1137*f6aab3d8Srobert "oddly; variables may not be available.";
1138*f6aab3d8Srobert Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
1139*f6aab3d8Srobert &m_optimization_warning);
1140*f6aab3d8Srobert }
1141*f6aab3d8Srobert
ReportWarningUnsupportedLanguage(LanguageType language,std::optional<lldb::user_id_t> debugger_id)1142*f6aab3d8Srobert void Module::ReportWarningUnsupportedLanguage(
1143*f6aab3d8Srobert LanguageType language, std::optional<lldb::user_id_t> debugger_id) {
1144*f6aab3d8Srobert StreamString ss;
1145*f6aab3d8Srobert ss << "This version of LLDB has no plugin for the language \""
1146*f6aab3d8Srobert << Language::GetNameForLanguageType(language)
1147*f6aab3d8Srobert << "\". "
1148*f6aab3d8Srobert "Inspection of frame variables will be limited.";
1149*f6aab3d8Srobert Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
1150*f6aab3d8Srobert &m_language_warning);
1151*f6aab3d8Srobert }
1152*f6aab3d8Srobert
ReportErrorIfModifyDetected(const llvm::formatv_object_base & payload)1153*f6aab3d8Srobert void Module::ReportErrorIfModifyDetected(
1154*f6aab3d8Srobert const llvm::formatv_object_base &payload) {
1155061da546Spatrick if (!m_first_file_changed_log) {
1156061da546Spatrick if (FileHasChanged()) {
1157061da546Spatrick m_first_file_changed_log = true;
1158061da546Spatrick StreamString strm;
1159*f6aab3d8Srobert strm.PutCString("the object file ");
1160061da546Spatrick GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
1161061da546Spatrick strm.PutCString(" has been modified\n");
1162*f6aab3d8Srobert strm.PutCString(payload.str());
1163061da546Spatrick strm.PutCString("The debug session should be aborted as the original "
1164*f6aab3d8Srobert "debug information has been overwritten.");
1165*f6aab3d8Srobert Debugger::ReportError(std::string(strm.GetString()));
1166061da546Spatrick }
1167061da546Spatrick }
1168061da546Spatrick }
1169061da546Spatrick
ReportError(const llvm::formatv_object_base & payload)1170*f6aab3d8Srobert void Module::ReportError(const llvm::formatv_object_base &payload) {
1171061da546Spatrick StreamString strm;
1172*f6aab3d8Srobert GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);
1173*f6aab3d8Srobert strm.PutChar(' ');
1174*f6aab3d8Srobert strm.PutCString(payload.str());
1175*f6aab3d8Srobert Debugger::ReportError(strm.GetString().str());
1176*f6aab3d8Srobert }
1177*f6aab3d8Srobert
ReportWarning(const llvm::formatv_object_base & payload)1178*f6aab3d8Srobert void Module::ReportWarning(const llvm::formatv_object_base &payload) {
1179*f6aab3d8Srobert StreamString strm;
1180061da546Spatrick GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
1181061da546Spatrick strm.PutChar(' ');
1182*f6aab3d8Srobert strm.PutCString(payload.str());
1183*f6aab3d8Srobert Debugger::ReportWarning(std::string(strm.GetString()));
1184061da546Spatrick }
1185061da546Spatrick
LogMessage(Log * log,const llvm::formatv_object_base & payload)1186*f6aab3d8Srobert void Module::LogMessage(Log *log, const llvm::formatv_object_base &payload) {
1187061da546Spatrick StreamString log_message;
1188061da546Spatrick GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
1189061da546Spatrick log_message.PutCString(": ");
1190*f6aab3d8Srobert log_message.PutCString(payload.str());
1191061da546Spatrick log->PutCString(log_message.GetData());
1192061da546Spatrick }
1193061da546Spatrick
LogMessageVerboseBacktrace(Log * log,const llvm::formatv_object_base & payload)1194*f6aab3d8Srobert void Module::LogMessageVerboseBacktrace(
1195*f6aab3d8Srobert Log *log, const llvm::formatv_object_base &payload) {
1196061da546Spatrick StreamString log_message;
1197061da546Spatrick GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
1198061da546Spatrick log_message.PutCString(": ");
1199*f6aab3d8Srobert log_message.PutCString(payload.str());
1200061da546Spatrick if (log->GetVerbose()) {
1201061da546Spatrick std::string back_trace;
1202061da546Spatrick llvm::raw_string_ostream stream(back_trace);
1203061da546Spatrick llvm::sys::PrintStackTrace(stream);
1204061da546Spatrick log_message.PutCString(back_trace);
1205061da546Spatrick }
1206061da546Spatrick log->PutCString(log_message.GetData());
1207061da546Spatrick }
1208061da546Spatrick
Dump(Stream * s)1209061da546Spatrick void Module::Dump(Stream *s) {
1210061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
1211061da546Spatrick // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
1212061da546Spatrick s->Indent();
1213061da546Spatrick s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),
1214061da546Spatrick m_object_name ? "(" : "",
1215061da546Spatrick m_object_name ? m_object_name.GetCString() : "",
1216061da546Spatrick m_object_name ? ")" : "");
1217061da546Spatrick
1218061da546Spatrick s->IndentMore();
1219061da546Spatrick
1220061da546Spatrick ObjectFile *objfile = GetObjectFile();
1221061da546Spatrick if (objfile)
1222061da546Spatrick objfile->Dump(s);
1223061da546Spatrick
1224061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
1225061da546Spatrick symbols->Dump(*s);
1226061da546Spatrick
1227061da546Spatrick s->IndentLess();
1228061da546Spatrick }
1229061da546Spatrick
GetObjectName() const1230061da546Spatrick ConstString Module::GetObjectName() const { return m_object_name; }
1231061da546Spatrick
GetObjectFile()1232061da546Spatrick ObjectFile *Module::GetObjectFile() {
1233061da546Spatrick if (!m_did_load_objfile.load()) {
1234061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
1235061da546Spatrick if (!m_did_load_objfile.load()) {
1236be691f3bSpatrick LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",
1237061da546Spatrick GetFileSpec().GetFilename().AsCString(""));
1238061da546Spatrick lldb::offset_t data_offset = 0;
1239dda28197Spatrick lldb::offset_t file_size = 0;
1240dda28197Spatrick
1241dda28197Spatrick if (m_data_sp)
1242dda28197Spatrick file_size = m_data_sp->GetByteSize();
1243dda28197Spatrick else if (m_file)
1244dda28197Spatrick file_size = FileSystem::Instance().GetByteSize(m_file);
1245dda28197Spatrick
1246061da546Spatrick if (file_size > m_object_offset) {
1247061da546Spatrick m_did_load_objfile = true;
1248dda28197Spatrick // FindPlugin will modify its data_sp argument. Do not let it
1249dda28197Spatrick // modify our m_data_sp member.
1250dda28197Spatrick auto data_sp = m_data_sp;
1251061da546Spatrick m_objfile_sp = ObjectFile::FindPlugin(
1252061da546Spatrick shared_from_this(), &m_file, m_object_offset,
1253061da546Spatrick file_size - m_object_offset, data_sp, data_offset);
1254061da546Spatrick if (m_objfile_sp) {
1255061da546Spatrick // Once we get the object file, update our module with the object
1256061da546Spatrick // file's architecture since it might differ in vendor/os if some
1257061da546Spatrick // parts were unknown. But since the matching arch might already be
1258061da546Spatrick // more specific than the generic COFF architecture, only merge in
1259061da546Spatrick // those values that overwrite unspecified unknown values.
1260061da546Spatrick m_arch.MergeFrom(m_objfile_sp->GetArchitecture());
1261061da546Spatrick } else {
1262*f6aab3d8Srobert ReportError("failed to load objfile for {0}",
1263061da546Spatrick GetFileSpec().GetPath().c_str());
1264061da546Spatrick }
1265061da546Spatrick }
1266061da546Spatrick }
1267061da546Spatrick }
1268061da546Spatrick return m_objfile_sp.get();
1269061da546Spatrick }
1270061da546Spatrick
GetSectionList()1271061da546Spatrick SectionList *Module::GetSectionList() {
1272061da546Spatrick // Populate m_sections_up with sections from objfile.
1273061da546Spatrick if (!m_sections_up) {
1274061da546Spatrick ObjectFile *obj_file = GetObjectFile();
1275061da546Spatrick if (obj_file != nullptr)
1276061da546Spatrick obj_file->CreateSections(*GetUnifiedSectionList());
1277061da546Spatrick }
1278061da546Spatrick return m_sections_up.get();
1279061da546Spatrick }
1280061da546Spatrick
SectionFileAddressesChanged()1281061da546Spatrick void Module::SectionFileAddressesChanged() {
1282061da546Spatrick ObjectFile *obj_file = GetObjectFile();
1283061da546Spatrick if (obj_file)
1284061da546Spatrick obj_file->SectionFileAddressesChanged();
1285061da546Spatrick if (SymbolFile *symbols = GetSymbolFile())
1286061da546Spatrick symbols->SectionFileAddressesChanged();
1287061da546Spatrick }
1288061da546Spatrick
GetUnwindTable()1289061da546Spatrick UnwindTable &Module::GetUnwindTable() {
1290*f6aab3d8Srobert if (!m_unwind_table) {
1291061da546Spatrick m_unwind_table.emplace(*this);
1292*f6aab3d8Srobert if (!m_symfile_spec)
1293*f6aab3d8Srobert Symbols::DownloadSymbolFileAsync(GetUUID());
1294*f6aab3d8Srobert }
1295061da546Spatrick return *m_unwind_table;
1296061da546Spatrick }
1297061da546Spatrick
GetUnifiedSectionList()1298061da546Spatrick SectionList *Module::GetUnifiedSectionList() {
1299061da546Spatrick if (!m_sections_up)
1300061da546Spatrick m_sections_up = std::make_unique<SectionList>();
1301061da546Spatrick return m_sections_up.get();
1302061da546Spatrick }
1303061da546Spatrick
FindFirstSymbolWithNameAndType(ConstString name,SymbolType symbol_type)1304061da546Spatrick const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,
1305061da546Spatrick SymbolType symbol_type) {
1306be691f3bSpatrick LLDB_SCOPED_TIMERF(
1307be691f3bSpatrick "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
1308061da546Spatrick name.AsCString(), symbol_type);
1309061da546Spatrick if (Symtab *symtab = GetSymtab())
1310061da546Spatrick return symtab->FindFirstSymbolWithNameAndType(
1311061da546Spatrick name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
1312061da546Spatrick return nullptr;
1313061da546Spatrick }
SymbolIndicesToSymbolContextList(Symtab * symtab,std::vector<uint32_t> & symbol_indexes,SymbolContextList & sc_list)1314061da546Spatrick void Module::SymbolIndicesToSymbolContextList(
1315061da546Spatrick Symtab *symtab, std::vector<uint32_t> &symbol_indexes,
1316061da546Spatrick SymbolContextList &sc_list) {
1317061da546Spatrick // No need to protect this call using m_mutex all other method calls are
1318061da546Spatrick // already thread safe.
1319061da546Spatrick
1320061da546Spatrick size_t num_indices = symbol_indexes.size();
1321061da546Spatrick if (num_indices > 0) {
1322061da546Spatrick SymbolContext sc;
1323061da546Spatrick CalculateSymbolContext(&sc);
1324061da546Spatrick for (size_t i = 0; i < num_indices; i++) {
1325061da546Spatrick sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
1326061da546Spatrick if (sc.symbol)
1327061da546Spatrick sc_list.Append(sc);
1328061da546Spatrick }
1329061da546Spatrick }
1330061da546Spatrick }
1331061da546Spatrick
FindFunctionSymbols(ConstString name,uint32_t name_type_mask,SymbolContextList & sc_list)1332*f6aab3d8Srobert void Module::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
1333061da546Spatrick SymbolContextList &sc_list) {
1334be691f3bSpatrick LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
1335061da546Spatrick name.AsCString(), name_type_mask);
1336061da546Spatrick if (Symtab *symtab = GetSymtab())
1337061da546Spatrick symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
1338061da546Spatrick }
1339061da546Spatrick
FindSymbolsWithNameAndType(ConstString name,SymbolType symbol_type,SymbolContextList & sc_list)1340061da546Spatrick void Module::FindSymbolsWithNameAndType(ConstString name,
1341061da546Spatrick SymbolType symbol_type,
1342061da546Spatrick SymbolContextList &sc_list) {
1343061da546Spatrick // No need to protect this call using m_mutex all other method calls are
1344061da546Spatrick // already thread safe.
1345061da546Spatrick if (Symtab *symtab = GetSymtab()) {
1346061da546Spatrick std::vector<uint32_t> symbol_indexes;
1347061da546Spatrick symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
1348061da546Spatrick SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
1349061da546Spatrick }
1350061da546Spatrick }
1351061da546Spatrick
FindSymbolsMatchingRegExAndType(const RegularExpression & regex,SymbolType symbol_type,SymbolContextList & sc_list,Mangled::NamePreference mangling_preference)1352*f6aab3d8Srobert void Module::FindSymbolsMatchingRegExAndType(
1353*f6aab3d8Srobert const RegularExpression ®ex, SymbolType symbol_type,
1354*f6aab3d8Srobert SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
1355061da546Spatrick // No need to protect this call using m_mutex all other method calls are
1356061da546Spatrick // already thread safe.
1357be691f3bSpatrick LLDB_SCOPED_TIMERF(
1358061da546Spatrick "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
1359061da546Spatrick regex.GetText().str().c_str(), symbol_type);
1360061da546Spatrick if (Symtab *symtab = GetSymtab()) {
1361061da546Spatrick std::vector<uint32_t> symbol_indexes;
1362061da546Spatrick symtab->FindAllSymbolsMatchingRexExAndType(
1363061da546Spatrick regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
1364*f6aab3d8Srobert symbol_indexes, mangling_preference);
1365061da546Spatrick SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
1366061da546Spatrick }
1367061da546Spatrick }
1368061da546Spatrick
PreloadSymbols()1369061da546Spatrick void Module::PreloadSymbols() {
1370061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
1371061da546Spatrick SymbolFile *sym_file = GetSymbolFile();
1372061da546Spatrick if (!sym_file)
1373061da546Spatrick return;
1374061da546Spatrick
1375*f6aab3d8Srobert // Load the object file symbol table and any symbols from the SymbolFile that
1376*f6aab3d8Srobert // get appended using SymbolFile::AddSymbols(...).
1377061da546Spatrick if (Symtab *symtab = sym_file->GetSymtab())
1378061da546Spatrick symtab->PreloadSymbols();
1379*f6aab3d8Srobert
1380*f6aab3d8Srobert // Now let the symbol file preload its data and the symbol table will be
1381*f6aab3d8Srobert // available without needing to take the module lock.
1382*f6aab3d8Srobert sym_file->PreloadSymbols();
1383061da546Spatrick }
1384061da546Spatrick
SetSymbolFileFileSpec(const FileSpec & file)1385061da546Spatrick void Module::SetSymbolFileFileSpec(const FileSpec &file) {
1386061da546Spatrick if (!FileSystem::Instance().Exists(file))
1387061da546Spatrick return;
1388061da546Spatrick if (m_symfile_up) {
1389061da546Spatrick // Remove any sections in the unified section list that come from the
1390061da546Spatrick // current symbol vendor.
1391061da546Spatrick SectionList *section_list = GetSectionList();
1392061da546Spatrick SymbolFile *symbol_file = GetSymbolFile();
1393061da546Spatrick if (section_list && symbol_file) {
1394061da546Spatrick ObjectFile *obj_file = symbol_file->GetObjectFile();
1395061da546Spatrick // Make sure we have an object file and that the symbol vendor's objfile
1396061da546Spatrick // isn't the same as the module's objfile before we remove any sections
1397061da546Spatrick // for it...
1398061da546Spatrick if (obj_file) {
1399061da546Spatrick // Check to make sure we aren't trying to specify the file we already
1400061da546Spatrick // have
1401061da546Spatrick if (obj_file->GetFileSpec() == file) {
1402061da546Spatrick // We are being told to add the exact same file that we already have
1403061da546Spatrick // we don't have to do anything.
1404061da546Spatrick return;
1405061da546Spatrick }
1406061da546Spatrick
1407061da546Spatrick // Cleare the current symtab as we are going to replace it with a new
1408061da546Spatrick // one
1409061da546Spatrick obj_file->ClearSymtab();
1410061da546Spatrick
1411061da546Spatrick // Clear the unwind table too, as that may also be affected by the
1412061da546Spatrick // symbol file information.
1413061da546Spatrick m_unwind_table.reset();
1414061da546Spatrick
1415061da546Spatrick // The symbol file might be a directory bundle ("/tmp/a.out.dSYM")
1416061da546Spatrick // instead of a full path to the symbol file within the bundle
1417061da546Spatrick // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
1418061da546Spatrick // check this
1419061da546Spatrick
1420061da546Spatrick if (FileSystem::Instance().IsDirectory(file)) {
1421061da546Spatrick std::string new_path(file.GetPath());
1422061da546Spatrick std::string old_path(obj_file->GetFileSpec().GetPath());
1423dda28197Spatrick if (llvm::StringRef(old_path).startswith(new_path)) {
1424061da546Spatrick // We specified the same bundle as the symbol file that we already
1425061da546Spatrick // have
1426061da546Spatrick return;
1427061da546Spatrick }
1428061da546Spatrick }
1429061da546Spatrick
1430061da546Spatrick if (obj_file != m_objfile_sp.get()) {
1431061da546Spatrick size_t num_sections = section_list->GetNumSections(0);
1432061da546Spatrick for (size_t idx = num_sections; idx > 0; --idx) {
1433061da546Spatrick lldb::SectionSP section_sp(
1434061da546Spatrick section_list->GetSectionAtIndex(idx - 1));
1435061da546Spatrick if (section_sp->GetObjectFile() == obj_file) {
1436061da546Spatrick section_list->DeleteSection(idx - 1);
1437061da546Spatrick }
1438061da546Spatrick }
1439061da546Spatrick }
1440061da546Spatrick }
1441061da546Spatrick }
1442061da546Spatrick // Keep all old symbol files around in case there are any lingering type
1443061da546Spatrick // references in any SBValue objects that might have been handed out.
1444061da546Spatrick m_old_symfiles.push_back(std::move(m_symfile_up));
1445061da546Spatrick }
1446061da546Spatrick m_symfile_spec = file;
1447061da546Spatrick m_symfile_up.reset();
1448061da546Spatrick m_did_load_symfile = false;
1449061da546Spatrick }
1450061da546Spatrick
IsExecutable()1451061da546Spatrick bool Module::IsExecutable() {
1452061da546Spatrick if (GetObjectFile() == nullptr)
1453061da546Spatrick return false;
1454061da546Spatrick else
1455061da546Spatrick return GetObjectFile()->IsExecutable();
1456061da546Spatrick }
1457061da546Spatrick
IsLoadedInTarget(Target * target)1458061da546Spatrick bool Module::IsLoadedInTarget(Target *target) {
1459061da546Spatrick ObjectFile *obj_file = GetObjectFile();
1460061da546Spatrick if (obj_file) {
1461061da546Spatrick SectionList *sections = GetSectionList();
1462061da546Spatrick if (sections != nullptr) {
1463061da546Spatrick size_t num_sections = sections->GetSize();
1464061da546Spatrick for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {
1465061da546Spatrick SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
1466061da546Spatrick if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {
1467061da546Spatrick return true;
1468061da546Spatrick }
1469061da546Spatrick }
1470061da546Spatrick }
1471061da546Spatrick }
1472061da546Spatrick return false;
1473061da546Spatrick }
1474061da546Spatrick
LoadScriptingResourceInTarget(Target * target,Status & error,Stream * feedback_stream)1475061da546Spatrick bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,
1476061da546Spatrick Stream *feedback_stream) {
1477061da546Spatrick if (!target) {
1478061da546Spatrick error.SetErrorString("invalid destination Target");
1479061da546Spatrick return false;
1480061da546Spatrick }
1481061da546Spatrick
1482061da546Spatrick LoadScriptFromSymFile should_load =
1483061da546Spatrick target->TargetProperties::GetLoadScriptFromSymbolFile();
1484061da546Spatrick
1485061da546Spatrick if (should_load == eLoadScriptFromSymFileFalse)
1486061da546Spatrick return false;
1487061da546Spatrick
1488061da546Spatrick Debugger &debugger = target->GetDebugger();
1489061da546Spatrick const ScriptLanguage script_language = debugger.GetScriptLanguage();
1490061da546Spatrick if (script_language != eScriptLanguageNone) {
1491061da546Spatrick
1492061da546Spatrick PlatformSP platform_sp(target->GetPlatform());
1493061da546Spatrick
1494061da546Spatrick if (!platform_sp) {
1495061da546Spatrick error.SetErrorString("invalid Platform");
1496061da546Spatrick return false;
1497061da546Spatrick }
1498061da546Spatrick
1499061da546Spatrick FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
1500061da546Spatrick target, *this, feedback_stream);
1501061da546Spatrick
1502061da546Spatrick const uint32_t num_specs = file_specs.GetSize();
1503061da546Spatrick if (num_specs) {
1504061da546Spatrick ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
1505061da546Spatrick if (script_interpreter) {
1506061da546Spatrick for (uint32_t i = 0; i < num_specs; ++i) {
1507061da546Spatrick FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
1508061da546Spatrick if (scripting_fspec &&
1509061da546Spatrick FileSystem::Instance().Exists(scripting_fspec)) {
1510061da546Spatrick if (should_load == eLoadScriptFromSymFileWarn) {
1511061da546Spatrick if (feedback_stream)
1512061da546Spatrick feedback_stream->Printf(
1513061da546Spatrick "warning: '%s' contains a debug script. To run this script "
1514061da546Spatrick "in "
1515061da546Spatrick "this debug session:\n\n command script import "
1516061da546Spatrick "\"%s\"\n\n"
1517061da546Spatrick "To run all discovered debug scripts in this session:\n\n"
1518061da546Spatrick " settings set target.load-script-from-symbol-file "
1519061da546Spatrick "true\n",
1520061da546Spatrick GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1521061da546Spatrick scripting_fspec.GetPath().c_str());
1522061da546Spatrick return false;
1523061da546Spatrick }
1524061da546Spatrick StreamString scripting_stream;
1525061da546Spatrick scripting_fspec.Dump(scripting_stream.AsRawOstream());
1526be691f3bSpatrick LoadScriptOptions options;
1527061da546Spatrick bool did_load = script_interpreter->LoadScriptingModule(
1528be691f3bSpatrick scripting_stream.GetData(), options, error);
1529061da546Spatrick if (!did_load)
1530061da546Spatrick return false;
1531061da546Spatrick }
1532061da546Spatrick }
1533061da546Spatrick } else {
1534061da546Spatrick error.SetErrorString("invalid ScriptInterpreter");
1535061da546Spatrick return false;
1536061da546Spatrick }
1537061da546Spatrick }
1538061da546Spatrick }
1539061da546Spatrick return true;
1540061da546Spatrick }
1541061da546Spatrick
SetArchitecture(const ArchSpec & new_arch)1542061da546Spatrick bool Module::SetArchitecture(const ArchSpec &new_arch) {
1543061da546Spatrick if (!m_arch.IsValid()) {
1544061da546Spatrick m_arch = new_arch;
1545061da546Spatrick return true;
1546061da546Spatrick }
1547061da546Spatrick return m_arch.IsCompatibleMatch(new_arch);
1548061da546Spatrick }
1549061da546Spatrick
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset,bool & changed)1550061da546Spatrick bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
1551061da546Spatrick bool value_is_offset, bool &changed) {
1552061da546Spatrick ObjectFile *object_file = GetObjectFile();
1553061da546Spatrick if (object_file != nullptr) {
1554061da546Spatrick changed = object_file->SetLoadAddress(target, value, value_is_offset);
1555061da546Spatrick return true;
1556061da546Spatrick } else {
1557061da546Spatrick changed = false;
1558061da546Spatrick }
1559061da546Spatrick return false;
1560061da546Spatrick }
1561061da546Spatrick
MatchesModuleSpec(const ModuleSpec & module_ref)1562061da546Spatrick bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
1563061da546Spatrick const UUID &uuid = module_ref.GetUUID();
1564061da546Spatrick
1565061da546Spatrick if (uuid.IsValid()) {
1566061da546Spatrick // If the UUID matches, then nothing more needs to match...
1567061da546Spatrick return (uuid == GetUUID());
1568061da546Spatrick }
1569061da546Spatrick
1570061da546Spatrick const FileSpec &file_spec = module_ref.GetFileSpec();
1571061da546Spatrick if (!FileSpec::Match(file_spec, m_file) &&
1572061da546Spatrick !FileSpec::Match(file_spec, m_platform_file))
1573061da546Spatrick return false;
1574061da546Spatrick
1575061da546Spatrick const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
1576061da546Spatrick if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))
1577061da546Spatrick return false;
1578061da546Spatrick
1579061da546Spatrick const ArchSpec &arch = module_ref.GetArchitecture();
1580061da546Spatrick if (arch.IsValid()) {
1581061da546Spatrick if (!m_arch.IsCompatibleMatch(arch))
1582061da546Spatrick return false;
1583061da546Spatrick }
1584061da546Spatrick
1585061da546Spatrick ConstString object_name = module_ref.GetObjectName();
1586061da546Spatrick if (object_name) {
1587061da546Spatrick if (object_name != GetObjectName())
1588061da546Spatrick return false;
1589061da546Spatrick }
1590061da546Spatrick return true;
1591061da546Spatrick }
1592061da546Spatrick
FindSourceFile(const FileSpec & orig_spec,FileSpec & new_spec) const1593061da546Spatrick bool Module::FindSourceFile(const FileSpec &orig_spec,
1594061da546Spatrick FileSpec &new_spec) const {
1595061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
1596be691f3bSpatrick if (auto remapped = m_source_mappings.FindFile(orig_spec)) {
1597be691f3bSpatrick new_spec = *remapped;
1598be691f3bSpatrick return true;
1599be691f3bSpatrick }
1600be691f3bSpatrick return false;
1601061da546Spatrick }
1602061da546Spatrick
RemapSourceFile(llvm::StringRef path) const1603*f6aab3d8Srobert std::optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {
1604061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex);
1605be691f3bSpatrick if (auto remapped = m_source_mappings.RemapPath(path))
1606be691f3bSpatrick return remapped->GetPath();
1607be691f3bSpatrick return {};
1608061da546Spatrick }
1609061da546Spatrick
RegisterXcodeSDK(llvm::StringRef sdk_name,llvm::StringRef sysroot)1610*f6aab3d8Srobert void Module::RegisterXcodeSDK(llvm::StringRef sdk_name,
1611*f6aab3d8Srobert llvm::StringRef sysroot) {
1612dda28197Spatrick XcodeSDK sdk(sdk_name.str());
1613*f6aab3d8Srobert auto sdk_path_or_err = HostInfo::GetXcodeSDKPath(sdk);
1614*f6aab3d8Srobert
1615*f6aab3d8Srobert if (!sdk_path_or_err) {
1616*f6aab3d8Srobert Debugger::ReportError("Error while searching for Xcode SDK: " +
1617*f6aab3d8Srobert toString(sdk_path_or_err.takeError()));
1618*f6aab3d8Srobert return;
1619*f6aab3d8Srobert }
1620*f6aab3d8Srobert
1621*f6aab3d8Srobert auto sdk_path = *sdk_path_or_err;
1622*f6aab3d8Srobert if (sdk_path.empty())
1623dda28197Spatrick return;
1624dda28197Spatrick // If the SDK changed for a previously registered source path, update it.
1625dda28197Spatrick // This could happend with -fdebug-prefix-map, otherwise it's unlikely.
1626*f6aab3d8Srobert if (!m_source_mappings.Replace(sysroot, sdk_path, true))
1627dda28197Spatrick // In the general case, however, append it to the list.
1628*f6aab3d8Srobert m_source_mappings.Append(sysroot, sdk_path, false);
1629dda28197Spatrick }
1630dda28197Spatrick
MergeArchitecture(const ArchSpec & arch_spec)1631061da546Spatrick bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
1632061da546Spatrick if (!arch_spec.IsValid())
1633061da546Spatrick return false;
1634*f6aab3d8Srobert LLDB_LOGF(GetLog(LLDBLog::Object | LLDBLog::Modules),
1635061da546Spatrick "module has arch %s, merging/replacing with arch %s",
1636061da546Spatrick m_arch.GetTriple().getTriple().c_str(),
1637061da546Spatrick arch_spec.GetTriple().getTriple().c_str());
1638061da546Spatrick if (!m_arch.IsCompatibleMatch(arch_spec)) {
1639061da546Spatrick // The new architecture is different, we just need to replace it.
1640061da546Spatrick return SetArchitecture(arch_spec);
1641061da546Spatrick }
1642061da546Spatrick
1643061da546Spatrick // Merge bits from arch_spec into "merged_arch" and set our architecture.
1644061da546Spatrick ArchSpec merged_arch(m_arch);
1645061da546Spatrick merged_arch.MergeFrom(arch_spec);
1646061da546Spatrick // SetArchitecture() is a no-op if m_arch is already valid.
1647061da546Spatrick m_arch = ArchSpec();
1648061da546Spatrick return SetArchitecture(merged_arch);
1649061da546Spatrick }
1650061da546Spatrick
GetVersion()1651061da546Spatrick llvm::VersionTuple Module::GetVersion() {
1652061da546Spatrick if (ObjectFile *obj_file = GetObjectFile())
1653061da546Spatrick return obj_file->GetVersion();
1654061da546Spatrick return llvm::VersionTuple();
1655061da546Spatrick }
1656061da546Spatrick
GetIsDynamicLinkEditor()1657061da546Spatrick bool Module::GetIsDynamicLinkEditor() {
1658061da546Spatrick ObjectFile *obj_file = GetObjectFile();
1659061da546Spatrick
1660061da546Spatrick if (obj_file)
1661061da546Spatrick return obj_file->GetIsDynamicLinkEditor();
1662061da546Spatrick
1663061da546Spatrick return false;
1664061da546Spatrick }
1665*f6aab3d8Srobert
Hash()1666*f6aab3d8Srobert uint32_t Module::Hash() {
1667*f6aab3d8Srobert std::string identifier;
1668*f6aab3d8Srobert llvm::raw_string_ostream id_strm(identifier);
1669*f6aab3d8Srobert id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath();
1670*f6aab3d8Srobert if (m_object_name)
1671*f6aab3d8Srobert id_strm << '(' << m_object_name.GetStringRef() << ')';
1672*f6aab3d8Srobert if (m_object_offset > 0)
1673*f6aab3d8Srobert id_strm << m_object_offset;
1674*f6aab3d8Srobert const auto mtime = llvm::sys::toTimeT(m_object_mod_time);
1675*f6aab3d8Srobert if (mtime > 0)
1676*f6aab3d8Srobert id_strm << mtime;
1677*f6aab3d8Srobert return llvm::djbHash(id_strm.str());
1678*f6aab3d8Srobert }
1679*f6aab3d8Srobert
GetCacheKey()1680*f6aab3d8Srobert std::string Module::GetCacheKey() {
1681*f6aab3d8Srobert std::string key;
1682*f6aab3d8Srobert llvm::raw_string_ostream strm(key);
1683*f6aab3d8Srobert strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename();
1684*f6aab3d8Srobert if (m_object_name)
1685*f6aab3d8Srobert strm << '(' << m_object_name.GetStringRef() << ')';
1686*f6aab3d8Srobert strm << '-' << llvm::format_hex(Hash(), 10);
1687*f6aab3d8Srobert return strm.str();
1688*f6aab3d8Srobert }
1689*f6aab3d8Srobert
GetIndexCache()1690*f6aab3d8Srobert DataFileCache *Module::GetIndexCache() {
1691*f6aab3d8Srobert if (!ModuleList::GetGlobalModuleListProperties().GetEnableLLDBIndexCache())
1692*f6aab3d8Srobert return nullptr;
1693*f6aab3d8Srobert // NOTE: intentional leak so we don't crash if global destructor chain gets
1694*f6aab3d8Srobert // called as other threads still use the result of this function
1695*f6aab3d8Srobert static DataFileCache *g_data_file_cache =
1696*f6aab3d8Srobert new DataFileCache(ModuleList::GetGlobalModuleListProperties()
1697*f6aab3d8Srobert .GetLLDBIndexCachePath()
1698*f6aab3d8Srobert .GetPath());
1699*f6aab3d8Srobert return g_data_file_cache;
1700*f6aab3d8Srobert }
1701