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