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 19 using namespace lldb; 20 using namespace lldb_private; 21 22 DynamicLoader* 23 DynamicLoader::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 //---------------------------------------------------------------------- 53 DynamicLoader::DynamicLoader(Process *process) : 54 m_process (process) 55 { 56 } 57 58 //---------------------------------------------------------------------- 59 // Destructor 60 //---------------------------------------------------------------------- 61 DynamicLoader::~DynamicLoader() 62 { 63 } 64 65 //---------------------------------------------------------------------- 66 // Accessosors to the global setting as to whether to stop at image 67 // (shared library) loading/unloading. 68 //---------------------------------------------------------------------- 69 bool 70 DynamicLoader::GetStopWhenImagesChange () const 71 { 72 return m_process->GetStopOnSharedLibraryEvents(); 73 } 74 75 void 76 DynamicLoader::SetStopWhenImagesChange (bool stop) 77 { 78 m_process->SetStopOnSharedLibraryEvents (stop); 79 } 80 81 ModuleSP 82 DynamicLoader::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 121 void 122 DynamicLoader::UpdateLoadedSections(ModuleSP module, 123 addr_t link_map_addr, 124 addr_t base_addr, 125 bool base_addr_is_offset) 126 { 127 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); 128 } 129 130 void 131 DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, 132 addr_t base_addr, 133 bool base_addr_is_offset) 134 { 135 bool changed; 136 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); 137 } 138 139 void 140 DynamicLoader::UnloadSections(const ModuleSP module) 141 { 142 UnloadSectionsCommon(module); 143 } 144 145 void 146 DynamicLoader::UnloadSectionsCommon(const ModuleSP module) 147 { 148 Target &target = m_process->GetTarget(); 149 const SectionList *sections = GetSectionListFromModule(module); 150 151 assert(sections && "SectionList missing from unloaded module."); 152 153 const size_t num_sections = sections->GetSize(); 154 for (size_t i = 0; i < num_sections; ++i) 155 { 156 SectionSP section_sp (sections->GetSectionAtIndex(i)); 157 target.SetSectionUnloaded(section_sp); 158 } 159 } 160 161 162 const SectionList * 163 DynamicLoader::GetSectionListFromModule(const ModuleSP module) const 164 { 165 SectionList *sections = nullptr; 166 if (module.get()) 167 { 168 ObjectFile *obj_file = module->GetObjectFile(); 169 if (obj_file) 170 { 171 sections = obj_file->GetSectionList(); 172 } 173 } 174 return sections; 175 } 176 177 ModuleSP 178 DynamicLoader::LoadModuleAtAddress(const FileSpec &file, 179 addr_t link_map_addr, 180 addr_t base_addr, 181 bool base_addr_is_offset) 182 { 183 Target &target = m_process->GetTarget(); 184 ModuleList &modules = target.GetImages(); 185 ModuleSP module_sp; 186 187 ModuleSpec module_spec (file, target.GetArchitecture()); 188 if ((module_sp = modules.FindFirstModule (module_spec))) 189 { 190 UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 191 } 192 else if ((module_sp = target.GetSharedModule(module_spec))) 193 { 194 UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 195 } 196 else 197 { 198 if (base_addr_is_offset) 199 { 200 // Try to fetch the load address of the file from the process as we need absolute load 201 // address to read the file out of the memory instead of a load bias. 202 bool is_loaded; 203 lldb::addr_t load_addr; 204 Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); 205 if (error.Success() && is_loaded) 206 base_addr = load_addr; 207 } 208 209 if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) 210 { 211 UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); 212 target.GetImages().AppendIfNeeded(module_sp); 213 } 214 } 215 216 return module_sp; 217 } 218 219 int64_t 220 DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes) 221 { 222 Error error; 223 224 uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 225 if (error.Fail()) 226 return -1; 227 else 228 return (int64_t)value; 229 } 230 231 addr_t 232 DynamicLoader::ReadPointer(addr_t addr) 233 { 234 Error error; 235 addr_t value = m_process->ReadPointerFromMemory(addr, error); 236 if (error.Fail()) 237 return LLDB_INVALID_ADDRESS; 238 else 239 return value; 240 } 241