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/Section.h"
17 #include "lldb/Symbol/LocateSymbolFile.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
);
87 // Check if the executable has changed and set it to the target
88 // executable if they differ.
89 if (module_sp
&& module_sp
->GetUUID().IsValid() &&
90 executable
->GetUUID().IsValid()) {
91 if (module_sp
->GetUUID() != executable
->GetUUID())
93 } else if (executable
->FileHasChanged()) {
98 executable
= target
.GetOrCreateModule(module_spec
, true /* notify */);
99 if (executable
.get() != target
.GetExecutableModulePointer()) {
100 // Don't load dependent images since we are in dyld where we will
101 // know and find out about all images that are loaded
102 target
.SetExecutableModule(executable
, eLoadDependentsNo
);
110 void DynamicLoader::UpdateLoadedSections(ModuleSP module
, addr_t link_map_addr
,
112 bool base_addr_is_offset
) {
113 UpdateLoadedSectionsCommon(module
, base_addr
, base_addr_is_offset
);
116 void DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module
,
118 bool base_addr_is_offset
) {
120 module
->SetLoadAddress(m_process
->GetTarget(), base_addr
, base_addr_is_offset
,
124 void DynamicLoader::UnloadSections(const ModuleSP module
) {
125 UnloadSectionsCommon(module
);
128 void DynamicLoader::UnloadSectionsCommon(const ModuleSP module
) {
129 Target
&target
= m_process
->GetTarget();
130 const SectionList
*sections
= GetSectionListFromModule(module
);
132 assert(sections
&& "SectionList missing from unloaded module.");
134 const size_t num_sections
= sections
->GetSize();
135 for (size_t i
= 0; i
< num_sections
; ++i
) {
136 SectionSP
section_sp(sections
->GetSectionAtIndex(i
));
137 target
.SetSectionUnloaded(section_sp
);
142 DynamicLoader::GetSectionListFromModule(const ModuleSP module
) const {
143 SectionList
*sections
= nullptr;
145 ObjectFile
*obj_file
= module
->GetObjectFile();
146 if (obj_file
!= nullptr) {
147 sections
= obj_file
->GetSectionList();
153 ModuleSP
DynamicLoader::FindModuleViaTarget(const FileSpec
&file
) {
154 Target
&target
= m_process
->GetTarget();
155 ModuleSpec
module_spec(file
, target
.GetArchitecture());
157 if (ModuleSP module_sp
= target
.GetImages().FindFirstModule(module_spec
))
160 if (ModuleSP module_sp
= target
.GetOrCreateModule(module_spec
, false))
166 ModuleSP
DynamicLoader::LoadModuleAtAddress(const FileSpec
&file
,
167 addr_t link_map_addr
,
169 bool base_addr_is_offset
) {
170 if (ModuleSP module_sp
= FindModuleViaTarget(file
)) {
171 UpdateLoadedSections(module_sp
, link_map_addr
, base_addr
,
172 base_addr_is_offset
);
179 static ModuleSP
ReadUnnamedMemoryModule(Process
*process
, addr_t addr
,
180 llvm::StringRef name
) {
183 snprintf(namebuf
, sizeof(namebuf
), "memory-image-0x%" PRIx64
, addr
);
186 return process
->ReadModuleFromMemory(FileSpec(name
), addr
);
189 ModuleSP
DynamicLoader::LoadBinaryWithUUIDAndAddress(
190 Process
*process
, llvm::StringRef name
, UUID uuid
, addr_t value
,
191 bool value_is_offset
, bool force_symbol_search
, bool notify
,
192 bool set_address_in_target
, bool allow_memory_image_last_resort
) {
193 ModuleSP memory_module_sp
;
195 PlatformSP platform_sp
= process
->GetTarget().GetPlatform();
196 Target
&target
= process
->GetTarget();
199 if (!uuid
.IsValid() && !value_is_offset
) {
200 memory_module_sp
= ReadUnnamedMemoryModule(process
, value
, name
);
202 if (memory_module_sp
)
203 uuid
= memory_module_sp
->GetUUID();
205 ModuleSpec module_spec
;
206 module_spec
.GetUUID() = uuid
;
207 FileSpec
name_filespec(name
);
208 if (FileSystem::Instance().Exists(name_filespec
))
209 module_spec
.GetFileSpec() = name_filespec
;
211 if (uuid
.IsValid()) {
212 // Has lldb already seen a module with this UUID?
214 error
= ModuleList::GetSharedModule(module_spec
, module_sp
, nullptr,
217 // Can lldb's symbol/executable location schemes
218 // find an executable and symbol file.
220 FileSpecList search_paths
= Target::GetDefaultDebugFileSearchPaths();
221 module_spec
.GetSymbolFileSpec() =
222 Symbols::LocateExecutableSymbolFile(module_spec
, search_paths
);
223 ModuleSpec objfile_module_spec
=
224 Symbols::LocateExecutableObjectFile(module_spec
);
225 module_spec
.GetFileSpec() = objfile_module_spec
.GetFileSpec();
226 if (FileSystem::Instance().Exists(module_spec
.GetFileSpec()) &&
227 FileSystem::Instance().Exists(module_spec
.GetSymbolFileSpec())) {
228 module_sp
= std::make_shared
<Module
>(module_spec
);
232 // If we haven't found a binary, or we don't have a SymbolFile, see
233 // if there is an external search tool that can find it.
234 if (!module_sp
|| !module_sp
->GetSymbolFileFileSpec()) {
235 Symbols::DownloadObjectAndSymbolFile(module_spec
, error
,
236 force_symbol_search
);
237 if (FileSystem::Instance().Exists(module_spec
.GetFileSpec())) {
238 module_sp
= std::make_shared
<Module
>(module_spec
);
239 } else if (force_symbol_search
&& error
.AsCString("") &&
240 error
.AsCString("")[0] != '\0') {
241 target
.GetDebugger().GetErrorStream() << error
.AsCString();
245 // If we only found the executable, create a Module based on that.
246 if (!module_sp
&& FileSystem::Instance().Exists(module_spec
.GetFileSpec()))
247 module_sp
= std::make_shared
<Module
>(module_spec
);
250 // If we couldn't find the binary anywhere else, as a last resort,
251 // read it out of memory.
252 if (allow_memory_image_last_resort
&& !module_sp
.get() &&
253 value
!= LLDB_INVALID_ADDRESS
&& !value_is_offset
) {
254 if (!memory_module_sp
)
255 memory_module_sp
= ReadUnnamedMemoryModule(process
, value
, name
);
256 if (memory_module_sp
)
257 module_sp
= memory_module_sp
;
260 Log
*log
= GetLog(LLDBLog::DynamicLoader
);
261 if (module_sp
.get()) {
262 // Ensure the Target has an architecture set in case
263 // we need it while processing this binary/eh_frame/debug info.
264 if (!target
.GetArchitecture().IsValid())
265 target
.SetArchitecture(module_sp
->GetArchitecture());
266 target
.GetImages().AppendIfNeeded(module_sp
, false);
268 bool changed
= false;
269 if (set_address_in_target
) {
270 if (module_sp
->GetObjectFile()) {
271 if (value
!= LLDB_INVALID_ADDRESS
) {
273 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
274 "binary %s UUID %s at %s 0x%" PRIx64
,
275 name
.str().c_str(), uuid
.GetAsString().c_str(),
276 value_is_offset
? "offset" : "address", value
);
277 module_sp
->SetLoadAddress(target
, value
, value_is_offset
, changed
);
279 // No address/offset/slide, load the binary at file address,
282 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
283 "binary %s UUID %s at file address",
284 name
.str().c_str(), uuid
.GetAsString().c_str());
285 module_sp
->SetLoadAddress(target
, 0, true /* value_is_slide */,
289 // In-memory image, load at its true address, offset 0.
291 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary "
292 "%s UUID %s from memory at address 0x%" PRIx64
,
293 name
.str().c_str(), uuid
.GetAsString().c_str(), value
);
294 module_sp
->SetLoadAddress(target
, 0, true /* value_is_slide */,
300 ModuleList added_module
;
301 added_module
.Append(module_sp
, false);
302 target
.ModulesDidLoad(added_module
);
305 if (force_symbol_search
) {
306 Stream
&s
= target
.GetDebugger().GetErrorStream();
307 s
.Printf("Unable to find file");
309 s
.Printf(" %s", name
.str().c_str());
311 s
.Printf(" with UUID %s", uuid
.GetAsString().c_str());
312 if (value
!= LLDB_INVALID_ADDRESS
) {
314 s
.Printf(" with slide 0x%" PRIx64
, value
);
316 s
.Printf(" at address 0x%" PRIx64
, value
);
321 "Unable to find binary %s with UUID %s and load it at "
323 name
.str().c_str(), uuid
.GetAsString().c_str(),
324 value_is_offset
? "offset" : "address", value
);
330 int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr
,
334 m_process
->ReadUnsignedIntegerFromMemory(addr
, size_in_bytes
, 0, error
);
338 return (int64_t)value
;
341 addr_t
DynamicLoader::ReadPointer(addr_t addr
) {
343 addr_t value
= m_process
->ReadPointerFromMemory(addr
, error
);
345 return LLDB_INVALID_ADDRESS
;
350 void DynamicLoader::LoadOperatingSystemPlugin(bool flush
)
353 m_process
->LoadOperatingSystemPlugin(flush
);