1cfca06d7SDimitry Andric //===-- DynamicLoader.cpp -------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/Target/DynamicLoader.h"
1074a628f7SDimitry Andric
11b1c73532SDimitry Andric #include "lldb/Core/Debugger.h"
12866dcdacSEd Maste #include "lldb/Core/Module.h"
1394994d37SDimitry Andric #include "lldb/Core/ModuleList.h"
14866dcdacSEd Maste #include "lldb/Core/ModuleSpec.h"
1514f1b3e8SDimitry Andric #include "lldb/Core/PluginManager.h"
16ac9a064cSDimitry Andric #include "lldb/Core/Progress.h"
17866dcdacSEd Maste #include "lldb/Core/Section.h"
1894994d37SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
1914f1b3e8SDimitry Andric #include "lldb/Target/MemoryRegionInfo.h"
20e3b55780SDimitry Andric #include "lldb/Target/Platform.h"
2114f1b3e8SDimitry Andric #include "lldb/Target/Process.h"
2214f1b3e8SDimitry Andric #include "lldb/Target/Target.h"
2394994d37SDimitry Andric #include "lldb/Utility/ConstString.h"
24e3b55780SDimitry Andric #include "lldb/Utility/LLDBLog.h"
25e3b55780SDimitry Andric #include "lldb/Utility/Log.h"
2694994d37SDimitry Andric #include "lldb/lldb-private-interfaces.h"
2774a628f7SDimitry Andric
2894994d37SDimitry Andric #include "llvm/ADT/StringRef.h"
2974a628f7SDimitry Andric
3094994d37SDimitry Andric #include <memory>
3174a628f7SDimitry Andric
32344a3780SDimitry Andric #include <cassert>
33f034231aSEd Maste
34f034231aSEd Maste using namespace lldb;
35f034231aSEd Maste using namespace lldb_private;
36f034231aSEd Maste
FindPlugin(Process * process,llvm::StringRef plugin_name)3714f1b3e8SDimitry Andric DynamicLoader *DynamicLoader::FindPlugin(Process *process,
38c0981da4SDimitry Andric llvm::StringRef plugin_name) {
39f3fbd1c0SDimitry Andric DynamicLoaderCreateInstance create_callback = nullptr;
40c0981da4SDimitry Andric if (!plugin_name.empty()) {
4114f1b3e8SDimitry Andric create_callback =
42c0981da4SDimitry Andric PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name);
4314f1b3e8SDimitry Andric if (create_callback) {
445f29bb8aSDimitry Andric std::unique_ptr<DynamicLoader> instance_up(
4514f1b3e8SDimitry Andric create_callback(process, true));
465f29bb8aSDimitry Andric if (instance_up)
475f29bb8aSDimitry Andric return instance_up.release();
48f034231aSEd Maste }
4914f1b3e8SDimitry Andric } else {
5014f1b3e8SDimitry Andric for (uint32_t idx = 0;
5114f1b3e8SDimitry Andric (create_callback =
5214f1b3e8SDimitry Andric PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) !=
5314f1b3e8SDimitry Andric nullptr;
5414f1b3e8SDimitry Andric ++idx) {
555f29bb8aSDimitry Andric std::unique_ptr<DynamicLoader> instance_up(
5614f1b3e8SDimitry Andric create_callback(process, false));
575f29bb8aSDimitry Andric if (instance_up)
585f29bb8aSDimitry Andric return instance_up.release();
59f034231aSEd Maste }
60f034231aSEd Maste }
61f3fbd1c0SDimitry Andric return nullptr;
62f034231aSEd Maste }
63f034231aSEd Maste
DynamicLoader(Process * process)6414f1b3e8SDimitry Andric DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
65f034231aSEd Maste
66e3b55780SDimitry Andric // Accessors to the global setting as to whether to stop at image (shared
67f73363f1SDimitry Andric // library) loading/unloading.
68f3fbd1c0SDimitry Andric
GetStopWhenImagesChange() const6914f1b3e8SDimitry Andric bool DynamicLoader::GetStopWhenImagesChange() const {
70f034231aSEd Maste return m_process->GetStopOnSharedLibraryEvents();
71f034231aSEd Maste }
72f034231aSEd Maste
SetStopWhenImagesChange(bool stop)7314f1b3e8SDimitry Andric void DynamicLoader::SetStopWhenImagesChange(bool stop) {
74f034231aSEd Maste m_process->SetStopOnSharedLibraryEvents(stop);
75f034231aSEd Maste }
76f034231aSEd Maste
GetTargetExecutable()7714f1b3e8SDimitry Andric ModuleSP DynamicLoader::GetTargetExecutable() {
78866dcdacSEd Maste Target &target = m_process->GetTarget();
79866dcdacSEd Maste ModuleSP executable = target.GetExecutableModule();
80866dcdacSEd Maste
8114f1b3e8SDimitry Andric if (executable) {
8294994d37SDimitry Andric if (FileSystem::Instance().Exists(executable->GetFileSpec())) {
8314f1b3e8SDimitry Andric ModuleSpec module_spec(executable->GetFileSpec(),
8414f1b3e8SDimitry Andric executable->GetArchitecture());
8574a628f7SDimitry Andric auto module_sp = std::make_shared<Module>(module_spec);
86866dcdacSEd Maste
87f73363f1SDimitry Andric // Check if the executable has changed and set it to the target
88f73363f1SDimitry Andric // executable if they differ.
8914f1b3e8SDimitry Andric if (module_sp && module_sp->GetUUID().IsValid() &&
9014f1b3e8SDimitry Andric executable->GetUUID().IsValid()) {
91866dcdacSEd Maste if (module_sp->GetUUID() != executable->GetUUID())
92866dcdacSEd Maste executable.reset();
9314f1b3e8SDimitry Andric } else if (executable->FileHasChanged()) {
94866dcdacSEd Maste executable.reset();
95866dcdacSEd Maste }
96866dcdacSEd Maste
9714f1b3e8SDimitry Andric if (!executable) {
985f29bb8aSDimitry Andric executable = target.GetOrCreateModule(module_spec, true /* notify */);
9914f1b3e8SDimitry Andric if (executable.get() != target.GetExecutableModulePointer()) {
100f73363f1SDimitry Andric // Don't load dependent images since we are in dyld where we will
101f73363f1SDimitry Andric // know and find out about all images that are loaded
10294994d37SDimitry Andric target.SetExecutableModule(executable, eLoadDependentsNo);
103866dcdacSEd Maste }
104866dcdacSEd Maste }
105866dcdacSEd Maste }
106866dcdacSEd Maste }
107866dcdacSEd Maste return executable;
108866dcdacSEd Maste }
109866dcdacSEd Maste
UpdateLoadedSections(ModuleSP module,addr_t link_map_addr,addr_t base_addr,bool base_addr_is_offset)11014f1b3e8SDimitry Andric void DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr,
111e81d9d49SDimitry Andric addr_t base_addr,
11214f1b3e8SDimitry Andric bool base_addr_is_offset) {
113e81d9d49SDimitry Andric UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
114866dcdacSEd Maste }
115866dcdacSEd Maste
UpdateLoadedSectionsCommon(ModuleSP module,addr_t base_addr,bool base_addr_is_offset)11614f1b3e8SDimitry Andric void DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
117e81d9d49SDimitry Andric addr_t base_addr,
11814f1b3e8SDimitry Andric bool base_addr_is_offset) {
119866dcdacSEd Maste bool changed;
12014f1b3e8SDimitry Andric module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset,
12114f1b3e8SDimitry Andric changed);
122866dcdacSEd Maste }
123866dcdacSEd Maste
UnloadSections(const ModuleSP module)12414f1b3e8SDimitry Andric void DynamicLoader::UnloadSections(const ModuleSP module) {
125866dcdacSEd Maste UnloadSectionsCommon(module);
126866dcdacSEd Maste }
127866dcdacSEd Maste
UnloadSectionsCommon(const ModuleSP module)12814f1b3e8SDimitry Andric void DynamicLoader::UnloadSectionsCommon(const ModuleSP module) {
129866dcdacSEd Maste Target &target = m_process->GetTarget();
130866dcdacSEd Maste const SectionList *sections = GetSectionListFromModule(module);
131866dcdacSEd Maste
132866dcdacSEd Maste assert(sections && "SectionList missing from unloaded module.");
133866dcdacSEd Maste
134866dcdacSEd Maste const size_t num_sections = sections->GetSize();
13514f1b3e8SDimitry Andric for (size_t i = 0; i < num_sections; ++i) {
136866dcdacSEd Maste SectionSP section_sp(sections->GetSectionAtIndex(i));
137866dcdacSEd Maste target.SetSectionUnloaded(section_sp);
138866dcdacSEd Maste }
139866dcdacSEd Maste }
140866dcdacSEd Maste
141866dcdacSEd Maste const SectionList *
GetSectionListFromModule(const ModuleSP module) const14214f1b3e8SDimitry Andric DynamicLoader::GetSectionListFromModule(const ModuleSP module) const {
143866dcdacSEd Maste SectionList *sections = nullptr;
14414f1b3e8SDimitry Andric if (module) {
145866dcdacSEd Maste ObjectFile *obj_file = module->GetObjectFile();
14614f1b3e8SDimitry Andric if (obj_file != nullptr) {
147866dcdacSEd Maste sections = obj_file->GetSectionList();
148866dcdacSEd Maste }
149866dcdacSEd Maste }
150866dcdacSEd Maste return sections;
151866dcdacSEd Maste }
152866dcdacSEd Maste
FindModuleViaTarget(const FileSpec & file)153145449b1SDimitry Andric ModuleSP DynamicLoader::FindModuleViaTarget(const FileSpec &file) {
154145449b1SDimitry Andric Target &target = m_process->GetTarget();
155145449b1SDimitry Andric ModuleSpec module_spec(file, target.GetArchitecture());
156145449b1SDimitry Andric
157145449b1SDimitry Andric if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec))
158145449b1SDimitry Andric return module_sp;
159145449b1SDimitry Andric
160145449b1SDimitry Andric if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false))
161145449b1SDimitry Andric return module_sp;
162145449b1SDimitry Andric
163145449b1SDimitry Andric return nullptr;
164145449b1SDimitry Andric }
165145449b1SDimitry Andric
LoadModuleAtAddress(const FileSpec & file,addr_t link_map_addr,addr_t base_addr,bool base_addr_is_offset)16614f1b3e8SDimitry Andric ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
167e81d9d49SDimitry Andric addr_t link_map_addr,
168e81d9d49SDimitry Andric addr_t base_addr,
16914f1b3e8SDimitry Andric bool base_addr_is_offset) {
170145449b1SDimitry Andric if (ModuleSP module_sp = FindModuleViaTarget(file)) {
17114f1b3e8SDimitry Andric UpdateLoadedSections(module_sp, link_map_addr, base_addr,
17214f1b3e8SDimitry Andric base_addr_is_offset);
17314f1b3e8SDimitry Andric return module_sp;
174866dcdacSEd Maste }
17514f1b3e8SDimitry Andric
176145449b1SDimitry Andric return nullptr;
177866dcdacSEd Maste }
178866dcdacSEd Maste
ReadUnnamedMemoryModule(Process * process,addr_t addr,llvm::StringRef name)179e3b55780SDimitry Andric static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr,
180e3b55780SDimitry Andric llvm::StringRef name) {
181e3b55780SDimitry Andric char namebuf[80];
182e3b55780SDimitry Andric if (name.empty()) {
183e3b55780SDimitry Andric snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
184e3b55780SDimitry Andric name = namebuf;
185e3b55780SDimitry Andric }
186e3b55780SDimitry Andric return process->ReadModuleFromMemory(FileSpec(name), addr);
187e3b55780SDimitry Andric }
188e3b55780SDimitry 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)189e3b55780SDimitry Andric ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
190e3b55780SDimitry Andric Process *process, llvm::StringRef name, UUID uuid, addr_t value,
1917fa27ce4SDimitry Andric bool value_is_offset, bool force_symbol_search, bool notify,
192b1c73532SDimitry Andric bool set_address_in_target, bool allow_memory_image_last_resort) {
193e3b55780SDimitry Andric ModuleSP memory_module_sp;
194e3b55780SDimitry Andric ModuleSP module_sp;
195e3b55780SDimitry Andric PlatformSP platform_sp = process->GetTarget().GetPlatform();
196e3b55780SDimitry Andric Target &target = process->GetTarget();
197e3b55780SDimitry Andric Status error;
198e3b55780SDimitry Andric
199ac9a064cSDimitry Andric StreamString prog_str;
200ac9a064cSDimitry Andric if (!name.empty()) {
201ac9a064cSDimitry Andric prog_str << name.str() << " ";
202ac9a064cSDimitry Andric }
203ac9a064cSDimitry Andric if (uuid.IsValid())
204ac9a064cSDimitry Andric prog_str << uuid.GetAsString();
205ac9a064cSDimitry Andric if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) {
206ac9a064cSDimitry Andric prog_str << "at 0x";
207ac9a064cSDimitry Andric prog_str.PutHex64(value);
208ac9a064cSDimitry Andric }
209ac9a064cSDimitry Andric
210e3b55780SDimitry Andric if (!uuid.IsValid() && !value_is_offset) {
211e3b55780SDimitry Andric memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
212e3b55780SDimitry Andric
213ac9a064cSDimitry Andric if (memory_module_sp) {
214e3b55780SDimitry Andric uuid = memory_module_sp->GetUUID();
215ac9a064cSDimitry Andric if (uuid.IsValid()) {
216ac9a064cSDimitry Andric prog_str << " ";
217ac9a064cSDimitry Andric prog_str << uuid.GetAsString();
218ac9a064cSDimitry Andric }
219ac9a064cSDimitry Andric }
220e3b55780SDimitry Andric }
221e3b55780SDimitry Andric ModuleSpec module_spec;
222e3b55780SDimitry Andric module_spec.GetUUID() = uuid;
2237fa27ce4SDimitry Andric FileSpec name_filespec(name);
224e3b55780SDimitry Andric
2257fa27ce4SDimitry Andric if (uuid.IsValid()) {
226ac9a064cSDimitry Andric Progress progress("Locating binary", prog_str.GetString().str());
227ac9a064cSDimitry Andric
2287fa27ce4SDimitry Andric // Has lldb already seen a module with this UUID?
229ac9a064cSDimitry Andric // Or have external lookup enabled in DebugSymbols on macOS.
230e3b55780SDimitry Andric if (!module_sp)
2317fa27ce4SDimitry Andric error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
2327fa27ce4SDimitry Andric nullptr, nullptr);
2337fa27ce4SDimitry Andric
2347fa27ce4SDimitry Andric // Can lldb's symbol/executable location schemes
2357fa27ce4SDimitry Andric // find an executable and symbol file.
2367fa27ce4SDimitry Andric if (!module_sp) {
2377fa27ce4SDimitry Andric FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
2387fa27ce4SDimitry Andric module_spec.GetSymbolFileSpec() =
239b1c73532SDimitry Andric PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
2407fa27ce4SDimitry Andric ModuleSpec objfile_module_spec =
241b1c73532SDimitry Andric PluginManager::LocateExecutableObjectFile(module_spec);
2427fa27ce4SDimitry Andric module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
2437fa27ce4SDimitry Andric if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
2447fa27ce4SDimitry Andric FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) {
2457fa27ce4SDimitry Andric module_sp = std::make_shared<Module>(module_spec);
2467fa27ce4SDimitry Andric }
2477fa27ce4SDimitry Andric }
248e3b55780SDimitry Andric
249e3b55780SDimitry Andric // If we haven't found a binary, or we don't have a SymbolFile, see
250e3b55780SDimitry Andric // if there is an external search tool that can find it.
2517fa27ce4SDimitry Andric if (!module_sp || !module_sp->GetSymbolFileFileSpec()) {
252b1c73532SDimitry Andric PluginManager::DownloadObjectAndSymbolFile(module_spec, error,
2537fa27ce4SDimitry Andric force_symbol_search);
254e3b55780SDimitry Andric if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
255e3b55780SDimitry Andric module_sp = std::make_shared<Module>(module_spec);
256b1c73532SDimitry Andric } else if (force_symbol_search && error.AsCString("") &&
257b1c73532SDimitry Andric error.AsCString("")[0] != '\0') {
258b1c73532SDimitry Andric target.GetDebugger().GetErrorStream() << error.AsCString();
259e3b55780SDimitry Andric }
260e3b55780SDimitry Andric }
2617fa27ce4SDimitry Andric
2627fa27ce4SDimitry Andric // If we only found the executable, create a Module based on that.
2637fa27ce4SDimitry Andric if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec()))
2647fa27ce4SDimitry Andric module_sp = std::make_shared<Module>(module_spec);
265e3b55780SDimitry Andric }
266e3b55780SDimitry Andric
267e3b55780SDimitry Andric // If we couldn't find the binary anywhere else, as a last resort,
268e3b55780SDimitry Andric // read it out of memory.
269b1c73532SDimitry Andric if (allow_memory_image_last_resort && !module_sp.get() &&
270b1c73532SDimitry Andric value != LLDB_INVALID_ADDRESS && !value_is_offset) {
271e3b55780SDimitry Andric if (!memory_module_sp)
272e3b55780SDimitry Andric memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
273e3b55780SDimitry Andric if (memory_module_sp)
274e3b55780SDimitry Andric module_sp = memory_module_sp;
275e3b55780SDimitry Andric }
276e3b55780SDimitry Andric
277e3b55780SDimitry Andric Log *log = GetLog(LLDBLog::DynamicLoader);
278e3b55780SDimitry Andric if (module_sp.get()) {
279e3b55780SDimitry Andric // Ensure the Target has an architecture set in case
280e3b55780SDimitry Andric // we need it while processing this binary/eh_frame/debug info.
281e3b55780SDimitry Andric if (!target.GetArchitecture().IsValid())
282e3b55780SDimitry Andric target.SetArchitecture(module_sp->GetArchitecture());
283e3b55780SDimitry Andric target.GetImages().AppendIfNeeded(module_sp, false);
284e3b55780SDimitry Andric
285e3b55780SDimitry Andric bool changed = false;
2867fa27ce4SDimitry Andric if (set_address_in_target) {
287e3b55780SDimitry Andric if (module_sp->GetObjectFile()) {
288e3b55780SDimitry Andric if (value != LLDB_INVALID_ADDRESS) {
2897fa27ce4SDimitry Andric LLDB_LOGF(log,
2907fa27ce4SDimitry Andric "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
291b1c73532SDimitry Andric "binary %s UUID %s at %s 0x%" PRIx64,
292b1c73532SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str(),
293e3b55780SDimitry Andric value_is_offset ? "offset" : "address", value);
294e3b55780SDimitry Andric module_sp->SetLoadAddress(target, value, value_is_offset, changed);
295e3b55780SDimitry Andric } else {
296e3b55780SDimitry Andric // No address/offset/slide, load the binary at file address,
297e3b55780SDimitry Andric // offset 0.
2987fa27ce4SDimitry Andric LLDB_LOGF(log,
2997fa27ce4SDimitry Andric "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading "
300b1c73532SDimitry Andric "binary %s UUID %s at file address",
301b1c73532SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str());
302e3b55780SDimitry Andric module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
303e3b55780SDimitry Andric changed);
304e3b55780SDimitry Andric }
305e3b55780SDimitry Andric } else {
306e3b55780SDimitry Andric // In-memory image, load at its true address, offset 0.
3077fa27ce4SDimitry Andric LLDB_LOGF(log,
3087fa27ce4SDimitry Andric "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary "
309b1c73532SDimitry Andric "%s UUID %s from memory at address 0x%" PRIx64,
310b1c73532SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str(), value);
3117fa27ce4SDimitry Andric module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
3127fa27ce4SDimitry Andric changed);
3137fa27ce4SDimitry Andric }
314e3b55780SDimitry Andric }
315e3b55780SDimitry Andric
316e3b55780SDimitry Andric if (notify) {
317e3b55780SDimitry Andric ModuleList added_module;
318e3b55780SDimitry Andric added_module.Append(module_sp, false);
319e3b55780SDimitry Andric target.ModulesDidLoad(added_module);
320e3b55780SDimitry Andric }
321e3b55780SDimitry Andric } else {
322b1c73532SDimitry Andric if (force_symbol_search) {
323b1c73532SDimitry Andric Stream &s = target.GetDebugger().GetErrorStream();
324b1c73532SDimitry Andric s.Printf("Unable to find file");
325b1c73532SDimitry Andric if (!name.empty())
326b1c73532SDimitry Andric s.Printf(" %s", name.str().c_str());
327b1c73532SDimitry Andric if (uuid.IsValid())
328b1c73532SDimitry Andric s.Printf(" with UUID %s", uuid.GetAsString().c_str());
329b1c73532SDimitry Andric if (value != LLDB_INVALID_ADDRESS) {
330b1c73532SDimitry Andric if (value_is_offset)
331b1c73532SDimitry Andric s.Printf(" with slide 0x%" PRIx64, value);
332b1c73532SDimitry Andric else
333b1c73532SDimitry Andric s.Printf(" at address 0x%" PRIx64, value);
334b1c73532SDimitry Andric }
335b1c73532SDimitry Andric s.Printf("\n");
336b1c73532SDimitry Andric }
337b1c73532SDimitry Andric LLDB_LOGF(log,
338b1c73532SDimitry Andric "Unable to find binary %s with UUID %s and load it at "
339e3b55780SDimitry Andric "%s 0x%" PRIx64,
340b1c73532SDimitry Andric name.str().c_str(), uuid.GetAsString().c_str(),
341e3b55780SDimitry Andric value_is_offset ? "offset" : "address", value);
342e3b55780SDimitry Andric }
343e3b55780SDimitry Andric
344e3b55780SDimitry Andric return module_sp;
345e3b55780SDimitry Andric }
346e3b55780SDimitry Andric
ReadUnsignedIntWithSizeInBytes(addr_t addr,int size_in_bytes)34714f1b3e8SDimitry Andric int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr,
34814f1b3e8SDimitry Andric int size_in_bytes) {
349b76161e4SDimitry Andric Status error;
35014f1b3e8SDimitry Andric uint64_t value =
35114f1b3e8SDimitry Andric m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
352866dcdacSEd Maste if (error.Fail())
353866dcdacSEd Maste return -1;
354866dcdacSEd Maste else
355866dcdacSEd Maste return (int64_t)value;
356866dcdacSEd Maste }
357866dcdacSEd Maste
ReadPointer(addr_t addr)35814f1b3e8SDimitry Andric addr_t DynamicLoader::ReadPointer(addr_t addr) {
359b76161e4SDimitry Andric Status error;
360866dcdacSEd Maste addr_t value = m_process->ReadPointerFromMemory(addr, error);
361866dcdacSEd Maste if (error.Fail())
362866dcdacSEd Maste return LLDB_INVALID_ADDRESS;
363866dcdacSEd Maste else
364866dcdacSEd Maste return value;
365866dcdacSEd Maste }
36674a628f7SDimitry Andric
LoadOperatingSystemPlugin(bool flush)36774a628f7SDimitry Andric void DynamicLoader::LoadOperatingSystemPlugin(bool flush)
36874a628f7SDimitry Andric {
36974a628f7SDimitry Andric if (m_process)
37074a628f7SDimitry Andric m_process->LoadOperatingSystemPlugin(flush);
37174a628f7SDimitry Andric }
37274a628f7SDimitry Andric
373