1254721Semaste//===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-private.h" 11254721Semaste#include "lldb/Target/DynamicLoader.h" 12254721Semaste#include "lldb/Target/Process.h" 13269024Semaste#include "lldb/Target/Target.h" 14254721Semaste#include "lldb/Core/PluginManager.h" 15269024Semaste#include "lldb/Core/Module.h" 16269024Semaste#include "lldb/Core/ModuleSpec.h" 17269024Semaste#include "lldb/Core/Section.h" 18254721Semaste 19254721Semasteusing namespace lldb; 20254721Semasteusing namespace lldb_private; 21254721Semaste 22254721SemasteDynamicLoader* 23254721SemasteDynamicLoader::FindPlugin (Process *process, const char *plugin_name) 24254721Semaste{ 25254721Semaste DynamicLoaderCreateInstance create_callback = NULL; 26254721Semaste if (plugin_name) 27254721Semaste { 28254721Semaste ConstString const_plugin_name(plugin_name); 29254721Semaste create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name); 30254721Semaste if (create_callback) 31254721Semaste { 32254721Semaste std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true)); 33254721Semaste if (instance_ap.get()) 34254721Semaste return instance_ap.release(); 35254721Semaste } 36254721Semaste } 37254721Semaste else 38254721Semaste { 39254721Semaste for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx) 40254721Semaste { 41254721Semaste std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false)); 42254721Semaste if (instance_ap.get()) 43254721Semaste return instance_ap.release(); 44254721Semaste } 45254721Semaste } 46254721Semaste return NULL; 47254721Semaste} 48254721Semaste 49254721Semaste 50254721Semaste//---------------------------------------------------------------------- 51254721Semaste// DynamicLoader constructor 52254721Semaste//---------------------------------------------------------------------- 53254721SemasteDynamicLoader::DynamicLoader(Process *process) : 54254721Semaste m_process (process) 55254721Semaste{ 56254721Semaste} 57254721Semaste 58254721Semaste//---------------------------------------------------------------------- 59254721Semaste// Destructor 60254721Semaste//---------------------------------------------------------------------- 61254721SemasteDynamicLoader::~DynamicLoader() 62254721Semaste{ 63254721Semaste} 64254721Semaste 65254721Semaste//---------------------------------------------------------------------- 66254721Semaste// Accessosors to the global setting as to whether to stop at image 67254721Semaste// (shared library) loading/unloading. 68254721Semaste//---------------------------------------------------------------------- 69254721Semastebool 70254721SemasteDynamicLoader::GetStopWhenImagesChange () const 71254721Semaste{ 72254721Semaste return m_process->GetStopOnSharedLibraryEvents(); 73254721Semaste} 74254721Semaste 75254721Semastevoid 76254721SemasteDynamicLoader::SetStopWhenImagesChange (bool stop) 77254721Semaste{ 78254721Semaste m_process->SetStopOnSharedLibraryEvents (stop); 79254721Semaste} 80254721Semaste 81269024SemasteModuleSP 82269024SemasteDynamicLoader::GetTargetExecutable() 83269024Semaste{ 84269024Semaste Target &target = m_process->GetTarget(); 85269024Semaste ModuleSP executable = target.GetExecutableModule(); 86269024Semaste 87269024Semaste if (executable.get()) 88269024Semaste { 89269024Semaste if (executable->GetFileSpec().Exists()) 90269024Semaste { 91269024Semaste ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture()); 92269024Semaste ModuleSP module_sp (new Module (module_spec)); 93269024Semaste 94269024Semaste // Check if the executable has changed and set it to the target executable if they differ. 95269024Semaste if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid()) 96269024Semaste { 97269024Semaste if (module_sp->GetUUID() != executable->GetUUID()) 98269024Semaste executable.reset(); 99269024Semaste } 100269024Semaste else if (executable->FileHasChanged()) 101269024Semaste { 102269024Semaste executable.reset(); 103269024Semaste } 104269024Semaste 105269024Semaste if (!executable.get()) 106269024Semaste { 107269024Semaste executable = target.GetSharedModule(module_spec); 108269024Semaste if (executable.get() != target.GetExecutableModulePointer()) 109269024Semaste { 110269024Semaste // Don't load dependent images since we are in dyld where we will know 111269024Semaste // and find out about all images that are loaded 112269024Semaste const bool get_dependent_images = false; 113269024Semaste target.SetExecutableModule(executable, get_dependent_images); 114269024Semaste } 115269024Semaste } 116269024Semaste } 117269024Semaste } 118269024Semaste return executable; 119269024Semaste} 120269024Semaste 121269024Semastevoid 122269024SemasteDynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) 123269024Semaste{ 124269024Semaste UpdateLoadedSectionsCommon(module, base_addr); 125269024Semaste} 126269024Semaste 127269024Semastevoid 128269024SemasteDynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr) 129269024Semaste{ 130269024Semaste bool changed; 131269024Semaste const bool base_addr_is_offset = true; 132269024Semaste module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); 133269024Semaste} 134269024Semaste 135269024Semastevoid 136269024SemasteDynamicLoader::UnloadSections(const ModuleSP module) 137269024Semaste{ 138269024Semaste UnloadSectionsCommon(module); 139269024Semaste} 140269024Semaste 141269024Semastevoid 142269024SemasteDynamicLoader::UnloadSectionsCommon(const ModuleSP module) 143269024Semaste{ 144269024Semaste Target &target = m_process->GetTarget(); 145269024Semaste const SectionList *sections = GetSectionListFromModule(module); 146269024Semaste 147269024Semaste assert(sections && "SectionList missing from unloaded module."); 148269024Semaste 149269024Semaste const size_t num_sections = sections->GetSize(); 150269024Semaste for (size_t i = 0; i < num_sections; ++i) 151269024Semaste { 152269024Semaste SectionSP section_sp (sections->GetSectionAtIndex(i)); 153269024Semaste target.SetSectionUnloaded(section_sp); 154269024Semaste } 155269024Semaste} 156269024Semaste 157269024Semaste 158269024Semasteconst SectionList * 159269024SemasteDynamicLoader::GetSectionListFromModule(const ModuleSP module) const 160269024Semaste{ 161269024Semaste SectionList *sections = nullptr; 162269024Semaste if (module.get()) 163269024Semaste { 164269024Semaste ObjectFile *obj_file = module->GetObjectFile(); 165269024Semaste if (obj_file) 166269024Semaste { 167269024Semaste sections = obj_file->GetSectionList(); 168269024Semaste } 169269024Semaste } 170269024Semaste return sections; 171269024Semaste} 172269024Semaste 173269024SemasteModuleSP 174269024SemasteDynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr) 175269024Semaste{ 176269024Semaste Target &target = m_process->GetTarget(); 177269024Semaste ModuleList &modules = target.GetImages(); 178269024Semaste ModuleSP module_sp; 179269024Semaste 180269024Semaste ModuleSpec module_spec (file, target.GetArchitecture()); 181269024Semaste if ((module_sp = modules.FindFirstModule (module_spec))) 182269024Semaste { 183269024Semaste UpdateLoadedSections(module_sp, link_map_addr, base_addr); 184269024Semaste } 185269024Semaste else if ((module_sp = target.GetSharedModule(module_spec))) 186269024Semaste { 187269024Semaste UpdateLoadedSections(module_sp, link_map_addr, base_addr); 188269024Semaste } 189269024Semaste 190269024Semaste return module_sp; 191269024Semaste} 192269024Semaste 193269024Semasteint64_t 194269024SemasteDynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes) 195269024Semaste{ 196269024Semaste Error error; 197269024Semaste 198269024Semaste uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 199269024Semaste if (error.Fail()) 200269024Semaste return -1; 201269024Semaste else 202269024Semaste return (int64_t)value; 203269024Semaste} 204269024Semaste 205269024Semasteaddr_t 206269024SemasteDynamicLoader::ReadPointer(addr_t addr) 207269024Semaste{ 208269024Semaste Error error; 209269024Semaste addr_t value = m_process->ReadPointerFromMemory(addr, error); 210269024Semaste if (error.Fail()) 211269024Semaste return LLDB_INVALID_ADDRESS; 212269024Semaste else 213269024Semaste return value; 214269024Semaste} 215