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/Debugger.h"
12#include "lldb/Core/Module.h"
16#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
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
124 UnloadSectionsCommon(module);
125}
126
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 *
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
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 bool set_address_in_target, bool allow_memory_image_last_resort) {
192 ModuleSP memory_module_sp;
193 ModuleSP module_sp;
194 PlatformSP platform_sp = process->GetTarget().GetPlatform();
195 Target &target = process->GetTarget();
197
198 if (!uuid.IsValid() && !value_is_offset) {
199 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
200
201 if (memory_module_sp)
202 uuid = memory_module_sp->GetUUID();
203 }
204 ModuleSpec module_spec;
205 module_spec.GetUUID() = uuid;
206 FileSpec name_filespec(name);
207 if (FileSystem::Instance().Exists(name_filespec))
208 module_spec.GetFileSpec() = name_filespec;
209
210 if (uuid.IsValid()) {
211 // Has lldb already seen a module with this UUID?
212 if (!module_sp)
213 error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
214 nullptr, nullptr);
215
216 // Can lldb's symbol/executable location schemes
217 // find an executable and symbol file.
218 if (!module_sp) {
220 module_spec.GetSymbolFileSpec() =
221 PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
222 ModuleSpec objfile_module_spec =
224 module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
225 if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
227 module_sp = std::make_shared<Module>(module_spec);
228 }
229 }
230
231 // If we haven't found a binary, or we don't have a SymbolFile, see
232 // if there is an external search tool that can find it.
233 if (!module_sp || !module_sp->GetSymbolFileFileSpec()) {
235 force_symbol_search);
236 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
237 module_sp = std::make_shared<Module>(module_spec);
238 } else if (force_symbol_search && error.AsCString("") &&
239 error.AsCString("")[0] != '\0') {
240 target.GetDebugger().GetErrorStream() << error.AsCString();
241 }
242 }
243
244 // If we only found the executable, create a Module based on that.
245 if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec()))
246 module_sp = std::make_shared<Module>(module_spec);
247 }
248
249 // If we couldn't find the binary anywhere else, as a last resort,
250 // read it out of memory.
251 if (allow_memory_image_last_resort && !module_sp.get() &&
252 value != LLDB_INVALID_ADDRESS && !value_is_offset) {
253 if (!memory_module_sp)
254 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
255 if (memory_module_sp)
256 module_sp = memory_module_sp;
257 }
258
260 if (module_sp.get()) {
261 // Ensure the Target has an architecture set in case
262 // we need it while processing this binary/eh_frame/debug info.
263 if (!target.GetArchitecture().IsValid())
264 target.SetArchitecture(module_sp->GetArchitecture());
265 target.GetImages().AppendIfNeeded(module_sp, false);
266
267 bool changed = false;
268 if (set_address_in_target) {
269 if (module_sp->GetObjectFile()) {
270 if (value != LLDB_INVALID_ADDRESS) {
271 LLDB_LOGF(log,
272 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
273 "binary %s UUID %s at %s 0x%" PRIx64,
274 name.str().c_str(), uuid.GetAsString().c_str(),
275 value_is_offset ? "offset" : "address", value);
276 module_sp->SetLoadAddress(target, value, value_is_offset, changed);
277 } else {
278 // No address/offset/slide, load the binary at file address,
279 // offset 0.
280 LLDB_LOGF(log,
281 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
282 "binary %s UUID %s at file address",
283 name.str().c_str(), uuid.GetAsString().c_str());
284 module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
285 changed);
286 }
287 } else {
288 // In-memory image, load at its true address, offset 0.
289 LLDB_LOGF(log,
290 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary "
291 "%s UUID %s from memory at address 0x%" PRIx64,
292 name.str().c_str(), uuid.GetAsString().c_str(), value);
293 module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
294 changed);
295 }
296 }
297
298 if (notify) {
299 ModuleList added_module;
300 added_module.Append(module_sp, false);
301 target.ModulesDidLoad(added_module);
302 }
303 } else {
304 if (force_symbol_search) {
305 Stream &s = target.GetDebugger().GetErrorStream();
306 s.Printf("Unable to find file");
307 if (!name.empty())
308 s.Printf(" %s", name.str().c_str());
309 if (uuid.IsValid())
310 s.Printf(" with UUID %s", uuid.GetAsString().c_str());
311 if (value != LLDB_INVALID_ADDRESS) {
312 if (value_is_offset)
313 s.Printf(" with slide 0x%" PRIx64, value);
314 else
315 s.Printf(" at address 0x%" PRIx64, value);
316 }
317 s.Printf("\n");
318 }
319 LLDB_LOGF(log,
320 "Unable to find binary %s with UUID %s and load it at "
321 "%s 0x%" PRIx64,
322 name.str().c_str(), uuid.GetAsString().c_str(),
323 value_is_offset ? "offset" : "address", value);
324 }
325
326 return module_sp;
327}
328
330 int size_in_bytes) {
332 uint64_t value =
333 m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
334 if (error.Fail())
335 return -1;
336 else
337 return (int64_t)value;
338}
339
343 if (error.Fail())
345 else
346 return value;
347}
348
350{
351 if (m_process)
353}
354
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:349
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:348
StreamFile & GetErrorStream()
Definition: Debugger.h:156
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.
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.
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, bool set_address_in_target, bool allow_memory_image_last_resort)
Find/load a binary into lldb given a UUID and the address where it is loaded in memory,...
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 collection class.
Definition: FileSpecList.h:85
A file utility class.
Definition: FileSpec.h:56
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
A collection class for Module objects.
Definition: ModuleList.h:103
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:626
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Definition: ModuleList.cpp:280
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool always_create=false)
Definition: ModuleList.cpp:789
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
Definition: ModuleList.cpp:247
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:53
FileSpec & GetSymbolFileSpec()
Definition: ModuleSpec.h:77
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
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:590
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec)
static DynamicLoaderCreateInstance GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx)
static DynamicLoaderCreateInstance GetDynamicLoaderCreateCallbackForPluginName(llvm::StringRef name)
static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec, const FileSpecList &default_search_paths)
void SetStopOnSharedLibraryEvents(bool stop)
Definition: Process.cpp:272
bool GetStopOnSharedLibraryEvents() const
Definition: Process.cpp:266
A plug-in interface definition class for debugging a process.
Definition: Process.h:340
void LoadOperatingSystemPlugin(bool flush)
Definition: Process.cpp:2457
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:2079
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2101
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2387
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1276
size_t GetSize() const
Definition: Section.h:75
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:544
An error handling class.
Definition: Status.h:44
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
void ModulesDidLoad(ModuleList &module_list)
Definition: Target.cpp:1697
Module * GetExecutableModulePointer()
Definition: Target.cpp:1436
Debugger & GetDebugger()
Definition: Target.h:1053
bool SetSectionUnloaded(const lldb::SectionSP &section_sp)
Definition: Target.cpp:3177
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:2165
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition: Target.cpp:1538
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1422
static FileSpecList GetDefaultDebugFileSearchPaths()
Definition: Target.cpp:2612
lldb::PlatformSP GetPlatform()
Definition: Target.h:1431
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:970
const ArchSpec & GetArchitecture() const
Definition: Target.h:1012
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition: Target.cpp:1471
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:82
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
DynamicLoader *(* DynamicLoaderCreateInstance)(Process *process, bool force)
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::Platform > PlatformSP
Definition: lldb-forward.h:380
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:406
uint64_t addr_t
Definition: lldb-types.h:79
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:365