LLDB mainline
DynamicLoader.cpp
Go to the documentation of this file.
1//===-- DynamicLoader.cpp -------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Core/Module.h"
15#include "lldb/Core/Section.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Target/Target.h"
24#include "lldb/Utility/Log.h"
26
27#include "llvm/ADT/StringRef.h"
28
29#include <memory>
30
31#include <cassert>
32
33using namespace lldb;
34using namespace lldb_private;
35
37 llvm::StringRef plugin_name) {
38 DynamicLoaderCreateInstance create_callback = nullptr;
39 if (!plugin_name.empty()) {
40 create_callback =
42 if (create_callback) {
43 std::unique_ptr<DynamicLoader> instance_up(
44 create_callback(process, true));
45 if (instance_up)
46 return instance_up.release();
47 }
48 } else {
49 for (uint32_t idx = 0;
50 (create_callback =
52 nullptr;
53 ++idx) {
54 std::unique_ptr<DynamicLoader> instance_up(
55 create_callback(process, false));
56 if (instance_up)
57 return instance_up.release();
58 }
59 }
60 return nullptr;
61}
62
63DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
64
65// Accessors to the global setting as to whether to stop at image (shared
66// library) loading/unloading.
67
70}
71
74}
75
77 Target &target = m_process->GetTarget();
78 ModuleSP executable = target.GetExecutableModule();
79
80 if (executable) {
81 if (FileSystem::Instance().Exists(executable->GetFileSpec())) {
82 ModuleSpec module_spec(executable->GetFileSpec(),
83 executable->GetArchitecture());
84 auto module_sp = std::make_shared<Module>(module_spec);
85
86 // Check if the executable has changed and set it to the target
87 // executable if they differ.
88 if (module_sp && module_sp->GetUUID().IsValid() &&
89 executable->GetUUID().IsValid()) {
90 if (module_sp->GetUUID() != executable->GetUUID())
91 executable.reset();
92 } else if (executable->FileHasChanged()) {
93 executable.reset();
94 }
95
96 if (!executable) {
97 executable = target.GetOrCreateModule(module_spec, true /* notify */);
98 if (executable.get() != target.GetExecutableModulePointer()) {
99 // Don't load dependent images since we are in dyld where we will
100 // know and find out about all images that are loaded
101 target.SetExecutableModule(executable, eLoadDependentsNo);
102 }
103 }
104 }
105 }
106 return executable;
107}
108
109void DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr,
110 addr_t base_addr,
111 bool base_addr_is_offset) {
112 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
113}
114
116 addr_t base_addr,
117 bool base_addr_is_offset) {
118 bool changed;
119 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset,
120 changed);
121}
122
123void DynamicLoader::UnloadSections(const ModuleSP module) {
124 UnloadSectionsCommon(module);
125}
126
127void DynamicLoader::UnloadSectionsCommon(const ModuleSP module) {
128 Target &target = m_process->GetTarget();
129 const SectionList *sections = GetSectionListFromModule(module);
130
131 assert(sections && "SectionList missing from unloaded module.");
132
133 const size_t num_sections = sections->GetSize();
134 for (size_t i = 0; i < num_sections; ++i) {
135 SectionSP section_sp(sections->GetSectionAtIndex(i));
136 target.SetSectionUnloaded(section_sp);
137 }
138}
139
140const SectionList *
141DynamicLoader::GetSectionListFromModule(const ModuleSP module) const {
142 SectionList *sections = nullptr;
143 if (module) {
144 ObjectFile *obj_file = module->GetObjectFile();
145 if (obj_file != nullptr) {
146 sections = obj_file->GetSectionList();
147 }
148 }
149 return sections;
150}
151
153 Target &target = m_process->GetTarget();
154 ModuleSpec module_spec(file, target.GetArchitecture());
155
156 if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec))
157 return module_sp;
158
159 if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false))
160 return module_sp;
161
162 return nullptr;
163}
164
166 addr_t link_map_addr,
167 addr_t base_addr,
168 bool base_addr_is_offset) {
169 if (ModuleSP module_sp = FindModuleViaTarget(file)) {
170 UpdateLoadedSections(module_sp, link_map_addr, base_addr,
171 base_addr_is_offset);
172 return module_sp;
173 }
174
175 return nullptr;
176}
177
178static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr,
179 llvm::StringRef name) {
180 char namebuf[80];
181 if (name.empty()) {
182 snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
183 name = namebuf;
184 }
185 return process->ReadModuleFromMemory(FileSpec(name), addr);
186}
187
189 Process *process, llvm::StringRef name, UUID uuid, addr_t value,
190 bool value_is_offset, bool force_symbol_search, bool notify) {
191 ModuleSP memory_module_sp;
192 ModuleSP module_sp;
193 PlatformSP platform_sp = process->GetTarget().GetPlatform();
194 Target &target = process->GetTarget();
196 ModuleSpec module_spec;
197 module_spec.GetUUID() = uuid;
198
199 if (!uuid.IsValid() && !value_is_offset) {
200 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
201
202 if (memory_module_sp)
203 uuid = memory_module_sp->GetUUID();
204 }
205
206 if (uuid.IsValid()) {
207 ModuleSpec module_spec;
208 module_spec.GetUUID() = uuid;
209
210 if (!module_sp)
211 module_sp = target.GetOrCreateModule(module_spec, false, &error);
212
213 // If we haven't found a binary, or we don't have a SymbolFile, see
214 // if there is an external search tool that can find it.
215 if (force_symbol_search &&
216 (!module_sp || !module_sp->GetSymbolFileFileSpec())) {
218 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
219 module_sp = std::make_shared<Module>(module_spec);
220 }
221 }
222 }
223
224 // If we couldn't find the binary anywhere else, as a last resort,
225 // read it out of memory.
226 if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
227 if (!memory_module_sp)
228 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
229 if (memory_module_sp)
230 module_sp = memory_module_sp;
231 }
232
234 if (module_sp.get()) {
235 // Ensure the Target has an architecture set in case
236 // we need it while processing this binary/eh_frame/debug info.
237 if (!target.GetArchitecture().IsValid())
238 target.SetArchitecture(module_sp->GetArchitecture());
239 target.GetImages().AppendIfNeeded(module_sp, false);
240
241 bool changed = false;
242 if (module_sp->GetObjectFile()) {
243 if (value != LLDB_INVALID_ADDRESS) {
244 LLDB_LOGF(log, "Loading binary UUID %s at %s 0x%" PRIx64,
245 uuid.GetAsString().c_str(),
246 value_is_offset ? "offset" : "address", value);
247 module_sp->SetLoadAddress(target, value, value_is_offset, changed);
248 } else {
249 // No address/offset/slide, load the binary at file address,
250 // offset 0.
251 LLDB_LOGF(log, "Loading binary UUID %s at file address",
252 uuid.GetAsString().c_str());
253 module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
254 changed);
255 }
256 } else {
257 // In-memory image, load at its true address, offset 0.
258 LLDB_LOGF(log, "Loading binary UUID %s from memory at address 0x%" PRIx64,
259 uuid.GetAsString().c_str(), value);
260 module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, changed);
261 }
262
263 if (notify) {
264 ModuleList added_module;
265 added_module.Append(module_sp, false);
266 target.ModulesDidLoad(added_module);
267 }
268 } else {
269 LLDB_LOGF(log, "Unable to find binary with UUID %s and load it at "
270 "%s 0x%" PRIx64,
271 uuid.GetAsString().c_str(),
272 value_is_offset ? "offset" : "address", value);
273 }
274
275 return module_sp;
276}
277
279 int size_in_bytes) {
281 uint64_t value =
282 m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
283 if (error.Fail())
284 return -1;
285 else
286 return (int64_t)value;
287}
288
292 if (error.Fail())
294 else
295 return value;
296}
297
299{
300 if (m_process)
302}
303
static llvm::raw_ostream & error(Stream &strm)
static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr, llvm::StringRef name)
#define LLDB_LOGF(log,...)
Definition: Log.h:344
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:361
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:52
void LoadOperatingSystemPlugin(bool flush)
void SetStopWhenImagesChange(bool stop)
Set whether the process should stop when images change.
static lldb::ModuleSP LoadBinaryWithUUIDAndAddress(Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value, bool value_is_offset, bool force_symbol_search, bool notify)
Find/load a binary into lldb given a UUID and the address where it is loaded in memory,...
int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes)
lldb::addr_t ReadPointer(lldb::addr_t addr)
Process * m_process
The process that this dynamic loader plug-in is tracking.
void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr, bool base_addr_is_offset)
lldb::ModuleSP GetTargetExecutable()
Checks to see if the target module has changed, updates the target accordingly and returns the target...
bool GetStopWhenImagesChange() const
Get whether the process should stop when images change.
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
virtual void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Updates the load address of every allocatable section in module.
DynamicLoader(Process *process)
Construct with a process.
const lldb_private::SectionList * GetSectionListFromModule(const lldb::ModuleSP module) const
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
void UnloadSectionsCommon(const lldb::ModuleSP module)
lldb::ModuleSP FindModuleViaTarget(const FileSpec &file)
virtual void UnloadSections(const lldb::ModuleSP module)
Removes the loaded sections from the target in module.
A file utility class.
Definition: FileSpec.h:56
static FileSystem & Instance()
A collection class for Module objects.
Definition: ModuleList.h:82
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:623
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:62
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:588
static DynamicLoaderCreateInstance GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx)
static DynamicLoaderCreateInstance GetDynamicLoaderCreateCallbackForPluginName(llvm::StringRef name)
void SetStopOnSharedLibraryEvents(bool stop)
Definition: Process.cpp:263
bool GetStopOnSharedLibraryEvents() const
Definition: Process.cpp:257
A plug-in interface definition class for debugging a process.
Definition: Process.h:342
void LoadOperatingSystemPlugin(bool flush)
Definition: Process.cpp:2437
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
Definition: Process.cpp:2067
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2089
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2358
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1219
size_t GetSize() const
Definition: Section.h:74
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:538
An error handling class.
Definition: Status.h:44
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1646
Module * GetExecutableModulePointer()
Definition: Target.cpp:1386
bool SetSectionUnloaded(const lldb::SectionSP &section_sp)
Definition: Target.cpp:3059
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition: Target.cpp:2111
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition: Target.cpp:1488
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1372
lldb::PlatformSP GetPlatform()
Definition: Target.h:1403
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:946
const ArchSpec & GetArchitecture() const
Definition: Target.h:988
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition: Target.cpp:1421
std::string GetAsString(llvm::StringRef separator="-") const
Definition: UUID.cpp:49
bool IsValid() const
Definition: UUID.h:69
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
Definition: SBAddress.h:15
uint64_t addr_t
Definition: lldb-types.h:83