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 1030fdc8d8SChris Lattner #include "lldb/lldb-private.h" 1130fdc8d8SChris Lattner #include "lldb/Target/DynamicLoader.h" 122995077dSJim Ingham #include "lldb/Target/Process.h" 139e02dacdSSteve Pucci #include "lldb/Target/Target.h" 1430fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h" 159e02dacdSSteve Pucci #include "lldb/Core/Module.h" 169e02dacdSSteve Pucci #include "lldb/Core/ModuleSpec.h" 179e02dacdSSteve Pucci #include "lldb/Core/Section.h" 1830fdc8d8SChris Lattner 1930fdc8d8SChris Lattner using namespace lldb; 2030fdc8d8SChris Lattner using namespace lldb_private; 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner DynamicLoader* 2330fdc8d8SChris Lattner DynamicLoader::FindPlugin (Process *process, const char *plugin_name) 2430fdc8d8SChris Lattner { 2530fdc8d8SChris Lattner DynamicLoaderCreateInstance create_callback = NULL; 2630fdc8d8SChris Lattner if (plugin_name) 2730fdc8d8SChris Lattner { 2857abc5d6SGreg Clayton ConstString const_plugin_name(plugin_name); 2957abc5d6SGreg Clayton create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name); 3030fdc8d8SChris Lattner if (create_callback) 3130fdc8d8SChris Lattner { 327b0992d9SGreg Clayton std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true)); 3330fdc8d8SChris Lattner if (instance_ap.get()) 3430fdc8d8SChris Lattner return instance_ap.release(); 3530fdc8d8SChris Lattner } 3630fdc8d8SChris Lattner } 3730fdc8d8SChris Lattner else 3830fdc8d8SChris Lattner { 3930fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx) 4030fdc8d8SChris Lattner { 417b0992d9SGreg Clayton std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false)); 4230fdc8d8SChris Lattner if (instance_ap.get()) 4330fdc8d8SChris Lattner return instance_ap.release(); 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner } 4630fdc8d8SChris Lattner return NULL; 4730fdc8d8SChris Lattner } 4830fdc8d8SChris Lattner 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner //---------------------------------------------------------------------- 5130fdc8d8SChris Lattner // DynamicLoader constructor 5230fdc8d8SChris Lattner //---------------------------------------------------------------------- 5330fdc8d8SChris Lattner DynamicLoader::DynamicLoader(Process *process) : 542995077dSJim Ingham m_process (process) 5530fdc8d8SChris Lattner { 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner 5830fdc8d8SChris Lattner //---------------------------------------------------------------------- 5930fdc8d8SChris Lattner // Destructor 6030fdc8d8SChris Lattner //---------------------------------------------------------------------- 6130fdc8d8SChris Lattner DynamicLoader::~DynamicLoader() 6230fdc8d8SChris Lattner { 6330fdc8d8SChris Lattner } 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner //---------------------------------------------------------------------- 66ed8a705cSGreg Clayton // Accessosors to the global setting as to whether to stop at image 6730fdc8d8SChris Lattner // (shared library) loading/unloading. 6830fdc8d8SChris Lattner //---------------------------------------------------------------------- 6930fdc8d8SChris Lattner bool 7030fdc8d8SChris Lattner DynamicLoader::GetStopWhenImagesChange () const 7130fdc8d8SChris Lattner { 722995077dSJim Ingham return m_process->GetStopOnSharedLibraryEvents(); 7330fdc8d8SChris Lattner } 7430fdc8d8SChris Lattner 7530fdc8d8SChris Lattner void 7630fdc8d8SChris Lattner DynamicLoader::SetStopWhenImagesChange (bool stop) 7730fdc8d8SChris Lattner { 782995077dSJim Ingham m_process->SetStopOnSharedLibraryEvents (stop); 7930fdc8d8SChris Lattner } 8030fdc8d8SChris Lattner 819e02dacdSSteve Pucci ModuleSP 829e02dacdSSteve Pucci DynamicLoader::GetTargetExecutable() 839e02dacdSSteve Pucci { 849e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 859e02dacdSSteve Pucci ModuleSP executable = target.GetExecutableModule(); 869e02dacdSSteve Pucci 879e02dacdSSteve Pucci if (executable.get()) 889e02dacdSSteve Pucci { 899e02dacdSSteve Pucci if (executable->GetFileSpec().Exists()) 909e02dacdSSteve Pucci { 919e02dacdSSteve Pucci ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture()); 929e02dacdSSteve Pucci ModuleSP module_sp (new Module (module_spec)); 939e02dacdSSteve Pucci 949e02dacdSSteve Pucci // Check if the executable has changed and set it to the target executable if they differ. 959e02dacdSSteve Pucci if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid()) 969e02dacdSSteve Pucci { 979e02dacdSSteve Pucci if (module_sp->GetUUID() != executable->GetUUID()) 989e02dacdSSteve Pucci executable.reset(); 999e02dacdSSteve Pucci } 1009e02dacdSSteve Pucci else if (executable->FileHasChanged()) 1019e02dacdSSteve Pucci { 1029e02dacdSSteve Pucci executable.reset(); 1039e02dacdSSteve Pucci } 1049e02dacdSSteve Pucci 1059e02dacdSSteve Pucci if (!executable.get()) 1069e02dacdSSteve Pucci { 1079e02dacdSSteve Pucci executable = target.GetSharedModule(module_spec); 1089e02dacdSSteve Pucci if (executable.get() != target.GetExecutableModulePointer()) 1099e02dacdSSteve Pucci { 1109e02dacdSSteve Pucci // Don't load dependent images since we are in dyld where we will know 1119e02dacdSSteve Pucci // and find out about all images that are loaded 1129e02dacdSSteve Pucci const bool get_dependent_images = false; 1139e02dacdSSteve Pucci target.SetExecutableModule(executable, get_dependent_images); 1149e02dacdSSteve Pucci } 1159e02dacdSSteve Pucci } 1169e02dacdSSteve Pucci } 1179e02dacdSSteve Pucci } 1189e02dacdSSteve Pucci return executable; 1199e02dacdSSteve Pucci } 1209e02dacdSSteve Pucci 1219e02dacdSSteve Pucci void 122*42ecef3bSTamas Berghammer DynamicLoader::UpdateLoadedSections(ModuleSP module, 123*42ecef3bSTamas Berghammer addr_t link_map_addr, 124*42ecef3bSTamas Berghammer addr_t base_addr, 125*42ecef3bSTamas Berghammer bool base_addr_is_offset) 1269e02dacdSSteve Pucci { 127*42ecef3bSTamas Berghammer UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); 1289e02dacdSSteve Pucci } 1299e02dacdSSteve Pucci 1309e02dacdSSteve Pucci void 131*42ecef3bSTamas Berghammer DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, 132*42ecef3bSTamas Berghammer addr_t base_addr, 133*42ecef3bSTamas Berghammer bool base_addr_is_offset) 1349e02dacdSSteve Pucci { 1359e02dacdSSteve Pucci bool changed; 136751caf65SGreg Clayton module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); 1379e02dacdSSteve Pucci } 1389e02dacdSSteve Pucci 1399e02dacdSSteve Pucci void 1409e02dacdSSteve Pucci DynamicLoader::UnloadSections(const ModuleSP module) 1419e02dacdSSteve Pucci { 1429e02dacdSSteve Pucci UnloadSectionsCommon(module); 1439e02dacdSSteve Pucci } 1449e02dacdSSteve Pucci 1459e02dacdSSteve Pucci void 1469e02dacdSSteve Pucci DynamicLoader::UnloadSectionsCommon(const ModuleSP module) 1479e02dacdSSteve Pucci { 1489e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 1499e02dacdSSteve Pucci const SectionList *sections = GetSectionListFromModule(module); 1509e02dacdSSteve Pucci 1519e02dacdSSteve Pucci assert(sections && "SectionList missing from unloaded module."); 1529e02dacdSSteve Pucci 1539e02dacdSSteve Pucci const size_t num_sections = sections->GetSize(); 1549e02dacdSSteve Pucci for (size_t i = 0; i < num_sections; ++i) 1559e02dacdSSteve Pucci { 1569e02dacdSSteve Pucci SectionSP section_sp (sections->GetSectionAtIndex(i)); 1579e02dacdSSteve Pucci target.SetSectionUnloaded(section_sp); 1589e02dacdSSteve Pucci } 1599e02dacdSSteve Pucci } 1609e02dacdSSteve Pucci 1619e02dacdSSteve Pucci 1629e02dacdSSteve Pucci const SectionList * 1639e02dacdSSteve Pucci DynamicLoader::GetSectionListFromModule(const ModuleSP module) const 1649e02dacdSSteve Pucci { 1659e02dacdSSteve Pucci SectionList *sections = nullptr; 1669e02dacdSSteve Pucci if (module.get()) 1679e02dacdSSteve Pucci { 1689e02dacdSSteve Pucci ObjectFile *obj_file = module->GetObjectFile(); 1699e02dacdSSteve Pucci if (obj_file) 1709e02dacdSSteve Pucci { 1719e02dacdSSteve Pucci sections = obj_file->GetSectionList(); 1729e02dacdSSteve Pucci } 1739e02dacdSSteve Pucci } 1749e02dacdSSteve Pucci return sections; 1759e02dacdSSteve Pucci } 1769e02dacdSSteve Pucci 1779e02dacdSSteve Pucci ModuleSP 178*42ecef3bSTamas Berghammer DynamicLoader::LoadModuleAtAddress(const FileSpec &file, 179*42ecef3bSTamas Berghammer addr_t link_map_addr, 180*42ecef3bSTamas Berghammer addr_t base_addr, 181*42ecef3bSTamas Berghammer bool base_addr_is_offset) 1829e02dacdSSteve Pucci { 1839e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 1849e02dacdSSteve Pucci ModuleList &modules = target.GetImages(); 1859e02dacdSSteve Pucci ModuleSP module_sp; 1869e02dacdSSteve Pucci 1879e02dacdSSteve Pucci ModuleSpec module_spec (file, target.GetArchitecture()); 1889e02dacdSSteve Pucci if ((module_sp = modules.FindFirstModule (module_spec))) 1899e02dacdSSteve Pucci { 190*42ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 1919e02dacdSSteve Pucci } 1929e02dacdSSteve Pucci else if ((module_sp = target.GetSharedModule(module_spec))) 1939e02dacdSSteve Pucci { 194*42ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 1959e02dacdSSteve Pucci } 196f2561846STamas Berghammer else 197f2561846STamas Berghammer { 198*42ecef3bSTamas Berghammer if (base_addr_is_offset) 199*42ecef3bSTamas Berghammer { 200*42ecef3bSTamas Berghammer // Try to fetch the load address of the file from the process as we need absolute load 201*42ecef3bSTamas Berghammer // address to read the file out of the memory instead of a load bias. 202f2561846STamas Berghammer bool is_loaded; 203f2561846STamas Berghammer lldb::addr_t load_addr; 204f2561846STamas Berghammer Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); 205*42ecef3bSTamas Berghammer if (error.Success() && is_loaded) 206*42ecef3bSTamas Berghammer base_addr = load_addr; 207*42ecef3bSTamas Berghammer } 208f2561846STamas Berghammer 209*42ecef3bSTamas Berghammer if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) 210f2561846STamas Berghammer { 211*42ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); 212f2561846STamas Berghammer target.GetImages().AppendIfNeeded(module_sp); 213f2561846STamas Berghammer } 214f2561846STamas Berghammer } 2159e02dacdSSteve Pucci 2169e02dacdSSteve Pucci return module_sp; 2179e02dacdSSteve Pucci } 2189e02dacdSSteve Pucci 2199e02dacdSSteve Pucci int64_t 2209e02dacdSSteve Pucci DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes) 2219e02dacdSSteve Pucci { 2229e02dacdSSteve Pucci Error error; 2239e02dacdSSteve Pucci 2249e02dacdSSteve Pucci uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 2259e02dacdSSteve Pucci if (error.Fail()) 2269e02dacdSSteve Pucci return -1; 2279e02dacdSSteve Pucci else 2289e02dacdSSteve Pucci return (int64_t)value; 2299e02dacdSSteve Pucci } 2309e02dacdSSteve Pucci 2319e02dacdSSteve Pucci addr_t 2329e02dacdSSteve Pucci DynamicLoader::ReadPointer(addr_t addr) 2339e02dacdSSteve Pucci { 2349e02dacdSSteve Pucci Error error; 2359e02dacdSSteve Pucci addr_t value = m_process->ReadPointerFromMemory(addr, error); 2369e02dacdSSteve Pucci if (error.Fail()) 2379e02dacdSSteve Pucci return LLDB_INVALID_ADDRESS; 2389e02dacdSSteve Pucci else 2399e02dacdSSteve Pucci return value; 2409e02dacdSSteve Pucci } 241