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 1034ede34aSEugene Zelenko // C Includes 1134ede34aSEugene Zelenko // C++ Includes 1234ede34aSEugene Zelenko // Other libraries and framework includes 1334ede34aSEugene Zelenko // Project includes 1430fdc8d8SChris Lattner #include "lldb/lldb-private.h" 159e02dacdSSteve Pucci #include "lldb/Core/Module.h" 169e02dacdSSteve Pucci #include "lldb/Core/ModuleSpec.h" 17*d7d69f80STamas Berghammer #include "lldb/Core/PluginManager.h" 189e02dacdSSteve Pucci #include "lldb/Core/Section.h" 19*d7d69f80STamas Berghammer #include "lldb/Target/DynamicLoader.h" 20*d7d69f80STamas Berghammer #include "lldb/Target/MemoryRegionInfo.h" 21*d7d69f80STamas Berghammer #include "lldb/Target/Process.h" 22*d7d69f80STamas Berghammer #include "lldb/Target/Target.h" 2330fdc8d8SChris Lattner 2430fdc8d8SChris Lattner using namespace lldb; 2530fdc8d8SChris Lattner using namespace lldb_private; 2630fdc8d8SChris Lattner 2730fdc8d8SChris Lattner DynamicLoader* 2830fdc8d8SChris Lattner DynamicLoader::FindPlugin (Process *process, const char *plugin_name) 2930fdc8d8SChris Lattner { 3034ede34aSEugene Zelenko DynamicLoaderCreateInstance create_callback = nullptr; 3130fdc8d8SChris Lattner if (plugin_name) 3230fdc8d8SChris Lattner { 3357abc5d6SGreg Clayton ConstString const_plugin_name(plugin_name); 3457abc5d6SGreg Clayton create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name); 3530fdc8d8SChris Lattner if (create_callback) 3630fdc8d8SChris Lattner { 377b0992d9SGreg Clayton std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true)); 3834ede34aSEugene Zelenko if (instance_ap) 3930fdc8d8SChris Lattner return instance_ap.release(); 4030fdc8d8SChris Lattner } 4130fdc8d8SChris Lattner } 4230fdc8d8SChris Lattner else 4330fdc8d8SChris Lattner { 4434ede34aSEugene Zelenko for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx) 4530fdc8d8SChris Lattner { 467b0992d9SGreg Clayton std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false)); 4734ede34aSEugene Zelenko if (instance_ap) 4830fdc8d8SChris Lattner return instance_ap.release(); 4930fdc8d8SChris Lattner } 5030fdc8d8SChris Lattner } 5134ede34aSEugene Zelenko return nullptr; 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner DynamicLoader::DynamicLoader(Process *process) : 552995077dSJim Ingham m_process (process) 5630fdc8d8SChris Lattner { 5730fdc8d8SChris Lattner } 5830fdc8d8SChris Lattner 5934ede34aSEugene Zelenko DynamicLoader::~DynamicLoader() = default; 6030fdc8d8SChris Lattner 6130fdc8d8SChris Lattner //---------------------------------------------------------------------- 62ed8a705cSGreg Clayton // Accessosors to the global setting as to whether to stop at image 6330fdc8d8SChris Lattner // (shared library) loading/unloading. 6430fdc8d8SChris Lattner //---------------------------------------------------------------------- 6534ede34aSEugene Zelenko 6630fdc8d8SChris Lattner bool 6730fdc8d8SChris Lattner DynamicLoader::GetStopWhenImagesChange () const 6830fdc8d8SChris Lattner { 692995077dSJim Ingham return m_process->GetStopOnSharedLibraryEvents(); 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner 7230fdc8d8SChris Lattner void 7330fdc8d8SChris Lattner DynamicLoader::SetStopWhenImagesChange (bool stop) 7430fdc8d8SChris Lattner { 752995077dSJim Ingham m_process->SetStopOnSharedLibraryEvents (stop); 7630fdc8d8SChris Lattner } 7730fdc8d8SChris Lattner 789e02dacdSSteve Pucci ModuleSP 799e02dacdSSteve Pucci DynamicLoader::GetTargetExecutable() 809e02dacdSSteve Pucci { 819e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 829e02dacdSSteve Pucci ModuleSP executable = target.GetExecutableModule(); 839e02dacdSSteve Pucci 8434ede34aSEugene Zelenko if (executable) 859e02dacdSSteve Pucci { 869e02dacdSSteve Pucci if (executable->GetFileSpec().Exists()) 879e02dacdSSteve Pucci { 889e02dacdSSteve Pucci ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture()); 899e02dacdSSteve Pucci ModuleSP module_sp (new Module (module_spec)); 909e02dacdSSteve Pucci 919e02dacdSSteve Pucci // Check if the executable has changed and set it to the target executable if they differ. 9234ede34aSEugene Zelenko if (module_sp && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid()) 939e02dacdSSteve Pucci { 949e02dacdSSteve Pucci if (module_sp->GetUUID() != executable->GetUUID()) 959e02dacdSSteve Pucci executable.reset(); 969e02dacdSSteve Pucci } 979e02dacdSSteve Pucci else if (executable->FileHasChanged()) 989e02dacdSSteve Pucci { 999e02dacdSSteve Pucci executable.reset(); 1009e02dacdSSteve Pucci } 1019e02dacdSSteve Pucci 10234ede34aSEugene Zelenko if (!executable) 1039e02dacdSSteve Pucci { 1049e02dacdSSteve Pucci executable = target.GetSharedModule(module_spec); 1059e02dacdSSteve Pucci if (executable.get() != target.GetExecutableModulePointer()) 1069e02dacdSSteve Pucci { 1079e02dacdSSteve Pucci // Don't load dependent images since we are in dyld where we will know 1089e02dacdSSteve Pucci // and find out about all images that are loaded 1099e02dacdSSteve Pucci const bool get_dependent_images = false; 1109e02dacdSSteve Pucci target.SetExecutableModule(executable, get_dependent_images); 1119e02dacdSSteve Pucci } 1129e02dacdSSteve Pucci } 1139e02dacdSSteve Pucci } 1149e02dacdSSteve Pucci } 1159e02dacdSSteve Pucci return executable; 1169e02dacdSSteve Pucci } 1179e02dacdSSteve Pucci 1189e02dacdSSteve Pucci void 11942ecef3bSTamas Berghammer DynamicLoader::UpdateLoadedSections(ModuleSP module, 12042ecef3bSTamas Berghammer addr_t link_map_addr, 12142ecef3bSTamas Berghammer addr_t base_addr, 12242ecef3bSTamas Berghammer bool base_addr_is_offset) 1239e02dacdSSteve Pucci { 12442ecef3bSTamas Berghammer UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); 1259e02dacdSSteve Pucci } 1269e02dacdSSteve Pucci 1279e02dacdSSteve Pucci void 12842ecef3bSTamas Berghammer DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, 12942ecef3bSTamas Berghammer addr_t base_addr, 13042ecef3bSTamas Berghammer bool base_addr_is_offset) 1319e02dacdSSteve Pucci { 1329e02dacdSSteve Pucci bool changed; 133751caf65SGreg Clayton module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); 1349e02dacdSSteve Pucci } 1359e02dacdSSteve Pucci 1369e02dacdSSteve Pucci void 1379e02dacdSSteve Pucci DynamicLoader::UnloadSections(const ModuleSP module) 1389e02dacdSSteve Pucci { 1399e02dacdSSteve Pucci UnloadSectionsCommon(module); 1409e02dacdSSteve Pucci } 1419e02dacdSSteve Pucci 1429e02dacdSSteve Pucci void 1439e02dacdSSteve Pucci DynamicLoader::UnloadSectionsCommon(const ModuleSP module) 1449e02dacdSSteve Pucci { 1459e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 1469e02dacdSSteve Pucci const SectionList *sections = GetSectionListFromModule(module); 1479e02dacdSSteve Pucci 1489e02dacdSSteve Pucci assert(sections && "SectionList missing from unloaded module."); 1499e02dacdSSteve Pucci 1509e02dacdSSteve Pucci const size_t num_sections = sections->GetSize(); 1519e02dacdSSteve Pucci for (size_t i = 0; i < num_sections; ++i) 1529e02dacdSSteve Pucci { 1539e02dacdSSteve Pucci SectionSP section_sp (sections->GetSectionAtIndex(i)); 1549e02dacdSSteve Pucci target.SetSectionUnloaded(section_sp); 1559e02dacdSSteve Pucci } 1569e02dacdSSteve Pucci } 1579e02dacdSSteve Pucci 1589e02dacdSSteve Pucci const SectionList * 1599e02dacdSSteve Pucci DynamicLoader::GetSectionListFromModule(const ModuleSP module) const 1609e02dacdSSteve Pucci { 1619e02dacdSSteve Pucci SectionList *sections = nullptr; 16234ede34aSEugene Zelenko if (module) 1639e02dacdSSteve Pucci { 1649e02dacdSSteve Pucci ObjectFile *obj_file = module->GetObjectFile(); 16534ede34aSEugene Zelenko if (obj_file != nullptr) 1669e02dacdSSteve Pucci { 1679e02dacdSSteve Pucci sections = obj_file->GetSectionList(); 1689e02dacdSSteve Pucci } 1699e02dacdSSteve Pucci } 1709e02dacdSSteve Pucci return sections; 1719e02dacdSSteve Pucci } 1729e02dacdSSteve Pucci 1739e02dacdSSteve Pucci ModuleSP 17442ecef3bSTamas Berghammer DynamicLoader::LoadModuleAtAddress(const FileSpec &file, 17542ecef3bSTamas Berghammer addr_t link_map_addr, 17642ecef3bSTamas Berghammer addr_t base_addr, 17742ecef3bSTamas Berghammer bool base_addr_is_offset) 1789e02dacdSSteve Pucci { 1799e02dacdSSteve Pucci Target &target = m_process->GetTarget(); 1809e02dacdSSteve Pucci ModuleList &modules = target.GetImages(); 181*d7d69f80STamas Berghammer ModuleSpec module_spec (file, target.GetArchitecture()); 1829e02dacdSSteve Pucci ModuleSP module_sp; 1839e02dacdSSteve Pucci 1849e02dacdSSteve Pucci if ((module_sp = modules.FindFirstModule (module_spec))) 1859e02dacdSSteve Pucci { 18642ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 187*d7d69f80STamas Berghammer return module_sp; 1889e02dacdSSteve Pucci } 189*d7d69f80STamas Berghammer 190*d7d69f80STamas Berghammer if ((module_sp = target.GetSharedModule(module_spec))) 1919e02dacdSSteve Pucci { 19242ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); 193*d7d69f80STamas Berghammer return module_sp; 1949e02dacdSSteve Pucci } 195*d7d69f80STamas Berghammer 196*d7d69f80STamas Berghammer bool check_alternative_file_name = true; 19742ecef3bSTamas Berghammer if (base_addr_is_offset) 19842ecef3bSTamas Berghammer { 19942ecef3bSTamas Berghammer // Try to fetch the load address of the file from the process as we need absolute load 20042ecef3bSTamas Berghammer // address to read the file out of the memory instead of a load bias. 2015d410241SJason Molenda bool is_loaded = false; 202f2561846STamas Berghammer lldb::addr_t load_addr; 203f2561846STamas Berghammer Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); 20442ecef3bSTamas Berghammer if (error.Success() && is_loaded) 205*d7d69f80STamas Berghammer { 206*d7d69f80STamas Berghammer check_alternative_file_name = false; 20742ecef3bSTamas Berghammer base_addr = load_addr; 20842ecef3bSTamas Berghammer } 209*d7d69f80STamas Berghammer } 210*d7d69f80STamas Berghammer 211*d7d69f80STamas Berghammer // We failed to find the module based on its name. Lets try to check if we can find a 212*d7d69f80STamas Berghammer // different name based on the memory region info. 213*d7d69f80STamas Berghammer if (check_alternative_file_name) 214*d7d69f80STamas Berghammer { 215*d7d69f80STamas Berghammer MemoryRegionInfo memory_info; 216*d7d69f80STamas Berghammer Error error = m_process->GetMemoryRegionInfo(base_addr, memory_info); 217*d7d69f80STamas Berghammer if (error.Success() && memory_info.GetMapped() && memory_info.GetRange().GetRangeBase() == base_addr) 218*d7d69f80STamas Berghammer { 219*d7d69f80STamas Berghammer ModuleSpec new_module_spec(FileSpec(memory_info.GetName().AsCString(), false), 220*d7d69f80STamas Berghammer target.GetArchitecture()); 221*d7d69f80STamas Berghammer 222*d7d69f80STamas Berghammer if ((module_sp = modules.FindFirstModule(new_module_spec))) 223*d7d69f80STamas Berghammer { 224*d7d69f80STamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); 225*d7d69f80STamas Berghammer return module_sp; 226*d7d69f80STamas Berghammer } 227*d7d69f80STamas Berghammer 228*d7d69f80STamas Berghammer if ((module_sp = target.GetSharedModule(new_module_spec))) 229*d7d69f80STamas Berghammer { 230*d7d69f80STamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); 231*d7d69f80STamas Berghammer return module_sp; 232*d7d69f80STamas Berghammer } 233*d7d69f80STamas Berghammer } 234*d7d69f80STamas Berghammer } 235f2561846STamas Berghammer 23642ecef3bSTamas Berghammer if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) 237f2561846STamas Berghammer { 23842ecef3bSTamas Berghammer UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); 239f2561846STamas Berghammer target.GetImages().AppendIfNeeded(module_sp); 240f2561846STamas Berghammer } 2419e02dacdSSteve Pucci 2429e02dacdSSteve Pucci return module_sp; 2439e02dacdSSteve Pucci } 2449e02dacdSSteve Pucci 2459e02dacdSSteve Pucci int64_t 2469e02dacdSSteve Pucci DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes) 2479e02dacdSSteve Pucci { 2489e02dacdSSteve Pucci Error error; 2499e02dacdSSteve Pucci uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 2509e02dacdSSteve Pucci if (error.Fail()) 2519e02dacdSSteve Pucci return -1; 2529e02dacdSSteve Pucci else 2539e02dacdSSteve Pucci return (int64_t)value; 2549e02dacdSSteve Pucci } 2559e02dacdSSteve Pucci 2569e02dacdSSteve Pucci addr_t 2579e02dacdSSteve Pucci DynamicLoader::ReadPointer(addr_t addr) 2589e02dacdSSteve Pucci { 2599e02dacdSSteve Pucci Error error; 2609e02dacdSSteve Pucci addr_t value = m_process->ReadPointerFromMemory(addr, error); 2619e02dacdSSteve Pucci if (error.Fail()) 2629e02dacdSSteve Pucci return LLDB_INVALID_ADDRESS; 2639e02dacdSSteve Pucci else 2649e02dacdSSteve Pucci return value; 2659e02dacdSSteve Pucci } 266