130fdc8d8SChris Lattner //===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 10*34ede34aSEugene Zelenko // C Includes 11*34ede34aSEugene Zelenko // C++ Includes 12*34ede34aSEugene Zelenko // Other libraries and framework includes 13*34ede34aSEugene Zelenko // Project includes 1430fdc8d8SChris Lattner #include "lldb/lldb-private.h" 1530fdc8d8SChris Lattner #include "lldb/Target/DynamicLoader.h" 162995077dSJim Ingham #include "lldb/Target/Process.h" 179e02dacdSSteve Pucci #include "lldb/Target/Target.h" 1830fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h" 199e02dacdSSteve Pucci #include "lldb/Core/Module.h" 209e02dacdSSteve Pucci #include "lldb/Core/ModuleSpec.h" 219e02dacdSSteve Pucci #include "lldb/Core/Section.h" 2230fdc8d8SChris Lattner 2330fdc8d8SChris Lattner using namespace lldb; 2430fdc8d8SChris Lattner using namespace lldb_private; 2530fdc8d8SChris Lattner 2630fdc8d8SChris Lattner DynamicLoader* 2730fdc8d8SChris Lattner DynamicLoader::FindPlugin (Process *process, const char *plugin_name) 2830fdc8d8SChris Lattner { 29*34ede34aSEugene Zelenko DynamicLoaderCreateInstance create_callback = nullptr; 3030fdc8d8SChris Lattner if (plugin_name) 3130fdc8d8SChris Lattner { 3257abc5d6SGreg Clayton ConstString const_plugin_name(plugin_name); 3357abc5d6SGreg Clayton create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name); 3430fdc8d8SChris Lattner if (create_callback) 3530fdc8d8SChris Lattner { 367b0992d9SGreg Clayton std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true)); 37*34ede34aSEugene Zelenko if (instance_ap) 3830fdc8d8SChris Lattner return instance_ap.release(); 3930fdc8d8SChris Lattner } 4030fdc8d8SChris Lattner } 4130fdc8d8SChris Lattner else 4230fdc8d8SChris Lattner { 43*34ede34aSEugene Zelenko for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx) 4430fdc8d8SChris Lattner { 457b0992d9SGreg Clayton std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false)); 46*34ede34aSEugene Zelenko if (instance_ap) 4730fdc8d8SChris Lattner return instance_ap.release(); 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner } 50*34ede34aSEugene Zelenko return nullptr; 5130fdc8d8SChris Lattner } 5230fdc8d8SChris Lattner 5330fdc8d8SChris Lattner DynamicLoader::DynamicLoader(Process *process) : 542995077dSJim Ingham m_process (process) 5530fdc8d8SChris Lattner { 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner 58*34ede34aSEugene Zelenko DynamicLoader::~DynamicLoader() = default; 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner //---------------------------------------------------------------------- 61ed8a705cSGreg Clayton // Accessosors to the global setting as to whether to stop at image 6230fdc8d8SChris Lattner // (shared library) loading/unloading. 6330fdc8d8SChris Lattner //---------------------------------------------------------------------- 64*34ede34aSEugene Zelenko 6530fdc8d8SChris Lattner bool 6630fdc8d8SChris Lattner DynamicLoader::GetStopWhenImagesChange () const 6730fdc8d8SChris Lattner { 682995077dSJim Ingham return m_process->GetStopOnSharedLibraryEvents(); 6930fdc8d8SChris Lattner } 7030fdc8d8SChris Lattner 7130fdc8d8SChris Lattner void 7230fdc8d8SChris Lattner DynamicLoader::SetStopWhenImagesChange (bool stop) 7330fdc8d8SChris Lattner { 742995077dSJim Ingham m_process->SetStopOnSharedLibraryEvents (stop); 7530fdc8d8SChris Lattner } 7630fdc8d8SChris Lattner 779e02dacdSSteve Pucci ModuleSP 789e02dacdSSteve Pucci DynamicLoader::GetTargetExecutable() 799e02dacdSSteve Pucci { 809e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 819e02dacdSSteve Pucci ModuleSP executable = target.GetExecutableModule(); 829e02dacdSSteve Pucci 83*34ede34aSEugene Zelenko if (executable) 849e02dacdSSteve Pucci { 859e02dacdSSteve Pucci if (executable->GetFileSpec().Exists()) 869e02dacdSSteve Pucci { 879e02dacdSSteve Pucci ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture()); 889e02dacdSSteve Pucci ModuleSP module_sp (new Module (module_spec)); 899e02dacdSSteve Pucci 909e02dacdSSteve Pucci // Check if the executable has changed and set it to the target executable if they differ. 91*34ede34aSEugene Zelenko if (module_sp && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid()) 929e02dacdSSteve Pucci { 939e02dacdSSteve Pucci if (module_sp->GetUUID() != executable->GetUUID()) 949e02dacdSSteve Pucci executable.reset(); 959e02dacdSSteve Pucci } 969e02dacdSSteve Pucci else if (executable->FileHasChanged()) 979e02dacdSSteve Pucci { 989e02dacdSSteve Pucci executable.reset(); 999e02dacdSSteve Pucci } 1009e02dacdSSteve Pucci 101*34ede34aSEugene Zelenko if (!executable) 1029e02dacdSSteve Pucci { 1039e02dacdSSteve Pucci executable = target.GetSharedModule(module_spec); 1049e02dacdSSteve Pucci if (executable.get() != target.GetExecutableModulePointer()) 1059e02dacdSSteve Pucci { 1069e02dacdSSteve Pucci // Don't load dependent images since we are in dyld where we will know 1079e02dacdSSteve Pucci // and find out about all images that are loaded 1089e02dacdSSteve Pucci const bool get_dependent_images = false; 1099e02dacdSSteve Pucci target.SetExecutableModule(executable, get_dependent_images); 1109e02dacdSSteve Pucci } 1119e02dacdSSteve Pucci } 1129e02dacdSSteve Pucci } 1139e02dacdSSteve Pucci } 1149e02dacdSSteve Pucci return executable; 1159e02dacdSSteve Pucci } 1169e02dacdSSteve Pucci 1179e02dacdSSteve Pucci void 11842ecef3bSTamas Berghammer DynamicLoader::UpdateLoadedSections(ModuleSP module, 11942ecef3bSTamas Berghammer addr_t link_map_addr, 12042ecef3bSTamas Berghammer addr_t base_addr, 12142ecef3bSTamas Berghammer bool base_addr_is_offset) 1229e02dacdSSteve Pucci { 12342ecef3bSTamas Berghammer UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); 1249e02dacdSSteve Pucci } 1259e02dacdSSteve Pucci 1269e02dacdSSteve Pucci void 12742ecef3bSTamas Berghammer DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, 12842ecef3bSTamas Berghammer addr_t base_addr, 12942ecef3bSTamas Berghammer bool base_addr_is_offset) 1309e02dacdSSteve Pucci { 1319e02dacdSSteve Pucci bool changed; 132751caf65SGreg Clayton module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); 1339e02dacdSSteve Pucci } 1349e02dacdSSteve Pucci 1359e02dacdSSteve Pucci void 1369e02dacdSSteve Pucci DynamicLoader::UnloadSections(const ModuleSP module) 1379e02dacdSSteve Pucci { 1389e02dacdSSteve Pucci UnloadSectionsCommon(module); 1399e02dacdSSteve Pucci } 1409e02dacdSSteve Pucci 1419e02dacdSSteve Pucci void 1429e02dacdSSteve Pucci DynamicLoader::UnloadSectionsCommon(const ModuleSP module) 1439e02dacdSSteve Pucci { 1449e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 1459e02dacdSSteve Pucci const SectionList *sections = GetSectionListFromModule(module); 1469e02dacdSSteve Pucci 1479e02dacdSSteve Pucci assert(sections && "SectionList missing from unloaded module."); 1489e02dacdSSteve Pucci 1499e02dacdSSteve Pucci const size_t num_sections = sections->GetSize(); 1509e02dacdSSteve Pucci for (size_t i = 0; i < num_sections; ++i) 1519e02dacdSSteve Pucci { 1529e02dacdSSteve Pucci SectionSP section_sp (sections->GetSectionAtIndex(i)); 1539e02dacdSSteve Pucci target.SetSectionUnloaded(section_sp); 1549e02dacdSSteve Pucci } 1559e02dacdSSteve Pucci } 1569e02dacdSSteve Pucci 1579e02dacdSSteve Pucci const SectionList * 1589e02dacdSSteve Pucci DynamicLoader::GetSectionListFromModule(const ModuleSP module) const 1599e02dacdSSteve Pucci { 1609e02dacdSSteve Pucci SectionList *sections = nullptr; 161*34ede34aSEugene Zelenko if (module) 1629e02dacdSSteve Pucci { 1639e02dacdSSteve Pucci ObjectFile *obj_file = module->GetObjectFile(); 164*34ede34aSEugene Zelenko if (obj_file != nullptr) 1659e02dacdSSteve Pucci { 1669e02dacdSSteve Pucci sections = obj_file->GetSectionList(); 1679e02dacdSSteve Pucci } 1689e02dacdSSteve Pucci } 1699e02dacdSSteve Pucci return sections; 1709e02dacdSSteve Pucci } 1719e02dacdSSteve Pucci 1729e02dacdSSteve Pucci ModuleSP 17342ecef3bSTamas Berghammer DynamicLoader::LoadModuleAtAddress(const FileSpec &file, 17442ecef3bSTamas Berghammer addr_t link_map_addr, 17542ecef3bSTamas Berghammer addr_t base_addr, 17642ecef3bSTamas Berghammer bool base_addr_is_offset) 1779e02dacdSSteve Pucci { 1789e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 1799e02dacdSSteve Pucci ModuleList &modules = target.GetImages(); 1809e02dacdSSteve Pucci ModuleSP module_sp; 1819e02dacdSSteve Pucci 1829e02dacdSSteve Pucci ModuleSpec module_spec (file, target.GetArchitecture()); 1839e02dacdSSteve Pucci if ((module_sp = modules.FindFirstModule (module_spec))) 1849e02dacdSSteve Pucci { 18542ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 1869e02dacdSSteve Pucci } 1879e02dacdSSteve Pucci else if ((module_sp = target.GetSharedModule(module_spec))) 1889e02dacdSSteve Pucci { 18942ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 1909e02dacdSSteve Pucci } 191f2561846STamas Berghammer else 192f2561846STamas Berghammer { 19342ecef3bSTamas Berghammer if (base_addr_is_offset) 19442ecef3bSTamas Berghammer { 19542ecef3bSTamas Berghammer // Try to fetch the load address of the file from the process as we need absolute load 19642ecef3bSTamas Berghammer // address to read the file out of the memory instead of a load bias. 197f2561846STamas Berghammer bool is_loaded; 198f2561846STamas Berghammer lldb::addr_t load_addr; 199f2561846STamas Berghammer Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); 20042ecef3bSTamas Berghammer if (error.Success() && is_loaded) 20142ecef3bSTamas Berghammer base_addr = load_addr; 20242ecef3bSTamas Berghammer } 203f2561846STamas Berghammer 20442ecef3bSTamas Berghammer if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) 205f2561846STamas Berghammer { 20642ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); 207f2561846STamas Berghammer target.GetImages().AppendIfNeeded(module_sp); 208f2561846STamas Berghammer } 209f2561846STamas Berghammer } 2109e02dacdSSteve Pucci 2119e02dacdSSteve Pucci return module_sp; 2129e02dacdSSteve Pucci } 2139e02dacdSSteve Pucci 2149e02dacdSSteve Pucci int64_t 2159e02dacdSSteve Pucci DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes) 2169e02dacdSSteve Pucci { 2179e02dacdSSteve Pucci Error error; 2189e02dacdSSteve Pucci uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 2199e02dacdSSteve Pucci if (error.Fail()) 2209e02dacdSSteve Pucci return -1; 2219e02dacdSSteve Pucci else 2229e02dacdSSteve Pucci return (int64_t)value; 2239e02dacdSSteve Pucci } 2249e02dacdSSteve Pucci 2259e02dacdSSteve Pucci addr_t 2269e02dacdSSteve Pucci DynamicLoader::ReadPointer(addr_t addr) 2279e02dacdSSteve Pucci { 2289e02dacdSSteve Pucci Error error; 2299e02dacdSSteve Pucci addr_t value = m_process->ReadPointerFromMemory(addr, error); 2309e02dacdSSteve Pucci if (error.Fail()) 2319e02dacdSSteve Pucci return LLDB_INVALID_ADDRESS; 2329e02dacdSSteve Pucci else 2339e02dacdSSteve Pucci return value; 2349e02dacdSSteve Pucci } 235