15ffd83dbSDimitry Andric //===-- DynamicLoader.cpp -------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "lldb/Target/DynamicLoader.h"
100b57cec5SDimitry Andric
11*c9157d92SDimitry Andric #include "lldb/Core/Debugger.h"
120b57cec5SDimitry Andric #include "lldb/Core/Module.h"
130b57cec5SDimitry Andric #include "lldb/Core/ModuleList.h"
140b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
150b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h"
160b57cec5SDimitry Andric #include "lldb/Core/Section.h"
170b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
180b57cec5SDimitry Andric #include "lldb/Target/MemoryRegionInfo.h"
19bdd1243dSDimitry Andric #include "lldb/Target/Platform.h"
200b57cec5SDimitry Andric #include "lldb/Target/Process.h"
210b57cec5SDimitry Andric #include "lldb/Target/Target.h"
220b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h"
23bdd1243dSDimitry Andric #include "lldb/Utility/LLDBLog.h"
24bdd1243dSDimitry Andric #include "lldb/Utility/Log.h"
250b57cec5SDimitry Andric #include "lldb/lldb-private-interfaces.h"
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric #include <memory>
300b57cec5SDimitry Andric
31fe6060f1SDimitry Andric #include <cassert>
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric using namespace lldb;
340b57cec5SDimitry Andric using namespace lldb_private;
350b57cec5SDimitry Andric
FindPlugin(Process * process,llvm::StringRef plugin_name)360b57cec5SDimitry Andric DynamicLoader *DynamicLoader::FindPlugin(Process *process,
37349cc55cSDimitry Andric llvm::StringRef plugin_name) {
380b57cec5SDimitry Andric DynamicLoaderCreateInstance create_callback = nullptr;
39349cc55cSDimitry Andric if (!plugin_name.empty()) {
400b57cec5SDimitry Andric create_callback =
41349cc55cSDimitry Andric PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name);
420b57cec5SDimitry Andric if (create_callback) {
430b57cec5SDimitry Andric std::unique_ptr<DynamicLoader> instance_up(
440b57cec5SDimitry Andric create_callback(process, true));
450b57cec5SDimitry Andric if (instance_up)
460b57cec5SDimitry Andric return instance_up.release();
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric } else {
490b57cec5SDimitry Andric for (uint32_t idx = 0;
500b57cec5SDimitry Andric (create_callback =
510b57cec5SDimitry Andric PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) !=
520b57cec5SDimitry Andric nullptr;
530b57cec5SDimitry Andric ++idx) {
540b57cec5SDimitry Andric std::unique_ptr<DynamicLoader> instance_up(
550b57cec5SDimitry Andric create_callback(process, false));
560b57cec5SDimitry Andric if (instance_up)
570b57cec5SDimitry Andric return instance_up.release();
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric return nullptr;
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric
DynamicLoader(Process * process)630b57cec5SDimitry Andric DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
640b57cec5SDimitry Andric
65bdd1243dSDimitry Andric // Accessors to the global setting as to whether to stop at image (shared
660b57cec5SDimitry Andric // library) loading/unloading.
670b57cec5SDimitry Andric
GetStopWhenImagesChange() const680b57cec5SDimitry Andric bool DynamicLoader::GetStopWhenImagesChange() const {
690b57cec5SDimitry Andric return m_process->GetStopOnSharedLibraryEvents();
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric
SetStopWhenImagesChange(bool stop)720b57cec5SDimitry Andric void DynamicLoader::SetStopWhenImagesChange(bool stop) {
730b57cec5SDimitry Andric m_process->SetStopOnSharedLibraryEvents(stop);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric
GetTargetExecutable()760b57cec5SDimitry Andric ModuleSP DynamicLoader::GetTargetExecutable() {
770b57cec5SDimitry Andric Target &target = m_process->GetTarget();
780b57cec5SDimitry Andric ModuleSP executable = target.GetExecutableModule();
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric if (executable) {
810b57cec5SDimitry Andric if (FileSystem::Instance().Exists(executable->GetFileSpec())) {
820b57cec5SDimitry Andric ModuleSpec module_spec(executable->GetFileSpec(),
830b57cec5SDimitry Andric executable->GetArchitecture());
840b57cec5SDimitry Andric auto module_sp = std::make_shared<Module>(module_spec);
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric // Check if the executable has changed and set it to the target
870b57cec5SDimitry Andric // executable if they differ.
880b57cec5SDimitry Andric if (module_sp && module_sp->GetUUID().IsValid() &&
890b57cec5SDimitry Andric executable->GetUUID().IsValid()) {
900b57cec5SDimitry Andric if (module_sp->GetUUID() != executable->GetUUID())
910b57cec5SDimitry Andric executable.reset();
920b57cec5SDimitry Andric } else if (executable->FileHasChanged()) {
930b57cec5SDimitry Andric executable.reset();
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric if (!executable) {
970b57cec5SDimitry Andric executable = target.GetOrCreateModule(module_spec, true /* notify */);
980b57cec5SDimitry Andric if (executable.get() != target.GetExecutableModulePointer()) {
990b57cec5SDimitry Andric // Don't load dependent images since we are in dyld where we will
1000b57cec5SDimitry Andric // know and find out about all images that are loaded
1010b57cec5SDimitry Andric target.SetExecutableModule(executable, eLoadDependentsNo);
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric return executable;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric
UpdateLoadedSections(ModuleSP module,addr_t link_map_addr,addr_t base_addr,bool base_addr_is_offset)1090b57cec5SDimitry Andric void DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr,
1100b57cec5SDimitry Andric addr_t base_addr,
1110b57cec5SDimitry Andric bool base_addr_is_offset) {
1120b57cec5SDimitry Andric UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric
UpdateLoadedSectionsCommon(ModuleSP module,addr_t base_addr,bool base_addr_is_offset)1150b57cec5SDimitry Andric void DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
1160b57cec5SDimitry Andric addr_t base_addr,
1170b57cec5SDimitry Andric bool base_addr_is_offset) {
1180b57cec5SDimitry Andric bool changed;
1190b57cec5SDimitry Andric module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset,
1200b57cec5SDimitry Andric changed);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric
UnloadSections(const ModuleSP module)1230b57cec5SDimitry Andric void DynamicLoader::UnloadSections(const ModuleSP module) {
1240b57cec5SDimitry Andric UnloadSectionsCommon(module);
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric
UnloadSectionsCommon(const ModuleSP module)1270b57cec5SDimitry Andric void DynamicLoader::UnloadSectionsCommon(const ModuleSP module) {
1280b57cec5SDimitry Andric Target &target = m_process->GetTarget();
1290b57cec5SDimitry Andric const SectionList *sections = GetSectionListFromModule(module);
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric assert(sections && "SectionList missing from unloaded module.");
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric const size_t num_sections = sections->GetSize();
1340b57cec5SDimitry Andric for (size_t i = 0; i < num_sections; ++i) {
1350b57cec5SDimitry Andric SectionSP section_sp(sections->GetSectionAtIndex(i));
1360b57cec5SDimitry Andric target.SetSectionUnloaded(section_sp);
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andric const SectionList *
GetSectionListFromModule(const ModuleSP module) const1410b57cec5SDimitry Andric DynamicLoader::GetSectionListFromModule(const ModuleSP module) const {
1420b57cec5SDimitry Andric SectionList *sections = nullptr;
1430b57cec5SDimitry Andric if (module) {
1440b57cec5SDimitry Andric ObjectFile *obj_file = module->GetObjectFile();
1450b57cec5SDimitry Andric if (obj_file != nullptr) {
1460b57cec5SDimitry Andric sections = obj_file->GetSectionList();
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric return sections;
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric
FindModuleViaTarget(const FileSpec & file)15281ad6265SDimitry Andric ModuleSP DynamicLoader::FindModuleViaTarget(const FileSpec &file) {
15381ad6265SDimitry Andric Target &target = m_process->GetTarget();
15481ad6265SDimitry Andric ModuleSpec module_spec(file, target.GetArchitecture());
15581ad6265SDimitry Andric
15681ad6265SDimitry Andric if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec))
15781ad6265SDimitry Andric return module_sp;
15881ad6265SDimitry Andric
15981ad6265SDimitry Andric if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false))
16081ad6265SDimitry Andric return module_sp;
16181ad6265SDimitry Andric
16281ad6265SDimitry Andric return nullptr;
16381ad6265SDimitry Andric }
16481ad6265SDimitry Andric
LoadModuleAtAddress(const FileSpec & file,addr_t link_map_addr,addr_t base_addr,bool base_addr_is_offset)1650b57cec5SDimitry Andric ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
1660b57cec5SDimitry Andric addr_t link_map_addr,
1670b57cec5SDimitry Andric addr_t base_addr,
1680b57cec5SDimitry Andric bool base_addr_is_offset) {
16981ad6265SDimitry Andric if (ModuleSP module_sp = FindModuleViaTarget(file)) {
1700b57cec5SDimitry Andric UpdateLoadedSections(module_sp, link_map_addr, base_addr,
1710b57cec5SDimitry Andric base_addr_is_offset);
1720b57cec5SDimitry Andric return module_sp;
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric
17581ad6265SDimitry Andric return nullptr;
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
ReadUnnamedMemoryModule(Process * process,addr_t addr,llvm::StringRef name)178bdd1243dSDimitry Andric static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr,
179bdd1243dSDimitry Andric llvm::StringRef name) {
180bdd1243dSDimitry Andric char namebuf[80];
181bdd1243dSDimitry Andric if (name.empty()) {
182bdd1243dSDimitry Andric snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
183bdd1243dSDimitry Andric name = namebuf;
184bdd1243dSDimitry Andric }
185bdd1243dSDimitry Andric return process->ReadModuleFromMemory(FileSpec(name), addr);
186bdd1243dSDimitry Andric }
187bdd1243dSDimitry Andric
LoadBinaryWithUUIDAndAddress(Process * process,llvm::StringRef name,UUID uuid,addr_t value,bool value_is_offset,bool force_symbol_search,bool notify,bool set_address_in_target,bool allow_memory_image_last_resort)188bdd1243dSDimitry Andric ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
189bdd1243dSDimitry Andric Process *process, llvm::StringRef name, UUID uuid, addr_t value,
190fe013be4SDimitry Andric bool value_is_offset, bool force_symbol_search, bool notify,
191*c9157d92SDimitry Andric bool set_address_in_target, bool allow_memory_image_last_resort) {
192bdd1243dSDimitry Andric ModuleSP memory_module_sp;
193bdd1243dSDimitry Andric ModuleSP module_sp;
194bdd1243dSDimitry Andric PlatformSP platform_sp = process->GetTarget().GetPlatform();
195bdd1243dSDimitry Andric Target &target = process->GetTarget();
196bdd1243dSDimitry Andric Status error;
197bdd1243dSDimitry Andric
198bdd1243dSDimitry Andric if (!uuid.IsValid() && !value_is_offset) {
199bdd1243dSDimitry Andric memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
200bdd1243dSDimitry Andric
201bdd1243dSDimitry Andric if (memory_module_sp)
202bdd1243dSDimitry Andric uuid = memory_module_sp->GetUUID();
203bdd1243dSDimitry Andric }
204bdd1243dSDimitry Andric ModuleSpec module_spec;
205bdd1243dSDimitry Andric module_spec.GetUUID() = uuid;
206fe013be4SDimitry Andric FileSpec name_filespec(name);
207fe013be4SDimitry Andric if (FileSystem::Instance().Exists(name_filespec))
208fe013be4SDimitry Andric module_spec.GetFileSpec() = name_filespec;
209bdd1243dSDimitry Andric
210fe013be4SDimitry Andric if (uuid.IsValid()) {
211fe013be4SDimitry Andric // Has lldb already seen a module with this UUID?
212bdd1243dSDimitry Andric if (!module_sp)
213fe013be4SDimitry Andric error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
214fe013be4SDimitry Andric nullptr, nullptr);
215fe013be4SDimitry Andric
216fe013be4SDimitry Andric // Can lldb's symbol/executable location schemes
217fe013be4SDimitry Andric // find an executable and symbol file.
218fe013be4SDimitry Andric if (!module_sp) {
219fe013be4SDimitry Andric FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
220fe013be4SDimitry Andric module_spec.GetSymbolFileSpec() =
221*c9157d92SDimitry Andric PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
222fe013be4SDimitry Andric ModuleSpec objfile_module_spec =
223*c9157d92SDimitry Andric PluginManager::LocateExecutableObjectFile(module_spec);
224fe013be4SDimitry Andric module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
225fe013be4SDimitry Andric if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
226fe013be4SDimitry Andric FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) {
227fe013be4SDimitry Andric module_sp = std::make_shared<Module>(module_spec);
228fe013be4SDimitry Andric }
229fe013be4SDimitry Andric }
230bdd1243dSDimitry Andric
231bdd1243dSDimitry Andric // If we haven't found a binary, or we don't have a SymbolFile, see
232bdd1243dSDimitry Andric // if there is an external search tool that can find it.
233fe013be4SDimitry Andric if (!module_sp || !module_sp->GetSymbolFileFileSpec()) {
234*c9157d92SDimitry Andric PluginManager::DownloadObjectAndSymbolFile(module_spec, error,
235fe013be4SDimitry Andric force_symbol_search);
236bdd1243dSDimitry Andric if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
237bdd1243dSDimitry Andric module_sp = std::make_shared<Module>(module_spec);
238*c9157d92SDimitry Andric } else if (force_symbol_search && error.AsCString("") &&
239*c9157d92SDimitry Andric error.AsCString("")[0] != '\0') {
240*c9157d92SDimitry Andric target.GetDebugger().GetErrorStream() << error.AsCString();
241bdd1243dSDimitry Andric }
242bdd1243dSDimitry Andric }
243fe013be4SDimitry Andric
244fe013be4SDimitry Andric // If we only found the executable, create a Module based on that.
245fe013be4SDimitry Andric if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec()))
246fe013be4SDimitry Andric module_sp = std::make_shared<Module>(module_spec);
247bdd1243dSDimitry Andric }
248bdd1243dSDimitry Andric
249bdd1243dSDimitry Andric // If we couldn't find the binary anywhere else, as a last resort,
250bdd1243dSDimitry Andric // read it out of memory.
251*c9157d92SDimitry Andric if (allow_memory_image_last_resort && !module_sp.get() &&
252*c9157d92SDimitry Andric value != LLDB_INVALID_ADDRESS && !value_is_offset) {
253bdd1243dSDimitry Andric if (!memory_module_sp)
254bdd1243dSDimitry Andric memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
255bdd1243dSDimitry Andric if (memory_module_sp)
256bdd1243dSDimitry Andric module_sp = memory_module_sp;
257bdd1243dSDimitry Andric }
258bdd1243dSDimitry Andric
259bdd1243dSDimitry Andric Log *log = GetLog(LLDBLog::DynamicLoader);
260bdd1243dSDimitry Andric if (module_sp.get()) {
261bdd1243dSDimitry Andric // Ensure the Target has an architecture set in case
262bdd1243dSDimitry Andric // we need it while processing this binary/eh_frame/debug info.
263bdd1243dSDimitry Andric if (!target.GetArchitecture().IsValid())
264bdd1243dSDimitry Andric target.SetArchitecture(module_sp->GetArchitecture());
265bdd1243dSDimitry Andric target.GetImages().AppendIfNeeded(module_sp, false);
266bdd1243dSDimitry Andric
267bdd1243dSDimitry Andric bool changed = false;
268fe013be4SDimitry Andric if (set_address_in_target) {
269bdd1243dSDimitry Andric if (module_sp->GetObjectFile()) {
270bdd1243dSDimitry Andric if (value != LLDB_INVALID_ADDRESS) {
271fe013be4SDimitry Andric LLDB_LOGF(log,
272fe013be4SDimitry Andric "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
273*c9157d92SDimitry Andric "binary %s UUID %s at %s 0x%" PRIx64,
274*c9157d92SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str(),
275bdd1243dSDimitry Andric value_is_offset ? "offset" : "address", value);
276bdd1243dSDimitry Andric module_sp->SetLoadAddress(target, value, value_is_offset, changed);
277bdd1243dSDimitry Andric } else {
278bdd1243dSDimitry Andric // No address/offset/slide, load the binary at file address,
279bdd1243dSDimitry Andric // offset 0.
280fe013be4SDimitry Andric LLDB_LOGF(log,
281fe013be4SDimitry Andric "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
282*c9157d92SDimitry Andric "binary %s UUID %s at file address",
283*c9157d92SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str());
284bdd1243dSDimitry Andric module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
285bdd1243dSDimitry Andric changed);
286bdd1243dSDimitry Andric }
287bdd1243dSDimitry Andric } else {
288bdd1243dSDimitry Andric // In-memory image, load at its true address, offset 0.
289fe013be4SDimitry Andric LLDB_LOGF(log,
290fe013be4SDimitry Andric "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary "
291*c9157d92SDimitry Andric "%s UUID %s from memory at address 0x%" PRIx64,
292*c9157d92SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str(), value);
293fe013be4SDimitry Andric module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
294fe013be4SDimitry Andric changed);
295fe013be4SDimitry Andric }
296bdd1243dSDimitry Andric }
297bdd1243dSDimitry Andric
298bdd1243dSDimitry Andric if (notify) {
299bdd1243dSDimitry Andric ModuleList added_module;
300bdd1243dSDimitry Andric added_module.Append(module_sp, false);
301bdd1243dSDimitry Andric target.ModulesDidLoad(added_module);
302bdd1243dSDimitry Andric }
303bdd1243dSDimitry Andric } else {
304*c9157d92SDimitry Andric if (force_symbol_search) {
305*c9157d92SDimitry Andric Stream &s = target.GetDebugger().GetErrorStream();
306*c9157d92SDimitry Andric s.Printf("Unable to find file");
307*c9157d92SDimitry Andric if (!name.empty())
308*c9157d92SDimitry Andric s.Printf(" %s", name.str().c_str());
309*c9157d92SDimitry Andric if (uuid.IsValid())
310*c9157d92SDimitry Andric s.Printf(" with UUID %s", uuid.GetAsString().c_str());
311*c9157d92SDimitry Andric if (value != LLDB_INVALID_ADDRESS) {
312*c9157d92SDimitry Andric if (value_is_offset)
313*c9157d92SDimitry Andric s.Printf(" with slide 0x%" PRIx64, value);
314*c9157d92SDimitry Andric else
315*c9157d92SDimitry Andric s.Printf(" at address 0x%" PRIx64, value);
316*c9157d92SDimitry Andric }
317*c9157d92SDimitry Andric s.Printf("\n");
318*c9157d92SDimitry Andric }
319*c9157d92SDimitry Andric LLDB_LOGF(log,
320*c9157d92SDimitry Andric "Unable to find binary %s with UUID %s and load it at "
321bdd1243dSDimitry Andric "%s 0x%" PRIx64,
322*c9157d92SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str(),
323bdd1243dSDimitry Andric value_is_offset ? "offset" : "address", value);
324bdd1243dSDimitry Andric }
325bdd1243dSDimitry Andric
326bdd1243dSDimitry Andric return module_sp;
327bdd1243dSDimitry Andric }
328bdd1243dSDimitry Andric
ReadUnsignedIntWithSizeInBytes(addr_t addr,int size_in_bytes)3290b57cec5SDimitry Andric int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr,
3300b57cec5SDimitry Andric int size_in_bytes) {
3310b57cec5SDimitry Andric Status error;
3320b57cec5SDimitry Andric uint64_t value =
3330b57cec5SDimitry Andric m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
3340b57cec5SDimitry Andric if (error.Fail())
3350b57cec5SDimitry Andric return -1;
3360b57cec5SDimitry Andric else
3370b57cec5SDimitry Andric return (int64_t)value;
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric
ReadPointer(addr_t addr)3400b57cec5SDimitry Andric addr_t DynamicLoader::ReadPointer(addr_t addr) {
3410b57cec5SDimitry Andric Status error;
3420b57cec5SDimitry Andric addr_t value = m_process->ReadPointerFromMemory(addr, error);
3430b57cec5SDimitry Andric if (error.Fail())
3440b57cec5SDimitry Andric return LLDB_INVALID_ADDRESS;
3450b57cec5SDimitry Andric else
3460b57cec5SDimitry Andric return value;
3470b57cec5SDimitry Andric }
3480b57cec5SDimitry Andric
LoadOperatingSystemPlugin(bool flush)3490b57cec5SDimitry Andric void DynamicLoader::LoadOperatingSystemPlugin(bool flush)
3500b57cec5SDimitry Andric {
3510b57cec5SDimitry Andric if (m_process)
3520b57cec5SDimitry Andric m_process->LoadOperatingSystemPlugin(flush);
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric
355