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
1229e02dacdSSteve Pucci DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr)
1239e02dacdSSteve Pucci {
1249e02dacdSSteve Pucci     UpdateLoadedSectionsCommon(module, base_addr);
1259e02dacdSSteve Pucci }
1269e02dacdSSteve Pucci 
1279e02dacdSSteve Pucci void
1289e02dacdSSteve Pucci DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr)
1299e02dacdSSteve Pucci {
1309e02dacdSSteve Pucci     bool changed;
131751caf65SGreg Clayton     const bool base_addr_is_offset = true;
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 
1589e02dacdSSteve Pucci const SectionList *
1599e02dacdSSteve Pucci DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
1609e02dacdSSteve Pucci {
1619e02dacdSSteve Pucci     SectionList *sections = nullptr;
1629e02dacdSSteve Pucci     if (module.get())
1639e02dacdSSteve Pucci     {
1649e02dacdSSteve Pucci         ObjectFile *obj_file = module->GetObjectFile();
1659e02dacdSSteve Pucci         if (obj_file)
1669e02dacdSSteve Pucci         {
1679e02dacdSSteve Pucci             sections = obj_file->GetSectionList();
1689e02dacdSSteve Pucci         }
1699e02dacdSSteve Pucci     }
1709e02dacdSSteve Pucci     return sections;
1719e02dacdSSteve Pucci }
1729e02dacdSSteve Pucci 
1739e02dacdSSteve Pucci ModuleSP
1749e02dacdSSteve Pucci DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr)
1759e02dacdSSteve Pucci {
1769e02dacdSSteve Pucci     Target &target = m_process->GetTarget();
1779e02dacdSSteve Pucci     ModuleList &modules = target.GetImages();
1789e02dacdSSteve Pucci     ModuleSP module_sp;
1799e02dacdSSteve Pucci 
1809e02dacdSSteve Pucci     ModuleSpec module_spec (file, target.GetArchitecture());
1819e02dacdSSteve Pucci     if ((module_sp = modules.FindFirstModule (module_spec)))
1829e02dacdSSteve Pucci     {
1839e02dacdSSteve Pucci         UpdateLoadedSections(module_sp, link_map_addr, base_addr);
1849e02dacdSSteve Pucci     }
1859e02dacdSSteve Pucci     else if ((module_sp = target.GetSharedModule(module_spec)))
1869e02dacdSSteve Pucci     {
1879e02dacdSSteve Pucci         UpdateLoadedSections(module_sp, link_map_addr, base_addr);
1889e02dacdSSteve Pucci     }
189*f2561846STamas Berghammer     else
190*f2561846STamas Berghammer     {
191*f2561846STamas Berghammer         // Try to fetch the load address of the file from the process. It can be different from the
192*f2561846STamas Berghammer         // address reported by the linker in case of a file with fixed load address because the
193*f2561846STamas Berghammer         // linker reports the bias between the load address specified in the file and the actual
194*f2561846STamas Berghammer         // load address it loaded the file.
195*f2561846STamas Berghammer         bool is_loaded;
196*f2561846STamas Berghammer         lldb::addr_t load_addr;
197*f2561846STamas Berghammer         Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
198*f2561846STamas Berghammer         if (error.Fail() || !is_loaded)
199*f2561846STamas Berghammer             load_addr = base_addr;
200*f2561846STamas Berghammer 
201*f2561846STamas Berghammer         if ((module_sp = m_process->ReadModuleFromMemory(file, load_addr)))
202*f2561846STamas Berghammer         {
203*f2561846STamas Berghammer             UpdateLoadedSections(module_sp, link_map_addr, base_addr);
204*f2561846STamas Berghammer             target.GetImages().AppendIfNeeded(module_sp);
205*f2561846STamas Berghammer         }
206*f2561846STamas Berghammer     }
2079e02dacdSSteve Pucci 
2089e02dacdSSteve Pucci     return module_sp;
2099e02dacdSSteve Pucci }
2109e02dacdSSteve Pucci 
2119e02dacdSSteve Pucci int64_t
2129e02dacdSSteve Pucci DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
2139e02dacdSSteve Pucci {
2149e02dacdSSteve Pucci     Error error;
2159e02dacdSSteve Pucci 
2169e02dacdSSteve Pucci     uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
2179e02dacdSSteve Pucci     if (error.Fail())
2189e02dacdSSteve Pucci         return -1;
2199e02dacdSSteve Pucci     else
2209e02dacdSSteve Pucci         return (int64_t)value;
2219e02dacdSSteve Pucci }
2229e02dacdSSteve Pucci 
2239e02dacdSSteve Pucci addr_t
2249e02dacdSSteve Pucci DynamicLoader::ReadPointer(addr_t addr)
2259e02dacdSSteve Pucci {
2269e02dacdSSteve Pucci     Error error;
2279e02dacdSSteve Pucci     addr_t value = m_process->ReadPointerFromMemory(addr, error);
2289e02dacdSSteve Pucci     if (error.Fail())
2299e02dacdSSteve Pucci         return LLDB_INVALID_ADDRESS;
2309e02dacdSSteve Pucci     else
2319e02dacdSSteve Pucci         return value;
2329e02dacdSSteve Pucci }
233