DynamicLoader.cpp revision 269024
1//===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/lldb-private.h" 11#include "lldb/Target/DynamicLoader.h" 12#include "lldb/Target/Process.h" 13#include "lldb/Target/Target.h" 14#include "lldb/Core/PluginManager.h" 15#include "lldb/Core/Module.h" 16#include "lldb/Core/ModuleSpec.h" 17#include "lldb/Core/Section.h" 18 19using namespace lldb; 20using namespace lldb_private; 21 22DynamicLoader* 23DynamicLoader::FindPlugin (Process *process, const char *plugin_name) 24{ 25 DynamicLoaderCreateInstance create_callback = NULL; 26 if (plugin_name) 27 { 28 ConstString const_plugin_name(plugin_name); 29 create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name); 30 if (create_callback) 31 { 32 std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true)); 33 if (instance_ap.get()) 34 return instance_ap.release(); 35 } 36 } 37 else 38 { 39 for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx) 40 { 41 std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false)); 42 if (instance_ap.get()) 43 return instance_ap.release(); 44 } 45 } 46 return NULL; 47} 48 49 50//---------------------------------------------------------------------- 51// DynamicLoader constructor 52//---------------------------------------------------------------------- 53DynamicLoader::DynamicLoader(Process *process) : 54 m_process (process) 55{ 56} 57 58//---------------------------------------------------------------------- 59// Destructor 60//---------------------------------------------------------------------- 61DynamicLoader::~DynamicLoader() 62{ 63} 64 65//---------------------------------------------------------------------- 66// Accessosors to the global setting as to whether to stop at image 67// (shared library) loading/unloading. 68//---------------------------------------------------------------------- 69bool 70DynamicLoader::GetStopWhenImagesChange () const 71{ 72 return m_process->GetStopOnSharedLibraryEvents(); 73} 74 75void 76DynamicLoader::SetStopWhenImagesChange (bool stop) 77{ 78 m_process->SetStopOnSharedLibraryEvents (stop); 79} 80 81ModuleSP 82DynamicLoader::GetTargetExecutable() 83{ 84 Target &target = m_process->GetTarget(); 85 ModuleSP executable = target.GetExecutableModule(); 86 87 if (executable.get()) 88 { 89 if (executable->GetFileSpec().Exists()) 90 { 91 ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture()); 92 ModuleSP module_sp (new Module (module_spec)); 93 94 // Check if the executable has changed and set it to the target executable if they differ. 95 if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid()) 96 { 97 if (module_sp->GetUUID() != executable->GetUUID()) 98 executable.reset(); 99 } 100 else if (executable->FileHasChanged()) 101 { 102 executable.reset(); 103 } 104 105 if (!executable.get()) 106 { 107 executable = target.GetSharedModule(module_spec); 108 if (executable.get() != target.GetExecutableModulePointer()) 109 { 110 // Don't load dependent images since we are in dyld where we will know 111 // and find out about all images that are loaded 112 const bool get_dependent_images = false; 113 target.SetExecutableModule(executable, get_dependent_images); 114 } 115 } 116 } 117 } 118 return executable; 119} 120 121void 122DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) 123{ 124 UpdateLoadedSectionsCommon(module, base_addr); 125} 126 127void 128DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr) 129{ 130 bool changed; 131 const bool base_addr_is_offset = true; 132 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); 133} 134 135void 136DynamicLoader::UnloadSections(const ModuleSP module) 137{ 138 UnloadSectionsCommon(module); 139} 140 141void 142DynamicLoader::UnloadSectionsCommon(const ModuleSP module) 143{ 144 Target &target = m_process->GetTarget(); 145 const SectionList *sections = GetSectionListFromModule(module); 146 147 assert(sections && "SectionList missing from unloaded module."); 148 149 const size_t num_sections = sections->GetSize(); 150 for (size_t i = 0; i < num_sections; ++i) 151 { 152 SectionSP section_sp (sections->GetSectionAtIndex(i)); 153 target.SetSectionUnloaded(section_sp); 154 } 155} 156 157 158const SectionList * 159DynamicLoader::GetSectionListFromModule(const ModuleSP module) const 160{ 161 SectionList *sections = nullptr; 162 if (module.get()) 163 { 164 ObjectFile *obj_file = module->GetObjectFile(); 165 if (obj_file) 166 { 167 sections = obj_file->GetSectionList(); 168 } 169 } 170 return sections; 171} 172 173ModuleSP 174DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr) 175{ 176 Target &target = m_process->GetTarget(); 177 ModuleList &modules = target.GetImages(); 178 ModuleSP module_sp; 179 180 ModuleSpec module_spec (file, target.GetArchitecture()); 181 if ((module_sp = modules.FindFirstModule (module_spec))) 182 { 183 UpdateLoadedSections(module_sp, link_map_addr, base_addr); 184 } 185 else if ((module_sp = target.GetSharedModule(module_spec))) 186 { 187 UpdateLoadedSections(module_sp, link_map_addr, base_addr); 188 } 189 190 return module_sp; 191} 192 193int64_t 194DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes) 195{ 196 Error error; 197 198 uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 199 if (error.Fail()) 200 return -1; 201 else 202 return (int64_t)value; 203} 204 205addr_t 206DynamicLoader::ReadPointer(addr_t addr) 207{ 208 Error error; 209 addr_t value = m_process->ReadPointerFromMemory(addr, error); 210 if (error.Fail()) 211 return LLDB_INVALID_ADDRESS; 212 else 213 return value; 214} 215