1 //===-- DynamicLoader.cpp -------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/DynamicLoader.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleList.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Progress.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Symbol/ObjectFile.h"
19 #include "lldb/Target/MemoryRegionInfo.h"
20 #include "lldb/Target/Platform.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Utility/ConstString.h"
24 #include "lldb/Utility/LLDBLog.h"
25 #include "lldb/Utility/Log.h"
26 #include "lldb/lldb-private-interfaces.h"
28 #include "llvm/ADT/StringRef.h"
35 using namespace lldb_private
;
37 DynamicLoader
*DynamicLoader::FindPlugin(Process
*process
,
38 llvm::StringRef plugin_name
) {
39 DynamicLoaderCreateInstance create_callback
= nullptr;
40 if (!plugin_name
.empty()) {
42 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name
);
43 if (create_callback
) {
44 std::unique_ptr
<DynamicLoader
> instance_up(
45 create_callback(process
, true));
47 return instance_up
.release();
50 for (uint32_t idx
= 0;
52 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx
)) !=
55 std::unique_ptr
<DynamicLoader
> instance_up(
56 create_callback(process
, false));
58 return instance_up
.release();
64 DynamicLoader::DynamicLoader(Process
*process
) : m_process(process
) {}
66 // Accessors to the global setting as to whether to stop at image (shared
67 // library) loading/unloading.
69 bool DynamicLoader::GetStopWhenImagesChange() const {
70 return m_process
->GetStopOnSharedLibraryEvents();
73 void DynamicLoader::SetStopWhenImagesChange(bool stop
) {
74 m_process
->SetStopOnSharedLibraryEvents(stop
);
77 ModuleSP
DynamicLoader::GetTargetExecutable() {
78 Target
&target
= m_process
->GetTarget();
79 ModuleSP executable
= target
.GetExecutableModule();
82 if (FileSystem::Instance().Exists(executable
->GetFileSpec())) {
83 ModuleSpec
module_spec(executable
->GetFileSpec(),
84 executable
->GetArchitecture());
85 auto module_sp
= std::make_shared
<Module
>(module_spec
);
86 // If we're a coredump and we already have a main executable, we don't
87 // need to reload the module list that target already has
88 if (!m_process
->IsLiveDebugSession()) {
91 // Check if the executable has changed and set it to the target
92 // executable if they differ.
93 if (module_sp
&& module_sp
->GetUUID().IsValid() &&
94 executable
->GetUUID().IsValid()) {
95 if (module_sp
->GetUUID() != executable
->GetUUID())
97 } else if (executable
->FileHasChanged()) {
102 executable
= target
.GetOrCreateModule(module_spec
, true /* notify */);
103 if (executable
.get() != target
.GetExecutableModulePointer()) {
104 // Don't load dependent images since we are in dyld where we will
105 // know and find out about all images that are loaded
106 target
.SetExecutableModule(executable
, eLoadDependentsNo
);
114 void DynamicLoader::UpdateLoadedSections(ModuleSP module
, addr_t link_map_addr
,
116 bool base_addr_is_offset
) {
117 UpdateLoadedSectionsCommon(module
, base_addr
, base_addr_is_offset
);
120 void DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module
,
122 bool base_addr_is_offset
) {
124 module
->SetLoadAddress(m_process
->GetTarget(), base_addr
, base_addr_is_offset
,
128 void DynamicLoader::UnloadSections(const ModuleSP module
) {
129 UnloadSectionsCommon(module
);
132 void DynamicLoader::UnloadSectionsCommon(const ModuleSP module
) {
133 Target
&target
= m_process
->GetTarget();
134 const SectionList
*sections
= GetSectionListFromModule(module
);
136 assert(sections
&& "SectionList missing from unloaded module.");
138 const size_t num_sections
= sections
->GetSize();
139 for (size_t i
= 0; i
< num_sections
; ++i
) {
140 SectionSP
section_sp(sections
->GetSectionAtIndex(i
));
141 target
.SetSectionUnloaded(section_sp
);
146 DynamicLoader::GetSectionListFromModule(const ModuleSP module
) const {
147 SectionList
*sections
= nullptr;
149 ObjectFile
*obj_file
= module
->GetObjectFile();
150 if (obj_file
!= nullptr) {
151 sections
= obj_file
->GetSectionList();
157 ModuleSP
DynamicLoader::FindModuleViaTarget(const FileSpec
&file
) {
158 Target
&target
= m_process
->GetTarget();
159 ModuleSpec
module_spec(file
, target
.GetArchitecture());
160 if (UUID uuid
= m_process
->FindModuleUUID(file
.GetPath())) {
161 // Process may be able to augment the module_spec with UUID, e.g. ELF core.
162 module_spec
.GetUUID() = uuid
;
165 if (ModuleSP module_sp
= target
.GetImages().FindFirstModule(module_spec
))
168 if (ModuleSP module_sp
= target
.GetOrCreateModule(module_spec
, false))
174 ModuleSP
DynamicLoader::LoadModuleAtAddress(const FileSpec
&file
,
175 addr_t link_map_addr
,
177 bool base_addr_is_offset
) {
178 if (ModuleSP module_sp
= FindModuleViaTarget(file
)) {
179 UpdateLoadedSections(module_sp
, link_map_addr
, base_addr
,
180 base_addr_is_offset
);
187 static ModuleSP
ReadUnnamedMemoryModule(Process
*process
, addr_t addr
,
188 llvm::StringRef name
) {
191 snprintf(namebuf
, sizeof(namebuf
), "memory-image-0x%" PRIx64
, addr
);
194 return process
->ReadModuleFromMemory(FileSpec(name
), addr
);
197 ModuleSP
DynamicLoader::LoadBinaryWithUUIDAndAddress(
198 Process
*process
, llvm::StringRef name
, UUID uuid
, addr_t value
,
199 bool value_is_offset
, bool force_symbol_search
, bool notify
,
200 bool set_address_in_target
, bool allow_memory_image_last_resort
) {
201 ModuleSP memory_module_sp
;
203 PlatformSP platform_sp
= process
->GetTarget().GetPlatform();
204 Target
&target
= process
->GetTarget();
207 StreamString prog_str
;
209 prog_str
<< name
.str() << " ";
212 prog_str
<< uuid
.GetAsString();
213 if (value_is_offset
== 0 && value
!= LLDB_INVALID_ADDRESS
) {
215 prog_str
.PutHex64(value
);
218 if (!uuid
.IsValid() && !value_is_offset
) {
219 memory_module_sp
= ReadUnnamedMemoryModule(process
, value
, name
);
221 if (memory_module_sp
) {
222 uuid
= memory_module_sp
->GetUUID();
223 if (uuid
.IsValid()) {
225 prog_str
<< uuid
.GetAsString();
229 ModuleSpec module_spec
;
230 module_spec
.GetUUID() = uuid
;
231 FileSpec
name_filespec(name
);
233 if (uuid
.IsValid()) {
234 Progress
progress("Locating binary", prog_str
.GetString().str());
236 // Has lldb already seen a module with this UUID?
237 // Or have external lookup enabled in DebugSymbols on macOS.
239 error
= ModuleList::GetSharedModule(module_spec
, module_sp
, nullptr,
242 // Can lldb's symbol/executable location schemes
243 // find an executable and symbol file.
245 FileSpecList search_paths
= Target::GetDefaultDebugFileSearchPaths();
246 module_spec
.GetSymbolFileSpec() =
247 PluginManager::LocateExecutableSymbolFile(module_spec
, search_paths
);
248 ModuleSpec objfile_module_spec
=
249 PluginManager::LocateExecutableObjectFile(module_spec
);
250 module_spec
.GetFileSpec() = objfile_module_spec
.GetFileSpec();
251 if (FileSystem::Instance().Exists(module_spec
.GetFileSpec()) &&
252 FileSystem::Instance().Exists(module_spec
.GetSymbolFileSpec())) {
253 module_sp
= std::make_shared
<Module
>(module_spec
);
257 // If we haven't found a binary, or we don't have a SymbolFile, see
258 // if there is an external search tool that can find it.
259 if (!module_sp
|| !module_sp
->GetSymbolFileFileSpec()) {
260 PluginManager::DownloadObjectAndSymbolFile(module_spec
, error
,
261 force_symbol_search
);
262 if (FileSystem::Instance().Exists(module_spec
.GetFileSpec())) {
263 module_sp
= std::make_shared
<Module
>(module_spec
);
264 } else if (force_symbol_search
&& error
.AsCString("") &&
265 error
.AsCString("")[0] != '\0') {
266 target
.GetDebugger().GetErrorStream() << error
.AsCString();
270 // If we only found the executable, create a Module based on that.
271 if (!module_sp
&& FileSystem::Instance().Exists(module_spec
.GetFileSpec()))
272 module_sp
= std::make_shared
<Module
>(module_spec
);
275 // If we couldn't find the binary anywhere else, as a last resort,
276 // read it out of memory.
277 if (allow_memory_image_last_resort
&& !module_sp
.get() &&
278 value
!= LLDB_INVALID_ADDRESS
&& !value_is_offset
) {
279 if (!memory_module_sp
)
280 memory_module_sp
= ReadUnnamedMemoryModule(process
, value
, name
);
281 if (memory_module_sp
)
282 module_sp
= memory_module_sp
;
285 Log
*log
= GetLog(LLDBLog::DynamicLoader
);
286 if (module_sp
.get()) {
287 // Ensure the Target has an architecture set in case
288 // we need it while processing this binary/eh_frame/debug info.
289 if (!target
.GetArchitecture().IsValid())
290 target
.SetArchitecture(module_sp
->GetArchitecture());
291 target
.GetImages().AppendIfNeeded(module_sp
, false);
293 bool changed
= false;
294 if (set_address_in_target
) {
295 if (module_sp
->GetObjectFile()) {
296 if (value
!= LLDB_INVALID_ADDRESS
) {
298 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
299 "binary %s UUID %s at %s 0x%" PRIx64
,
300 name
.str().c_str(), uuid
.GetAsString().c_str(),
301 value_is_offset
? "offset" : "address", value
);
302 module_sp
->SetLoadAddress(target
, value
, value_is_offset
, changed
);
304 // No address/offset/slide, load the binary at file address,
307 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
308 "binary %s UUID %s at file address",
309 name
.str().c_str(), uuid
.GetAsString().c_str());
310 module_sp
->SetLoadAddress(target
, 0, true /* value_is_slide */,
314 // In-memory image, load at its true address, offset 0.
316 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary "
317 "%s UUID %s from memory at address 0x%" PRIx64
,
318 name
.str().c_str(), uuid
.GetAsString().c_str(), value
);
319 module_sp
->SetLoadAddress(target
, 0, true /* value_is_slide */,
325 ModuleList added_module
;
326 added_module
.Append(module_sp
, false);
327 target
.ModulesDidLoad(added_module
);
330 if (force_symbol_search
) {
331 Stream
&s
= target
.GetDebugger().GetErrorStream();
332 s
.Printf("Unable to find file");
334 s
.Printf(" %s", name
.str().c_str());
336 s
.Printf(" with UUID %s", uuid
.GetAsString().c_str());
337 if (value
!= LLDB_INVALID_ADDRESS
) {
339 s
.Printf(" with slide 0x%" PRIx64
, value
);
341 s
.Printf(" at address 0x%" PRIx64
, value
);
346 "Unable to find binary %s with UUID %s and load it at "
348 name
.str().c_str(), uuid
.GetAsString().c_str(),
349 value_is_offset
? "offset" : "address", value
);
355 int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr
,
359 m_process
->ReadUnsignedIntegerFromMemory(addr
, size_in_bytes
, 0, error
);
363 return (int64_t)value
;
366 addr_t
DynamicLoader::ReadPointer(addr_t addr
) {
368 addr_t value
= m_process
->ReadPointerFromMemory(addr
, error
);
370 return LLDB_INVALID_ADDRESS
;
375 void DynamicLoader::LoadOperatingSystemPlugin(bool flush
)
378 m_process
->LoadOperatingSystemPlugin(flush
);