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/Progress.h"
17#include "lldb/Core/Section.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/Target.h"
25#include "lldb/Utility/Log.h"
27
28#include "llvm/ADT/StringRef.h"
29
30#include <memory>
31
32#include <cassert>
33
34using namespace lldb;
35using namespace lldb_private;
36
38 llvm::StringRef plugin_name) {
39 DynamicLoaderCreateInstance create_callback = nullptr;
40 if (!plugin_name.empty()) {
41 create_callback =
43 if (create_callback) {
44 std::unique_ptr<DynamicLoader> instance_up(
45 create_callback(process, true));
46 if (instance_up)
47 return instance_up.release();
48 }
49 } else {
50 for (uint32_t idx = 0;
51 (create_callback =
53 nullptr;
54 ++idx) {
55 std::unique_ptr<DynamicLoader> instance_up(
56 create_callback(process, false));
57 if (instance_up)
58 return instance_up.release();
59 }
60 }
61 return nullptr;
62}
63
64DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
65
66// Accessors to the global setting as to whether to stop at image (shared
67// library) loading/unloading.
68
71}
72
75}
76
78 Target &target = m_process->GetTarget();
79 ModuleSP executable = target.GetExecutableModule();
80
81 if (executable) {
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
89 return executable;
90 }
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())
96 executable.reset();
97 } else if (executable->FileHasChanged()) {
98 executable.reset();
99 }
100
101 if (!executable) {
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);
107 }
108 }
109 }
110 }
111 return executable;
112}
113
115 addr_t base_addr,
116 bool base_addr_is_offset) {
117 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
118}
119
121 addr_t base_addr,
122 bool base_addr_is_offset) {
123 bool changed;
124 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset,
125 changed);
126}
127
129 UnloadSectionsCommon(module);
130}
131
133 Target &target = m_process->GetTarget();
134 const SectionList *sections = GetSectionListFromModule(module);
135
136 assert(sections && "SectionList missing from unloaded module.");
137
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);
142 }
143}
144
145const SectionList *
147 SectionList *sections = nullptr;
148 if (module) {
149 ObjectFile *obj_file = module->GetObjectFile();
150 if (obj_file != nullptr) {
151 sections = obj_file->GetSectionList();
152 }
153 }
154 return sections;
155}
156
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;
163 }
164
165 if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec))
166 return module_sp;
167
168 if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false))
169 return module_sp;
170
171 return nullptr;
172}
173
175 addr_t link_map_addr,
176 addr_t base_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);
181 return module_sp;
182 }
183
184 return nullptr;
185}
186
188 llvm::StringRef name) {
189 char namebuf[80];
190 if (name.empty()) {
191 snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
192 name = namebuf;
193 }
194 return process->ReadModuleFromMemory(FileSpec(name), addr);
195}
196
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;
202 ModuleSP module_sp;
203 PlatformSP platform_sp = process->GetTarget().GetPlatform();
204 Target &target = process->GetTarget();
206
207 StreamString prog_str;
208 if (!name.empty()) {
209 prog_str << name.str() << " ";
210 }
211 if (uuid.IsValid())
212 prog_str << uuid.GetAsString();
213 if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
214 prog_str << "at 0x";
215 prog_str.PutHex64(value);
216 }
217
218 if (!uuid.IsValid() && !value_is_offset) {
219 memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
220
221 if (memory_module_sp) {
222 uuid = memory_module_sp->GetUUID();
223 if (uuid.IsValid()) {
224 prog_str << " ";
225 prog_str << uuid.GetAsString();
226 }
227 }
228 }
229 ModuleSpec module_spec;
230 module_spec.GetUUID() = uuid;
231 FileSpec name_filespec(name);
232
233 if (uuid.IsValid()) {
234 Progress progress("Locating binary", prog_str.GetString().str());
235
236 // Has lldb already seen a module with this UUID?
237 // Or have external lookup enabled in DebugSymbols on macOS.
238 if (!module_sp)
239 error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
240 nullptr, nullptr);
241
242 // Can lldb's symbol/executable location schemes
243 // find an executable and symbol file.
244 if (!module_sp) {
246 module_spec.GetSymbolFileSpec() =
247 PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
248 ModuleSpec objfile_module_spec =
250 module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
251 if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
253 module_sp = std::make_shared<Module>(module_spec);
254 }
255 }
256
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()) {
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();
267 }
268 }
269
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);
273 }
274
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;
283 }
284
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);
292
293 bool changed = false;
294 if (set_address_in_target) {
295 if (module_sp->GetObjectFile()) {
296 if (value != LLDB_INVALID_ADDRESS) {
297 LLDB_LOGF(log,
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);
303 } else {
304 // No address/offset/slide, load the binary at file address,
305 // offset 0.
306 LLDB_LOGF(log,
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 */,
311 changed);
312 }
313 } else {
314 // In-memory image, load at its true address, offset 0.
315 LLDB_LOGF(log,
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 */,
320 changed);
321 }
322 }
323
324 if (notify) {
325 ModuleList added_module;
326 added_module.Append(module_sp, false);
327 target.ModulesDidLoad(added_module);
328 }
329 } else {
330 if (force_symbol_search) {
331 Stream &s = target.GetDebugger().GetErrorStream();
332 s.Printf("Unable to find file");
333 if (!name.empty())
334 s.Printf(" %s", name.str().c_str());
335 if (uuid.IsValid())
336 s.Printf(" with UUID %s", uuid.GetAsString().c_str());
337 if (value != LLDB_INVALID_ADDRESS) {
338 if (value_is_offset)
339 s.Printf(" with slide 0x%" PRIx64, value);
340 else
341 s.Printf(" at address 0x%" PRIx64, value);
342 }
343 s.Printf("\n");
344 }
345 LLDB_LOGF(log,
346 "Unable to find binary %s with UUID %s and load it at "
347 "%s 0x%" PRIx64,
348 name.str().c_str(), uuid.GetAsString().c_str(),
349 value_is_offset ? "offset" : "address", value);
350 }
351
352 return module_sp;
353}
354
356 int size_in_bytes) {
358 uint64_t value =
359 m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
360 if (error.Fail())
361 return -1;
362 else
363 return (int64_t)value;
364}
365
369 if (error.Fail())
371 else
372 return value;
373}
374
376{
377 if (m_process)
379}
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:376
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:359
StreamFile & GetErrorStream()
Definition: Debugger.h:148
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:54
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:91
A file utility class.
Definition: FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
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:602
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:275
bool GetStopOnSharedLibraryEvents() const
Definition: Process.cpp:269
A plug-in interface definition class for debugging a process.
Definition: Process.h:343
void LoadOperatingSystemPlugin(bool flush)
Definition: Process.cpp:2605
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:2217
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2239
virtual lldb_private::UUID FindModuleUUID(const llvm::StringRef path)
Definition: Process.cpp:6084
virtual bool IsLiveDebugSession() const
Definition: Process.h:1494
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2527
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1246
A Progress indicator helper class.
Definition: Progress.h:60
size_t GetSize() const
Definition: Section.h:75
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:550
An error handling class.
Definition: Status.h:118
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t PutHex64(uint64_t uvalue, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition: Stream.cpp:299
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:1814
Module * GetExecutableModulePointer()
Definition: Target.cpp:1518
Debugger & GetDebugger()
Definition: Target.h:1080
bool SetSectionUnloaded(const lldb::SectionSP &section_sp)
Definition: Target.cpp:3278
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:2286
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition: Target.cpp:1662
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1504
static FileSpecList GetDefaultDebugFileSearchPaths()
Definition: Target.cpp:2741
lldb::PlatformSP GetPlatform()
Definition: Target.h:1463
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:997
const ArchSpec & GetArchitecture() const
Definition: Target.h:1039
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition: Target.cpp:1553
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.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:332
DynamicLoader *(* DynamicLoaderCreateInstance)(Process *process, bool force)
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::Platform > PlatformSP
Definition: lldb-forward.h:388
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:418
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373