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