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, addr_t link_map_addr, addr_t base_addr) 123 { 124 UpdateLoadedSectionsCommon(module, base_addr); 125 } 126 127 void 128 DynamicLoader::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 135 void 136 DynamicLoader::UnloadSections(const ModuleSP module) 137 { 138 UnloadSectionsCommon(module); 139 } 140 141 void 142 DynamicLoader::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 158 const SectionList * 159 DynamicLoader::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 173 ModuleSP 174 DynamicLoader::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 193 int64_t 194 DynamicLoader::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 205 addr_t 206 DynamicLoader::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